]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AArch64/AArch64InstrFormats.td
Update tcpdump to 4.9.2
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AArch64 / AArch64InstrFormats.td
1 //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 //===----------------------------------------------------------------------===//
11 //  Describe AArch64 instructions format here
12 //
13
14 // Format specifies the encoding used by the instruction.  This is part of the
15 // ad-hoc solution used to emit machine instruction encodings by our machine
16 // code emitter.
17 class Format<bits<2> val> {
18   bits<2> Value = val;
19 }
20
21 def PseudoFrm   : Format<0>;
22 def NormalFrm   : Format<1>; // Do we need any others?
23
24 // AArch64 Instruction Format
25 class AArch64Inst<Format f, string cstr> : Instruction {
26   field bits<32> Inst; // Instruction encoding.
27   // Mask of bits that cause an encoding to be UNPREDICTABLE.
28   // If a bit is set, then if the corresponding bit in the
29   // target encoding differs from its value in the "Inst" field,
30   // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
31   field bits<32> Unpredictable = 0;
32   // SoftFail is the generic name for this field, but we alias it so
33   // as to make it more obvious what it means in ARM-land.
34   field bits<32> SoftFail = Unpredictable;
35   let Namespace   = "AArch64";
36   Format F        = f;
37   bits<2> Form    = F.Value;
38   let Pattern     = [];
39   let Constraints = cstr;
40 }
41
42 class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
43   : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
44
45 // Pseudo instructions (don't have encoding information)
46 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
47     : AArch64Inst<PseudoFrm, cstr> {
48   dag OutOperandList = oops;
49   dag InOperandList  = iops;
50   let Pattern        = pattern;
51   let isCodeGenOnly  = 1;
52 }
53
54 // Real instructions (have encoding information)
55 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
56   let Pattern = pattern;
57   let Size = 4;
58 }
59
60 // Normal instructions
61 class I<dag oops, dag iops, string asm, string operands, string cstr,
62         list<dag> pattern>
63     : EncodedI<cstr, pattern> {
64   dag OutOperandList = oops;
65   dag InOperandList  = iops;
66   let AsmString      = !strconcat(asm, operands);
67 }
68
69 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
70 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
71 class UnOpFrag<dag res>  : PatFrag<(ops node:$LHS), res>;
72
73 // Helper fragment for an extract of the high portion of a 128-bit vector.
74 def extract_high_v16i8 :
75    UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
76 def extract_high_v8i16 :
77    UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
78 def extract_high_v4i32 :
79    UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
80 def extract_high_v2i64 :
81    UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
82
83 //===----------------------------------------------------------------------===//
84 // Asm Operand Classes.
85 //
86
87 // Shifter operand for arithmetic shifted encodings.
88 def ShifterOperand : AsmOperandClass {
89   let Name = "Shifter";
90 }
91
92 // Shifter operand for mov immediate encodings.
93 def MovImm32ShifterOperand : AsmOperandClass {
94   let SuperClasses = [ShifterOperand];
95   let Name = "MovImm32Shifter";
96   let RenderMethod = "addShifterOperands";
97   let DiagnosticType = "InvalidMovImm32Shift";
98 }
99 def MovImm64ShifterOperand : AsmOperandClass {
100   let SuperClasses = [ShifterOperand];
101   let Name = "MovImm64Shifter";
102   let RenderMethod = "addShifterOperands";
103   let DiagnosticType = "InvalidMovImm64Shift";
104 }
105
106 // Shifter operand for arithmetic register shifted encodings.
107 class ArithmeticShifterOperand<int width> : AsmOperandClass {
108   let SuperClasses = [ShifterOperand];
109   let Name = "ArithmeticShifter" # width;
110   let PredicateMethod = "isArithmeticShifter<" # width # ">";
111   let RenderMethod = "addShifterOperands";
112   let DiagnosticType = "AddSubRegShift" # width;
113 }
114
115 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
116 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
117
118 // Shifter operand for logical register shifted encodings.
119 class LogicalShifterOperand<int width> : AsmOperandClass {
120   let SuperClasses = [ShifterOperand];
121   let Name = "LogicalShifter" # width;
122   let PredicateMethod = "isLogicalShifter<" # width # ">";
123   let RenderMethod = "addShifterOperands";
124   let DiagnosticType = "AddSubRegShift" # width;
125 }
126
127 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
128 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
129
130 // Shifter operand for logical vector 128/64-bit shifted encodings.
131 def LogicalVecShifterOperand : AsmOperandClass {
132   let SuperClasses = [ShifterOperand];
133   let Name = "LogicalVecShifter";
134   let RenderMethod = "addShifterOperands";
135 }
136 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
137   let SuperClasses = [LogicalVecShifterOperand];
138   let Name = "LogicalVecHalfWordShifter";
139   let RenderMethod = "addShifterOperands";
140 }
141
142 // The "MSL" shifter on the vector MOVI instruction.
143 def MoveVecShifterOperand : AsmOperandClass {
144   let SuperClasses = [ShifterOperand];
145   let Name = "MoveVecShifter";
146   let RenderMethod = "addShifterOperands";
147 }
148
149 // Extend operand for arithmetic encodings.
150 def ExtendOperand : AsmOperandClass {
151   let Name = "Extend";
152   let DiagnosticType = "AddSubRegExtendLarge";
153 }
154 def ExtendOperand64 : AsmOperandClass {
155   let SuperClasses = [ExtendOperand];
156   let Name = "Extend64";
157   let DiagnosticType = "AddSubRegExtendSmall";
158 }
159 // 'extend' that's a lsl of a 64-bit register.
160 def ExtendOperandLSL64 : AsmOperandClass {
161   let SuperClasses = [ExtendOperand];
162   let Name = "ExtendLSL64";
163   let RenderMethod = "addExtend64Operands";
164   let DiagnosticType = "AddSubRegExtendLarge";
165 }
166
167 // 8-bit floating-point immediate encodings.
168 def FPImmOperand : AsmOperandClass {
169   let Name = "FPImm";
170   let ParserMethod = "tryParseFPImm";
171   let DiagnosticType = "InvalidFPImm";
172 }
173
174 def CondCode : AsmOperandClass {
175   let Name = "CondCode";
176   let DiagnosticType = "InvalidCondCode";
177 }
178
179 // A 32-bit register pasrsed as 64-bit
180 def GPR32as64Operand : AsmOperandClass {
181   let Name = "GPR32as64";
182 }
183 def GPR32as64 : RegisterOperand<GPR32> {
184   let ParserMatchClass = GPR32as64Operand;
185 }
186
187 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
188 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
189 // are encoded as the eight bit value 'abcdefgh'.
190 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
191
192
193 //===----------------------------------------------------------------------===//
194 // Operand Definitions.
195 //
196
197 // ADR[P] instruction labels.
198 def AdrpOperand : AsmOperandClass {
199   let Name = "AdrpLabel";
200   let ParserMethod = "tryParseAdrpLabel";
201   let DiagnosticType = "InvalidLabel";
202 }
203 def adrplabel : Operand<i64> {
204   let EncoderMethod = "getAdrLabelOpValue";
205   let PrintMethod = "printAdrpLabel";
206   let ParserMatchClass = AdrpOperand;
207 }
208
209 def AdrOperand : AsmOperandClass {
210   let Name = "AdrLabel";
211   let ParserMethod = "tryParseAdrLabel";
212   let DiagnosticType = "InvalidLabel";
213 }
214 def adrlabel : Operand<i64> {
215   let EncoderMethod = "getAdrLabelOpValue";
216   let ParserMatchClass = AdrOperand;
217 }
218
219 // simm9 predicate - True if the immediate is in the range [-256, 255].
220 def SImm9Operand : AsmOperandClass {
221   let Name = "SImm9";
222   let DiagnosticType = "InvalidMemoryIndexedSImm9";
223 }
224 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
225   let ParserMatchClass = SImm9Operand;
226 }
227
228 // simm7sN predicate - True if the immediate is a multiple of N in the range
229 // [-64 * N, 63 * N].
230 class SImm7Scaled<int Scale> : AsmOperandClass {
231   let Name = "SImm7s" # Scale;
232   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
233 }
234
235 def SImm7s4Operand : SImm7Scaled<4>;
236 def SImm7s8Operand : SImm7Scaled<8>;
237 def SImm7s16Operand : SImm7Scaled<16>;
238
239 def simm7s4 : Operand<i32> {
240   let ParserMatchClass = SImm7s4Operand;
241   let PrintMethod = "printImmScale<4>";
242 }
243
244 def simm7s8 : Operand<i32> {
245   let ParserMatchClass = SImm7s8Operand;
246   let PrintMethod = "printImmScale<8>";
247 }
248
249 def simm7s16 : Operand<i32> {
250   let ParserMatchClass = SImm7s16Operand;
251   let PrintMethod = "printImmScale<16>";
252 }
253
254 def am_indexed7s8   : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
255 def am_indexed7s16  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
256 def am_indexed7s32  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
257 def am_indexed7s64  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
258 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
259
260 class AsmImmRange<int Low, int High> : AsmOperandClass {
261   let Name = "Imm" # Low # "_" # High;
262   let DiagnosticType = "InvalidImm" # Low # "_" # High;
263   let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
264 }
265
266 def Imm1_8Operand : AsmImmRange<1, 8>;
267 def Imm1_16Operand : AsmImmRange<1, 16>;
268 def Imm1_32Operand : AsmImmRange<1, 32>;
269 def Imm1_64Operand : AsmImmRange<1, 64>;
270
271 class BranchTarget<int N> : AsmOperandClass {
272   let Name = "BranchTarget" # N;
273   let DiagnosticType = "InvalidLabel";
274   let PredicateMethod = "isBranchTarget<" # N # ">";
275 }
276
277 class PCRelLabel<int N> : BranchTarget<N> {
278   let Name = "PCRelLabel" # N;
279 }
280
281 def BranchTarget14Operand : BranchTarget<14>;
282 def BranchTarget26Operand : BranchTarget<26>;
283 def PCRelLabel19Operand   : PCRelLabel<19>;
284
285 def MovZSymbolG3AsmOperand : AsmOperandClass {
286   let Name = "MovZSymbolG3";
287   let RenderMethod = "addImmOperands";
288 }
289
290 def movz_symbol_g3 : Operand<i32> {
291   let ParserMatchClass = MovZSymbolG3AsmOperand;
292 }
293
294 def MovZSymbolG2AsmOperand : AsmOperandClass {
295   let Name = "MovZSymbolG2";
296   let RenderMethod = "addImmOperands";
297 }
298
299 def movz_symbol_g2 : Operand<i32> {
300   let ParserMatchClass = MovZSymbolG2AsmOperand;
301 }
302
303 def MovZSymbolG1AsmOperand : AsmOperandClass {
304   let Name = "MovZSymbolG1";
305   let RenderMethod = "addImmOperands";
306 }
307
308 def movz_symbol_g1 : Operand<i32> {
309   let ParserMatchClass = MovZSymbolG1AsmOperand;
310 }
311
312 def MovZSymbolG0AsmOperand : AsmOperandClass {
313   let Name = "MovZSymbolG0";
314   let RenderMethod = "addImmOperands";
315 }
316
317 def movz_symbol_g0 : Operand<i32> {
318   let ParserMatchClass = MovZSymbolG0AsmOperand;
319 }
320
321 def MovKSymbolG3AsmOperand : AsmOperandClass {
322   let Name = "MovKSymbolG3";
323   let RenderMethod = "addImmOperands";
324 }
325
326 def movk_symbol_g3 : Operand<i32> {
327   let ParserMatchClass = MovKSymbolG3AsmOperand;
328 }
329
330 def MovKSymbolG2AsmOperand : AsmOperandClass {
331   let Name = "MovKSymbolG2";
332   let RenderMethod = "addImmOperands";
333 }
334
335 def movk_symbol_g2 : Operand<i32> {
336   let ParserMatchClass = MovKSymbolG2AsmOperand;
337 }
338
339 def MovKSymbolG1AsmOperand : AsmOperandClass {
340   let Name = "MovKSymbolG1";
341   let RenderMethod = "addImmOperands";
342 }
343
344 def movk_symbol_g1 : Operand<i32> {
345   let ParserMatchClass = MovKSymbolG1AsmOperand;
346 }
347
348 def MovKSymbolG0AsmOperand : AsmOperandClass {
349   let Name = "MovKSymbolG0";
350   let RenderMethod = "addImmOperands";
351 }
352
353 def movk_symbol_g0 : Operand<i32> {
354   let ParserMatchClass = MovKSymbolG0AsmOperand;
355 }
356
357 class fixedpoint_i32<ValueType FloatVT>
358   : Operand<FloatVT>,
359     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
360   let EncoderMethod = "getFixedPointScaleOpValue";
361   let DecoderMethod = "DecodeFixedPointScaleImm32";
362   let ParserMatchClass = Imm1_32Operand;
363 }
364
365 class fixedpoint_i64<ValueType FloatVT>
366   : Operand<FloatVT>,
367     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
368   let EncoderMethod = "getFixedPointScaleOpValue";
369   let DecoderMethod = "DecodeFixedPointScaleImm64";
370   let ParserMatchClass = Imm1_64Operand;
371 }
372
373 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
374 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
375 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
376
377 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
378 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
379 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
380
381 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
382   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
383 }]> {
384   let EncoderMethod = "getVecShiftR8OpValue";
385   let DecoderMethod = "DecodeVecShiftR8Imm";
386   let ParserMatchClass = Imm1_8Operand;
387 }
388 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
389   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
390 }]> {
391   let EncoderMethod = "getVecShiftR16OpValue";
392   let DecoderMethod = "DecodeVecShiftR16Imm";
393   let ParserMatchClass = Imm1_16Operand;
394 }
395 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
396   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
397 }]> {
398   let EncoderMethod = "getVecShiftR16OpValue";
399   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
400   let ParserMatchClass = Imm1_8Operand;
401 }
402 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
403   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
404 }]> {
405   let EncoderMethod = "getVecShiftR32OpValue";
406   let DecoderMethod = "DecodeVecShiftR32Imm";
407   let ParserMatchClass = Imm1_32Operand;
408 }
409 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
410   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
411 }]> {
412   let EncoderMethod = "getVecShiftR32OpValue";
413   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
414   let ParserMatchClass = Imm1_16Operand;
415 }
416 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
417   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
418 }]> {
419   let EncoderMethod = "getVecShiftR64OpValue";
420   let DecoderMethod = "DecodeVecShiftR64Imm";
421   let ParserMatchClass = Imm1_64Operand;
422 }
423 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
424   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
425 }]> {
426   let EncoderMethod = "getVecShiftR64OpValue";
427   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
428   let ParserMatchClass = Imm1_32Operand;
429 }
430
431 def Imm0_1Operand : AsmImmRange<0, 1>;
432 def Imm0_7Operand : AsmImmRange<0, 7>;
433 def Imm0_15Operand : AsmImmRange<0, 15>;
434 def Imm0_31Operand : AsmImmRange<0, 31>;
435 def Imm0_63Operand : AsmImmRange<0, 63>;
436
437 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
438   return (((uint32_t)Imm) < 8);
439 }]> {
440   let EncoderMethod = "getVecShiftL8OpValue";
441   let DecoderMethod = "DecodeVecShiftL8Imm";
442   let ParserMatchClass = Imm0_7Operand;
443 }
444 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
445   return (((uint32_t)Imm) < 16);
446 }]> {
447   let EncoderMethod = "getVecShiftL16OpValue";
448   let DecoderMethod = "DecodeVecShiftL16Imm";
449   let ParserMatchClass = Imm0_15Operand;
450 }
451 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
452   return (((uint32_t)Imm) < 32);
453 }]> {
454   let EncoderMethod = "getVecShiftL32OpValue";
455   let DecoderMethod = "DecodeVecShiftL32Imm";
456   let ParserMatchClass = Imm0_31Operand;
457 }
458 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
459   return (((uint32_t)Imm) < 64);
460 }]> {
461   let EncoderMethod = "getVecShiftL64OpValue";
462   let DecoderMethod = "DecodeVecShiftL64Imm";
463   let ParserMatchClass = Imm0_63Operand;
464 }
465
466
467 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
468 // instructions for splatting repeating bit patterns across the immediate.
469 def logical_imm32_XFORM : SDNodeXForm<imm, [{
470   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
471   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
472 }]>;
473 def logical_imm64_XFORM : SDNodeXForm<imm, [{
474   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
475   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
476 }]>;
477
478 let DiagnosticType = "LogicalSecondSource" in {
479   def LogicalImm32Operand : AsmOperandClass {
480     let Name = "LogicalImm32";
481   }
482   def LogicalImm64Operand : AsmOperandClass {
483     let Name = "LogicalImm64";
484   }
485   def LogicalImm32NotOperand : AsmOperandClass {
486     let Name = "LogicalImm32Not";
487   }
488   def LogicalImm64NotOperand : AsmOperandClass {
489     let Name = "LogicalImm64Not";
490   }
491 }
492 def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
493   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
494 }], logical_imm32_XFORM> {
495   let PrintMethod = "printLogicalImm32";
496   let ParserMatchClass = LogicalImm32Operand;
497 }
498 def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
499   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
500 }], logical_imm64_XFORM> {
501   let PrintMethod = "printLogicalImm64";
502   let ParserMatchClass = LogicalImm64Operand;
503 }
504 def logical_imm32_not : Operand<i32> {
505   let ParserMatchClass = LogicalImm32NotOperand;
506 }
507 def logical_imm64_not : Operand<i64> {
508   let ParserMatchClass = LogicalImm64NotOperand;
509 }
510
511 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
512 def Imm0_65535Operand : AsmImmRange<0, 65535>;
513 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
514   return ((uint32_t)Imm) < 65536;
515 }]> {
516   let ParserMatchClass = Imm0_65535Operand;
517   let PrintMethod = "printImmHex";
518 }
519
520 // imm0_255 predicate - True if the immediate is in the range [0,255].
521 def Imm0_255Operand : AsmImmRange<0,255>;
522
523 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
524   return ((uint32_t)Imm) < 256;
525 }]> {
526   let ParserMatchClass = Imm0_255Operand;
527   let PrintMethod = "printImm";
528 }
529
530 // imm0_127 predicate - True if the immediate is in the range [0,127]
531 def Imm0_127Operand : AsmImmRange<0, 127>;
532 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
533   return ((uint32_t)Imm) < 128;
534 }]> {
535   let ParserMatchClass = Imm0_127Operand;
536   let PrintMethod = "printImm";
537 }
538
539 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
540 // for all shift-amounts.
541
542 // imm0_63 predicate - True if the immediate is in the range [0,63]
543 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
544   return ((uint64_t)Imm) < 64;
545 }]> {
546   let ParserMatchClass = Imm0_63Operand;
547 }
548
549 // imm0_31 predicate - True if the immediate is in the range [0,31]
550 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
551   return ((uint64_t)Imm) < 32;
552 }]> {
553   let ParserMatchClass = Imm0_31Operand;
554 }
555
556 // True if the 32-bit immediate is in the range [0,31]
557 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
558   return ((uint64_t)Imm) < 32;
559 }]> {
560   let ParserMatchClass = Imm0_31Operand;
561 }
562
563 // imm0_1 predicate - True if the immediate is in the range [0,1]
564 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
565   return ((uint64_t)Imm) < 2;
566 }]> {
567   let ParserMatchClass = Imm0_1Operand;
568 }
569
570 // imm0_15 predicate - True if the immediate is in the range [0,15]
571 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
572   return ((uint64_t)Imm) < 16;
573 }]> {
574   let ParserMatchClass = Imm0_15Operand;
575 }
576
577 // imm0_7 predicate - True if the immediate is in the range [0,7]
578 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
579   return ((uint64_t)Imm) < 8;
580 }]> {
581   let ParserMatchClass = Imm0_7Operand;
582 }
583
584 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
585 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
586   return ((uint32_t)Imm) < 16;
587 }]> {
588   let ParserMatchClass = Imm0_15Operand;
589 }
590
591 // An arithmetic shifter operand:
592 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
593 //  {5-0} - imm6
594 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
595   let PrintMethod = "printShifter";
596   let ParserMatchClass = !cast<AsmOperandClass>(
597                          "ArithmeticShifterOperand" # width);
598 }
599
600 def arith_shift32 : arith_shift<i32, 32>;
601 def arith_shift64 : arith_shift<i64, 64>;
602
603 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
604     : Operand<Ty>,
605       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
606   let PrintMethod = "printShiftedRegister";
607   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
608 }
609
610 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
611 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
612
613 // An arithmetic shifter operand:
614 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
615 //  {5-0} - imm6
616 class logical_shift<int width> : Operand<i32> {
617   let PrintMethod = "printShifter";
618   let ParserMatchClass = !cast<AsmOperandClass>(
619                          "LogicalShifterOperand" # width);
620 }
621
622 def logical_shift32 : logical_shift<32>;
623 def logical_shift64 : logical_shift<64>;
624
625 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
626     : Operand<Ty>,
627       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
628   let PrintMethod = "printShiftedRegister";
629   let MIOperandInfo = (ops regclass, shiftop);
630 }
631
632 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
633 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
634
635 // A logical vector shifter operand:
636 //  {7-6} - shift type: 00 = lsl
637 //  {5-0} - imm6: #0, #8, #16, or #24
638 def logical_vec_shift : Operand<i32> {
639   let PrintMethod = "printShifter";
640   let EncoderMethod = "getVecShifterOpValue";
641   let ParserMatchClass = LogicalVecShifterOperand;
642 }
643
644 // A logical vector half-word shifter operand:
645 //  {7-6} - shift type: 00 = lsl
646 //  {5-0} - imm6: #0 or #8
647 def logical_vec_hw_shift : Operand<i32> {
648   let PrintMethod = "printShifter";
649   let EncoderMethod = "getVecShifterOpValue";
650   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
651 }
652
653 // A vector move shifter operand:
654 //  {0} - imm1: #8 or #16
655 def move_vec_shift : Operand<i32> {
656   let PrintMethod = "printShifter";
657   let EncoderMethod = "getMoveVecShifterOpValue";
658   let ParserMatchClass = MoveVecShifterOperand;
659 }
660
661 let DiagnosticType = "AddSubSecondSource" in {
662   def AddSubImmOperand : AsmOperandClass {
663     let Name = "AddSubImm";
664     let ParserMethod = "tryParseAddSubImm";
665   }
666   def AddSubImmNegOperand : AsmOperandClass {
667     let Name = "AddSubImmNeg";
668     let ParserMethod = "tryParseAddSubImm";
669   }
670 }
671 // An ADD/SUB immediate shifter operand:
672 //  second operand:
673 //  {7-6} - shift type: 00 = lsl
674 //  {5-0} - imm6: #0 or #12
675 class addsub_shifted_imm<ValueType Ty>
676     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
677   let PrintMethod = "printAddSubImm";
678   let EncoderMethod = "getAddSubImmOpValue";
679   let ParserMatchClass = AddSubImmOperand;
680   let MIOperandInfo = (ops i32imm, i32imm);
681 }
682
683 class addsub_shifted_imm_neg<ValueType Ty>
684     : Operand<Ty> {
685   let EncoderMethod = "getAddSubImmOpValue";
686   let ParserMatchClass = AddSubImmNegOperand;
687   let MIOperandInfo = (ops i32imm, i32imm);
688 }
689
690 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
691 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
692 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
693 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
694
695 def gi_addsub_shifted_imm32 :
696     GIComplexOperandMatcher<s32, "selectArithImmed">,
697     GIComplexPatternEquiv<addsub_shifted_imm32>;
698
699 def gi_addsub_shifted_imm64 :
700     GIComplexOperandMatcher<s64, "selectArithImmed">,
701     GIComplexPatternEquiv<addsub_shifted_imm64>;
702
703 class neg_addsub_shifted_imm<ValueType Ty>
704     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
705   let PrintMethod = "printAddSubImm";
706   let EncoderMethod = "getAddSubImmOpValue";
707   let ParserMatchClass = AddSubImmOperand;
708   let MIOperandInfo = (ops i32imm, i32imm);
709 }
710
711 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
712 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
713
714 // An extend operand:
715 //  {5-3} - extend type
716 //  {2-0} - imm3
717 def arith_extend : Operand<i32> {
718   let PrintMethod = "printArithExtend";
719   let ParserMatchClass = ExtendOperand;
720 }
721 def arith_extend64 : Operand<i32> {
722   let PrintMethod = "printArithExtend";
723   let ParserMatchClass = ExtendOperand64;
724 }
725
726 // 'extend' that's a lsl of a 64-bit register.
727 def arith_extendlsl64 : Operand<i32> {
728   let PrintMethod = "printArithExtend";
729   let ParserMatchClass = ExtendOperandLSL64;
730 }
731
732 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
733                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
734   let PrintMethod = "printExtendedRegister";
735   let MIOperandInfo = (ops GPR32, arith_extend);
736 }
737
738 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
739                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
740   let PrintMethod = "printExtendedRegister";
741   let MIOperandInfo = (ops GPR32, arith_extend64);
742 }
743
744 // Floating-point immediate.
745 def fpimm16 : Operand<f16>,
746               PatLeaf<(f16 fpimm), [{
747       return AArch64_AM::getFP16Imm(N->getValueAPF()) != -1;
748     }], SDNodeXForm<fpimm, [{
749       APFloat InVal = N->getValueAPF();
750       uint32_t enc = AArch64_AM::getFP16Imm(InVal);
751       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
752     }]>> {
753   let ParserMatchClass = FPImmOperand;
754   let PrintMethod = "printFPImmOperand";
755 }
756 def fpimm32 : Operand<f32>,
757               PatLeaf<(f32 fpimm), [{
758       return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
759     }], SDNodeXForm<fpimm, [{
760       APFloat InVal = N->getValueAPF();
761       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
762       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
763     }]>> {
764   let ParserMatchClass = FPImmOperand;
765   let PrintMethod = "printFPImmOperand";
766 }
767 def fpimm64 : Operand<f64>,
768               PatLeaf<(f64 fpimm), [{
769       return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
770     }], SDNodeXForm<fpimm, [{
771       APFloat InVal = N->getValueAPF();
772       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
773       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
774     }]>> {
775   let ParserMatchClass = FPImmOperand;
776   let PrintMethod = "printFPImmOperand";
777 }
778
779 def fpimm8 : Operand<i32> {
780   let ParserMatchClass = FPImmOperand;
781   let PrintMethod = "printFPImmOperand";
782 }
783
784 def fpimm0 : PatLeaf<(fpimm), [{
785   return N->isExactlyValue(+0.0);
786 }]>;
787
788 // Vector lane operands
789 class AsmVectorIndex<string Suffix> : AsmOperandClass {
790   let Name = "VectorIndex" # Suffix;
791   let DiagnosticType = "InvalidIndex" # Suffix;
792 }
793 def VectorIndex1Operand : AsmVectorIndex<"1">;
794 def VectorIndexBOperand : AsmVectorIndex<"B">;
795 def VectorIndexHOperand : AsmVectorIndex<"H">;
796 def VectorIndexSOperand : AsmVectorIndex<"S">;
797 def VectorIndexDOperand : AsmVectorIndex<"D">;
798
799 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
800   return ((uint64_t)Imm) == 1;
801 }]> {
802   let ParserMatchClass = VectorIndex1Operand;
803   let PrintMethod = "printVectorIndex";
804   let MIOperandInfo = (ops i64imm);
805 }
806 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
807   return ((uint64_t)Imm) < 16;
808 }]> {
809   let ParserMatchClass = VectorIndexBOperand;
810   let PrintMethod = "printVectorIndex";
811   let MIOperandInfo = (ops i64imm);
812 }
813 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
814   return ((uint64_t)Imm) < 8;
815 }]> {
816   let ParserMatchClass = VectorIndexHOperand;
817   let PrintMethod = "printVectorIndex";
818   let MIOperandInfo = (ops i64imm);
819 }
820 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
821   return ((uint64_t)Imm) < 4;
822 }]> {
823   let ParserMatchClass = VectorIndexSOperand;
824   let PrintMethod = "printVectorIndex";
825   let MIOperandInfo = (ops i64imm);
826 }
827 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
828   return ((uint64_t)Imm) < 2;
829 }]> {
830   let ParserMatchClass = VectorIndexDOperand;
831   let PrintMethod = "printVectorIndex";
832   let MIOperandInfo = (ops i64imm);
833 }
834
835 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
836 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
837 // are encoded as the eight bit value 'abcdefgh'.
838 def simdimmtype10 : Operand<i32>,
839                     PatLeaf<(f64 fpimm), [{
840       return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
841                                                .bitcastToAPInt()
842                                                .getZExtValue());
843     }], SDNodeXForm<fpimm, [{
844       APFloat InVal = N->getValueAPF();
845       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
846                                                            .bitcastToAPInt()
847                                                            .getZExtValue());
848       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
849     }]>> {
850   let ParserMatchClass = SIMDImmType10Operand;
851   let PrintMethod = "printSIMDType10Operand";
852 }
853
854
855 //---
856 // System management
857 //---
858
859 // Base encoding for system instruction operands.
860 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
861 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
862                   list<dag> pattern = []>
863     : I<oops, iops, asm, operands, "", pattern> {
864   let Inst{31-22} = 0b1101010100;
865   let Inst{21}    = L;
866 }
867
868 // System instructions which do not have an Rt register.
869 class SimpleSystemI<bit L, dag iops, string asm, string operands,
870                     list<dag> pattern = []>
871     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
872   let Inst{4-0} = 0b11111;
873 }
874
875 // System instructions which have an Rt register.
876 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
877     : BaseSystemI<L, oops, iops, asm, operands>,
878       Sched<[WriteSys]> {
879   bits<5> Rt;
880   let Inst{4-0} = Rt;
881 }
882
883 // Hint instructions that take both a CRm and a 3-bit immediate.
884 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
885 // model patterns with sufficiently fine granularity
886 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
887   class HintI<string mnemonic>
888       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
889                       [(int_aarch64_hint imm0_127:$imm)]>,
890         Sched<[WriteHint]> {
891     bits <7> imm;
892     let Inst{20-12} = 0b000110010;
893     let Inst{11-5} = imm;
894   }
895
896 // System instructions taking a single literal operand which encodes into
897 // CRm. op2 differentiates the opcodes.
898 def BarrierAsmOperand : AsmOperandClass {
899   let Name = "Barrier";
900   let ParserMethod = "tryParseBarrierOperand";
901 }
902 def barrier_op : Operand<i32> {
903   let PrintMethod = "printBarrierOption";
904   let ParserMatchClass = BarrierAsmOperand;
905 }
906 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
907                  list<dag> pattern = []>
908     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
909       Sched<[WriteBarrier]> {
910   bits<4> CRm;
911   let Inst{20-12} = 0b000110011;
912   let Inst{11-8} = CRm;
913   let Inst{7-5} = opc;
914 }
915
916 // MRS/MSR system instructions. These have different operand classes because
917 // a different subset of registers can be accessed through each instruction.
918 def MRSSystemRegisterOperand : AsmOperandClass {
919   let Name = "MRSSystemRegister";
920   let ParserMethod = "tryParseSysReg";
921   let DiagnosticType = "MRS";
922 }
923 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
924 def mrs_sysreg_op : Operand<i32> {
925   let ParserMatchClass = MRSSystemRegisterOperand;
926   let DecoderMethod = "DecodeMRSSystemRegister";
927   let PrintMethod = "printMRSSystemRegister";
928 }
929
930 def MSRSystemRegisterOperand : AsmOperandClass {
931   let Name = "MSRSystemRegister";
932   let ParserMethod = "tryParseSysReg";
933   let DiagnosticType = "MSR";
934 }
935 def msr_sysreg_op : Operand<i32> {
936   let ParserMatchClass = MSRSystemRegisterOperand;
937   let DecoderMethod = "DecodeMSRSystemRegister";
938   let PrintMethod = "printMSRSystemRegister";
939 }
940
941 def PSBHintOperand : AsmOperandClass {
942   let Name = "PSBHint";
943   let ParserMethod = "tryParsePSBHint";
944 }
945 def psbhint_op : Operand<i32> {
946   let ParserMatchClass = PSBHintOperand;
947   let PrintMethod = "printPSBHintOp";
948   let MCOperandPredicate = [{
949     // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
950     // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
951     if (!MCOp.isImm())
952       return false;
953     return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
954   }];
955 }
956
957 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
958                        "mrs", "\t$Rt, $systemreg"> {
959   bits<16> systemreg;
960   let Inst{20-5} = systemreg;
961 }
962
963 // FIXME: Some of these def NZCV, others don't. Best way to model that?
964 // Explicitly modeling each of the system register as a register class
965 // would do it, but feels like overkill at this point.
966 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
967                        "msr", "\t$systemreg, $Rt"> {
968   bits<16> systemreg;
969   let Inst{20-5} = systemreg;
970 }
971
972 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
973   let Name = "SystemPStateFieldWithImm0_15";
974   let ParserMethod = "tryParseSysReg";
975 }
976 def pstatefield4_op : Operand<i32> {
977   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
978   let PrintMethod = "printSystemPStateField";
979 }
980
981 let Defs = [NZCV] in
982 class MSRpstateImm0_15
983   : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
984                   "msr", "\t$pstatefield, $imm">,
985     Sched<[WriteSys]> {
986   bits<6> pstatefield;
987   bits<4> imm;
988   let Inst{20-19} = 0b00;
989   let Inst{18-16} = pstatefield{5-3};
990   let Inst{15-12} = 0b0100;
991   let Inst{11-8} = imm;
992   let Inst{7-5} = pstatefield{2-0};
993
994   let DecoderMethod = "DecodeSystemPStateInstruction";
995   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
996   // Fail the decoder should attempt to decode the instruction as MSRI.
997   let hasCompleteDecoder = 0;
998 }
999
1000 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1001   let Name = "SystemPStateFieldWithImm0_1";
1002   let ParserMethod = "tryParseSysReg";
1003 }
1004 def pstatefield1_op : Operand<i32> {
1005   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1006   let PrintMethod = "printSystemPStateField";
1007 }
1008
1009 let Defs = [NZCV] in
1010 class MSRpstateImm0_1
1011   : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
1012                   "msr", "\t$pstatefield, $imm">,
1013     Sched<[WriteSys]> {
1014   bits<6> pstatefield;
1015   bit imm;
1016   let Inst{20-19} = 0b00;
1017   let Inst{18-16} = pstatefield{5-3};
1018   let Inst{15-9} = 0b0100000;
1019   let Inst{8} = imm;
1020   let Inst{7-5} = pstatefield{2-0};
1021
1022   let DecoderMethod = "DecodeSystemPStateInstruction";
1023   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1024   // Fail the decoder should attempt to decode the instruction as MSRI.
1025   let hasCompleteDecoder = 0;
1026 }
1027
1028 // SYS and SYSL generic system instructions.
1029 def SysCRAsmOperand : AsmOperandClass {
1030   let Name = "SysCR";
1031   let ParserMethod = "tryParseSysCROperand";
1032 }
1033
1034 def sys_cr_op : Operand<i32> {
1035   let PrintMethod = "printSysCROperand";
1036   let ParserMatchClass = SysCRAsmOperand;
1037 }
1038
1039 class SystemXtI<bit L, string asm>
1040   : RtSystemI<L, (outs),
1041        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1042        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1043   bits<3> op1;
1044   bits<4> Cn;
1045   bits<4> Cm;
1046   bits<3> op2;
1047   let Inst{20-19} = 0b01;
1048   let Inst{18-16} = op1;
1049   let Inst{15-12} = Cn;
1050   let Inst{11-8}  = Cm;
1051   let Inst{7-5}   = op2;
1052 }
1053
1054 class SystemLXtI<bit L, string asm>
1055   : RtSystemI<L, (outs),
1056        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1057        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1058   bits<3> op1;
1059   bits<4> Cn;
1060   bits<4> Cm;
1061   bits<3> op2;
1062   let Inst{20-19} = 0b01;
1063   let Inst{18-16} = op1;
1064   let Inst{15-12} = Cn;
1065   let Inst{11-8}  = Cm;
1066   let Inst{7-5}   = op2;
1067 }
1068
1069
1070 // Branch (register) instructions:
1071 //
1072 //  case opc of
1073 //    0001 blr
1074 //    0000 br
1075 //    0101 dret
1076 //    0100 eret
1077 //    0010 ret
1078 //    otherwise UNDEFINED
1079 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1080                     string operands, list<dag> pattern>
1081     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1082   let Inst{31-25} = 0b1101011;
1083   let Inst{24-21} = opc;
1084   let Inst{20-16} = 0b11111;
1085   let Inst{15-10} = 0b000000;
1086   let Inst{4-0}   = 0b00000;
1087 }
1088
1089 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1090     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1091   bits<5> Rn;
1092   let Inst{9-5} = Rn;
1093 }
1094
1095 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1096 class SpecialReturn<bits<4> opc, string asm>
1097     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1098   let Inst{9-5} = 0b11111;
1099 }
1100
1101 //---
1102 // Conditional branch instruction.
1103 //---
1104
1105 // Condition code.
1106 // 4-bit immediate. Pretty-printed as <cc>
1107 def ccode : Operand<i32> {
1108   let PrintMethod = "printCondCode";
1109   let ParserMatchClass = CondCode;
1110 }
1111 def inv_ccode : Operand<i32> {
1112   // AL and NV are invalid in the aliases which use inv_ccode
1113   let PrintMethod = "printInverseCondCode";
1114   let ParserMatchClass = CondCode;
1115   let MCOperandPredicate = [{
1116     return MCOp.isImm() &&
1117            MCOp.getImm() != AArch64CC::AL &&
1118            MCOp.getImm() != AArch64CC::NV;
1119   }];
1120 }
1121
1122 // Conditional branch target. 19-bit immediate. The low two bits of the target
1123 // offset are implied zero and so are not part of the immediate.
1124 def am_brcond : Operand<OtherVT> {
1125   let EncoderMethod = "getCondBranchTargetOpValue";
1126   let DecoderMethod = "DecodePCRelLabel19";
1127   let PrintMethod = "printAlignedLabel";
1128   let ParserMatchClass = PCRelLabel19Operand;
1129 }
1130
1131 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1132                      "b", ".$cond\t$target", "",
1133                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1134                    Sched<[WriteBr]> {
1135   let isBranch = 1;
1136   let isTerminator = 1;
1137   let Uses = [NZCV];
1138
1139   bits<4> cond;
1140   bits<19> target;
1141   let Inst{31-24} = 0b01010100;
1142   let Inst{23-5} = target;
1143   let Inst{4} = 0;
1144   let Inst{3-0} = cond;
1145 }
1146
1147 //---
1148 // Compare-and-branch instructions.
1149 //---
1150 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1151     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1152          asm, "\t$Rt, $target", "",
1153          [(node regtype:$Rt, bb:$target)]>,
1154       Sched<[WriteBr]> {
1155   let isBranch = 1;
1156   let isTerminator = 1;
1157
1158   bits<5> Rt;
1159   bits<19> target;
1160   let Inst{30-25} = 0b011010;
1161   let Inst{24}    = op;
1162   let Inst{23-5}  = target;
1163   let Inst{4-0}   = Rt;
1164 }
1165
1166 multiclass CmpBranch<bit op, string asm, SDNode node> {
1167   def W : BaseCmpBranch<GPR32, op, asm, node> {
1168     let Inst{31} = 0;
1169   }
1170   def X : BaseCmpBranch<GPR64, op, asm, node> {
1171     let Inst{31} = 1;
1172   }
1173 }
1174
1175 //---
1176 // Test-bit-and-branch instructions.
1177 //---
1178 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1179 // the target offset are implied zero and so are not part of the immediate.
1180 def am_tbrcond : Operand<OtherVT> {
1181   let EncoderMethod = "getTestBranchTargetOpValue";
1182   let PrintMethod = "printAlignedLabel";
1183   let ParserMatchClass = BranchTarget14Operand;
1184 }
1185
1186 // AsmOperand classes to emit (or not) special diagnostics
1187 def TBZImm0_31Operand : AsmOperandClass {
1188   let Name = "TBZImm0_31";
1189   let PredicateMethod = "isImmInRange<0,31>";
1190   let RenderMethod = "addImm0_31Operands";
1191 }
1192 def TBZImm32_63Operand : AsmOperandClass {
1193   let Name = "Imm32_63";
1194   let PredicateMethod = "isImmInRange<32,63>";
1195   let DiagnosticType = "InvalidImm0_63";
1196 }
1197
1198 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1199   return (((uint32_t)Imm) < 32);
1200 }]> {
1201   let ParserMatchClass = matcher;
1202 }
1203
1204 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1205 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1206
1207 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1208   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1209 }]> {
1210   let ParserMatchClass = TBZImm32_63Operand;
1211 }
1212
1213 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1214                      bit op, string asm, SDNode node>
1215     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1216        asm, "\t$Rt, $bit_off, $target", "",
1217        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1218       Sched<[WriteBr]> {
1219   let isBranch = 1;
1220   let isTerminator = 1;
1221
1222   bits<5> Rt;
1223   bits<6> bit_off;
1224   bits<14> target;
1225
1226   let Inst{30-25} = 0b011011;
1227   let Inst{24}    = op;
1228   let Inst{23-19} = bit_off{4-0};
1229   let Inst{18-5}  = target;
1230   let Inst{4-0}   = Rt;
1231
1232   let DecoderMethod = "DecodeTestAndBranch";
1233 }
1234
1235 multiclass TestBranch<bit op, string asm, SDNode node> {
1236   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1237     let Inst{31} = 0;
1238   }
1239
1240   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1241     let Inst{31} = 1;
1242   }
1243
1244   // Alias X-reg with 0-31 imm to W-Reg.
1245   def : InstAlias<asm # "\t$Rd, $imm, $target",
1246                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1247                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1248   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1249             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1250             tbz_imm0_31_diag:$imm, bb:$target)>;
1251 }
1252
1253 //---
1254 // Unconditional branch (immediate) instructions.
1255 //---
1256 def am_b_target : Operand<OtherVT> {
1257   let EncoderMethod = "getBranchTargetOpValue";
1258   let PrintMethod = "printAlignedLabel";
1259   let ParserMatchClass = BranchTarget26Operand;
1260 }
1261 def am_bl_target : Operand<i64> {
1262   let EncoderMethod = "getBranchTargetOpValue";
1263   let PrintMethod = "printAlignedLabel";
1264   let ParserMatchClass = BranchTarget26Operand;
1265 }
1266
1267 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1268     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1269   bits<26> addr;
1270   let Inst{31}    = op;
1271   let Inst{30-26} = 0b00101;
1272   let Inst{25-0}  = addr;
1273
1274   let DecoderMethod = "DecodeUnconditionalBranch";
1275 }
1276
1277 class BranchImm<bit op, string asm, list<dag> pattern>
1278     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1279 class CallImm<bit op, string asm, list<dag> pattern>
1280     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1281
1282 //---
1283 // Basic one-operand data processing instructions.
1284 //---
1285
1286 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1287 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1288                          SDPatternOperator node>
1289   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1290       [(set regtype:$Rd, (node regtype:$Rn))]>,
1291     Sched<[WriteI, ReadI]> {
1292   bits<5> Rd;
1293   bits<5> Rn;
1294
1295   let Inst{30-13} = 0b101101011000000000;
1296   let Inst{12-10} = opc;
1297   let Inst{9-5}   = Rn;
1298   let Inst{4-0}   = Rd;
1299 }
1300
1301 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1302 multiclass OneOperandData<bits<3> opc, string asm,
1303                           SDPatternOperator node = null_frag> {
1304   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1305     let Inst{31} = 0;
1306   }
1307
1308   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1309     let Inst{31} = 1;
1310   }
1311 }
1312
1313 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1314     : BaseOneOperandData<opc, GPR32, asm, node> {
1315   let Inst{31} = 0;
1316 }
1317
1318 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1319     : BaseOneOperandData<opc, GPR64, asm, node> {
1320   let Inst{31} = 1;
1321 }
1322
1323 //---
1324 // Basic two-operand data processing instructions.
1325 //---
1326 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1327                           list<dag> pattern>
1328     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1329         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1330       Sched<[WriteI, ReadI, ReadI]> {
1331   let Uses = [NZCV];
1332   bits<5> Rd;
1333   bits<5> Rn;
1334   bits<5> Rm;
1335   let Inst{30}    = isSub;
1336   let Inst{28-21} = 0b11010000;
1337   let Inst{20-16} = Rm;
1338   let Inst{15-10} = 0;
1339   let Inst{9-5}   = Rn;
1340   let Inst{4-0}   = Rd;
1341 }
1342
1343 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1344                       SDNode OpNode>
1345     : BaseBaseAddSubCarry<isSub, regtype, asm,
1346         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1347
1348 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1349                               SDNode OpNode>
1350     : BaseBaseAddSubCarry<isSub, regtype, asm,
1351         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1352          (implicit NZCV)]> {
1353   let Defs = [NZCV];
1354 }
1355
1356 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1357                        SDNode OpNode, SDNode OpNode_setflags> {
1358   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1359     let Inst{31} = 0;
1360     let Inst{29} = 0;
1361   }
1362   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1363     let Inst{31} = 1;
1364     let Inst{29} = 0;
1365   }
1366
1367   // Sets flags.
1368   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1369                                     OpNode_setflags> {
1370     let Inst{31} = 0;
1371     let Inst{29} = 1;
1372   }
1373   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1374                                     OpNode_setflags> {
1375     let Inst{31} = 1;
1376     let Inst{29} = 1;
1377   }
1378 }
1379
1380 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1381                      SDPatternOperator OpNode>
1382   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1383       asm, "\t$Rd, $Rn, $Rm", "",
1384       [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1385   bits<5> Rd;
1386   bits<5> Rn;
1387   bits<5> Rm;
1388   let Inst{30-21} = 0b0011010110;
1389   let Inst{20-16} = Rm;
1390   let Inst{15-14} = 0b00;
1391   let Inst{13-10} = opc;
1392   let Inst{9-5}   = Rn;
1393   let Inst{4-0}   = Rd;
1394 }
1395
1396 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1397               SDPatternOperator OpNode>
1398     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1399   let Inst{10}    = isSigned;
1400 }
1401
1402 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1403   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1404            Sched<[WriteID32, ReadID, ReadID]> {
1405     let Inst{31} = 0;
1406   }
1407   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1408            Sched<[WriteID64, ReadID, ReadID]> {
1409     let Inst{31} = 1;
1410   }
1411 }
1412
1413 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1414                 SDPatternOperator OpNode = null_frag>
1415   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1416     Sched<[WriteIS, ReadI]> {
1417   let Inst{11-10} = shift_type;
1418 }
1419
1420 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1421   def Wr : BaseShift<shift_type, GPR32, asm> {
1422     let Inst{31} = 0;
1423   }
1424
1425   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1426     let Inst{31} = 1;
1427   }
1428
1429   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1430             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1431                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1432
1433   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1434             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1435
1436   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1437             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1438
1439   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1440             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1441 }
1442
1443 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1444     : InstAlias<asm#"\t$dst, $src1, $src2",
1445                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1446
1447 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1448                        RegisterClass addtype, string asm,
1449                        list<dag> pattern>
1450   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1451       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1452   bits<5> Rd;
1453   bits<5> Rn;
1454   bits<5> Rm;
1455   bits<5> Ra;
1456   let Inst{30-24} = 0b0011011;
1457   let Inst{23-21} = opc;
1458   let Inst{20-16} = Rm;
1459   let Inst{15}    = isSub;
1460   let Inst{14-10} = Ra;
1461   let Inst{9-5}   = Rn;
1462   let Inst{4-0}   = Rd;
1463 }
1464
1465 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1466   // MADD/MSUB generation is decided by MachineCombiner.cpp
1467   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1468       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1469       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1470     let Inst{31} = 0;
1471   }
1472
1473   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1474       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1475       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1476     let Inst{31} = 1;
1477   }
1478 }
1479
1480 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1481                    SDNode AccNode, SDNode ExtNode>
1482   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1483     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1484                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1485     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1486   let Inst{31} = 1;
1487 }
1488
1489 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1490   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1491       asm, "\t$Rd, $Rn, $Rm", "",
1492       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1493     Sched<[WriteIM64, ReadIM, ReadIM]> {
1494   bits<5> Rd;
1495   bits<5> Rn;
1496   bits<5> Rm;
1497   let Inst{31-24} = 0b10011011;
1498   let Inst{23-21} = opc;
1499   let Inst{20-16} = Rm;
1500   let Inst{15}    = 0;
1501   let Inst{9-5}   = Rn;
1502   let Inst{4-0}   = Rd;
1503
1504   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1505   // (i.e. all bits 1) but is ignored by the processor.
1506   let PostEncoderMethod = "fixMulHigh";
1507 }
1508
1509 class MulAccumWAlias<string asm, Instruction inst>
1510     : InstAlias<asm#"\t$dst, $src1, $src2",
1511                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1512 class MulAccumXAlias<string asm, Instruction inst>
1513     : InstAlias<asm#"\t$dst, $src1, $src2",
1514                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1515 class WideMulAccumAlias<string asm, Instruction inst>
1516     : InstAlias<asm#"\t$dst, $src1, $src2",
1517                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1518
1519 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1520               SDPatternOperator OpNode, string asm>
1521   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1522       asm, "\t$Rd, $Rn, $Rm", "",
1523       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1524     Sched<[WriteISReg, ReadI, ReadISReg]> {
1525   bits<5> Rd;
1526   bits<5> Rn;
1527   bits<5> Rm;
1528
1529   let Inst{31} = sf;
1530   let Inst{30-21} = 0b0011010110;
1531   let Inst{20-16} = Rm;
1532   let Inst{15-13} = 0b010;
1533   let Inst{12} = C;
1534   let Inst{11-10} = sz;
1535   let Inst{9-5} = Rn;
1536   let Inst{4-0} = Rd;
1537   let Predicates = [HasCRC];
1538 }
1539
1540 //---
1541 // Address generation.
1542 //---
1543
1544 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1545     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1546         pattern>,
1547       Sched<[WriteI]> {
1548   bits<5>  Xd;
1549   bits<21> label;
1550   let Inst{31}    = page;
1551   let Inst{30-29} = label{1-0};
1552   let Inst{28-24} = 0b10000;
1553   let Inst{23-5}  = label{20-2};
1554   let Inst{4-0}   = Xd;
1555
1556   let DecoderMethod = "DecodeAdrInstruction";
1557 }
1558
1559 //---
1560 // Move immediate.
1561 //---
1562
1563 def movimm32_imm : Operand<i32> {
1564   let ParserMatchClass = Imm0_65535Operand;
1565   let EncoderMethod = "getMoveWideImmOpValue";
1566   let PrintMethod = "printImm";
1567 }
1568 def movimm32_shift : Operand<i32> {
1569   let PrintMethod = "printShifter";
1570   let ParserMatchClass = MovImm32ShifterOperand;
1571 }
1572 def movimm64_shift : Operand<i32> {
1573   let PrintMethod = "printShifter";
1574   let ParserMatchClass = MovImm64ShifterOperand;
1575 }
1576
1577 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1578 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1579                         string asm>
1580   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1581        asm, "\t$Rd, $imm$shift", "", []>,
1582     Sched<[WriteImm]> {
1583   bits<5> Rd;
1584   bits<16> imm;
1585   bits<6> shift;
1586   let Inst{30-29} = opc;
1587   let Inst{28-23} = 0b100101;
1588   let Inst{22-21} = shift{5-4};
1589   let Inst{20-5}  = imm;
1590   let Inst{4-0}   = Rd;
1591
1592   let DecoderMethod = "DecodeMoveImmInstruction";
1593 }
1594
1595 multiclass MoveImmediate<bits<2> opc, string asm> {
1596   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1597     let Inst{31} = 0;
1598   }
1599
1600   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1601     let Inst{31} = 1;
1602   }
1603 }
1604
1605 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1606 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1607                           string asm>
1608   : I<(outs regtype:$Rd),
1609       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1610        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1611     Sched<[WriteI, ReadI]> {
1612   bits<5> Rd;
1613   bits<16> imm;
1614   bits<6> shift;
1615   let Inst{30-29} = opc;
1616   let Inst{28-23} = 0b100101;
1617   let Inst{22-21} = shift{5-4};
1618   let Inst{20-5}  = imm;
1619   let Inst{4-0}   = Rd;
1620
1621   let DecoderMethod = "DecodeMoveImmInstruction";
1622 }
1623
1624 multiclass InsertImmediate<bits<2> opc, string asm> {
1625   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1626     let Inst{31} = 0;
1627   }
1628
1629   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1630     let Inst{31} = 1;
1631   }
1632 }
1633
1634 //---
1635 // Add/Subtract
1636 //---
1637
1638 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1639                     RegisterClass srcRegtype, addsub_shifted_imm immtype,
1640                     string asm, SDPatternOperator OpNode>
1641     : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1642         asm, "\t$Rd, $Rn, $imm", "",
1643         [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1644       Sched<[WriteI, ReadI]>  {
1645   bits<5>  Rd;
1646   bits<5>  Rn;
1647   bits<14> imm;
1648   let Inst{30}    = isSub;
1649   let Inst{29}    = setFlags;
1650   let Inst{28-24} = 0b10001;
1651   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1652   let Inst{21-10} = imm{11-0};
1653   let Inst{9-5}   = Rn;
1654   let Inst{4-0}   = Rd;
1655   let DecoderMethod = "DecodeBaseAddSubImm";
1656 }
1657
1658 class BaseAddSubRegPseudo<RegisterClass regtype,
1659                           SDPatternOperator OpNode>
1660     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1661              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1662       Sched<[WriteI, ReadI, ReadI]>;
1663
1664 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1665                      arith_shifted_reg shifted_regtype, string asm,
1666                      SDPatternOperator OpNode>
1667     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1668         asm, "\t$Rd, $Rn, $Rm", "",
1669         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1670       Sched<[WriteISReg, ReadI, ReadISReg]> {
1671   // The operands are in order to match the 'addr' MI operands, so we
1672   // don't need an encoder method and by-name matching. Just use the default
1673   // in-order handling. Since we're using by-order, make sure the names
1674   // do not match.
1675   bits<5> dst;
1676   bits<5> src1;
1677   bits<5> src2;
1678   bits<8> shift;
1679   let Inst{30}    = isSub;
1680   let Inst{29}    = setFlags;
1681   let Inst{28-24} = 0b01011;
1682   let Inst{23-22} = shift{7-6};
1683   let Inst{21}    = 0;
1684   let Inst{20-16} = src2;
1685   let Inst{15-10} = shift{5-0};
1686   let Inst{9-5}   = src1;
1687   let Inst{4-0}   = dst;
1688
1689   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1690 }
1691
1692 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1693                      RegisterClass src1Regtype, Operand src2Regtype,
1694                      string asm, SDPatternOperator OpNode>
1695     : I<(outs dstRegtype:$R1),
1696         (ins src1Regtype:$R2, src2Regtype:$R3),
1697         asm, "\t$R1, $R2, $R3", "",
1698         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1699       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1700   bits<5> Rd;
1701   bits<5> Rn;
1702   bits<5> Rm;
1703   bits<6> ext;
1704   let Inst{30}    = isSub;
1705   let Inst{29}    = setFlags;
1706   let Inst{28-24} = 0b01011;
1707   let Inst{23-21} = 0b001;
1708   let Inst{20-16} = Rm;
1709   let Inst{15-13} = ext{5-3};
1710   let Inst{12-10} = ext{2-0};
1711   let Inst{9-5}   = Rn;
1712   let Inst{4-0}   = Rd;
1713
1714   let DecoderMethod = "DecodeAddSubERegInstruction";
1715 }
1716
1717 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1718 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1719                        RegisterClass src1Regtype, RegisterClass src2Regtype,
1720                        Operand ext_op, string asm>
1721     : I<(outs dstRegtype:$Rd),
1722         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1723         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1724       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1725   bits<5> Rd;
1726   bits<5> Rn;
1727   bits<5> Rm;
1728   bits<6> ext;
1729   let Inst{30}    = isSub;
1730   let Inst{29}    = setFlags;
1731   let Inst{28-24} = 0b01011;
1732   let Inst{23-21} = 0b001;
1733   let Inst{20-16} = Rm;
1734   let Inst{15}    = ext{5};
1735   let Inst{12-10} = ext{2-0};
1736   let Inst{9-5}   = Rn;
1737   let Inst{4-0}   = Rd;
1738
1739   let DecoderMethod = "DecodeAddSubERegInstruction";
1740 }
1741
1742 // Aliases for register+register add/subtract.
1743 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1744                      RegisterClass src1Regtype, RegisterClass src2Regtype,
1745                      int shiftExt>
1746     : InstAlias<asm#"\t$dst, $src1, $src2",
1747                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1748                       shiftExt)>;
1749
1750 multiclass AddSub<bit isSub, string mnemonic, string alias,
1751                   SDPatternOperator OpNode = null_frag> {
1752   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1753   // Add/Subtract immediate
1754   // Increase the weight of the immediate variant to try to match it before
1755   // the extended register variant.
1756   // We used to match the register variant before the immediate when the
1757   // register argument could be implicitly zero-extended.
1758   let AddedComplexity = 6 in
1759   def Wri  : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1760                            mnemonic, OpNode> {
1761     let Inst{31} = 0;
1762   }
1763   let AddedComplexity = 6 in
1764   def Xri  : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1765                            mnemonic, OpNode> {
1766     let Inst{31} = 1;
1767   }
1768
1769   // Add/Subtract register - Only used for CodeGen
1770   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1771   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1772
1773   // Add/Subtract shifted register
1774   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1775                            OpNode> {
1776     let Inst{31} = 0;
1777   }
1778   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1779                            OpNode> {
1780     let Inst{31} = 1;
1781   }
1782   }
1783
1784   // Add/Subtract extended register
1785   let AddedComplexity = 1, hasSideEffects = 0 in {
1786   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1787                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1788     let Inst{31} = 0;
1789   }
1790   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1791                            arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1792     let Inst{31} = 1;
1793   }
1794   }
1795
1796   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1797                                arith_extendlsl64, mnemonic> {
1798     // UXTX and SXTX only.
1799     let Inst{14-13} = 0b11;
1800     let Inst{31} = 1;
1801   }
1802
1803   // add Rd, Rb, -imm -> sub Rd, Rn, imm
1804   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1805                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1806                       addsub_shifted_imm32_neg:$imm), 0>;
1807   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1808                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1809                        addsub_shifted_imm64_neg:$imm), 0>;
1810
1811   // Register/register aliases with no shift when SP is not used.
1812   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1813                        GPR32, GPR32, GPR32, 0>;
1814   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1815                        GPR64, GPR64, GPR64, 0>;
1816
1817   // Register/register aliases with no shift when either the destination or
1818   // first source register is SP.
1819   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1820                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1821   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1822                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1823   def : AddSubRegAlias<mnemonic,
1824                        !cast<Instruction>(NAME#"Xrx64"),
1825                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1826   def : AddSubRegAlias<mnemonic,
1827                        !cast<Instruction>(NAME#"Xrx64"),
1828                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1829 }
1830
1831 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1832                    string alias, string cmpAlias> {
1833   let isCompare = 1, Defs = [NZCV] in {
1834   // Add/Subtract immediate
1835   def Wri  : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1836                            mnemonic, OpNode> {
1837     let Inst{31} = 0;
1838   }
1839   def Xri  : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1840                            mnemonic, OpNode> {
1841     let Inst{31} = 1;
1842   }
1843
1844   // Add/Subtract register
1845   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1846   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1847
1848   // Add/Subtract shifted register
1849   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1850                            OpNode> {
1851     let Inst{31} = 0;
1852   }
1853   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1854                            OpNode> {
1855     let Inst{31} = 1;
1856   }
1857
1858   // Add/Subtract extended register
1859   let AddedComplexity = 1 in {
1860   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1861                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1862     let Inst{31} = 0;
1863   }
1864   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1865                            arith_extended_reg32<i64>, mnemonic, OpNode> {
1866     let Inst{31} = 1;
1867   }
1868   }
1869
1870   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1871                                arith_extendlsl64, mnemonic> {
1872     // UXTX and SXTX only.
1873     let Inst{14-13} = 0b11;
1874     let Inst{31} = 1;
1875   }
1876   } // Defs = [NZCV]
1877
1878   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
1879   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1880                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1881                       addsub_shifted_imm32_neg:$imm), 0>;
1882   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1883                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1884                        addsub_shifted_imm64_neg:$imm), 0>;
1885
1886   // Compare aliases
1887   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1888                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
1889   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1890                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
1891   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
1892                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1893   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
1894                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1895   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
1896                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
1897   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
1898                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
1899   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
1900                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1901
1902   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
1903   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1904                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
1905   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1906                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1907
1908   // Compare shorthands
1909   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
1910                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
1911   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
1912                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
1913   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
1914                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
1915   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
1916                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
1917
1918   // Register/register aliases with no shift when SP is not used.
1919   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1920                        GPR32, GPR32, GPR32, 0>;
1921   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1922                        GPR64, GPR64, GPR64, 0>;
1923
1924   // Register/register aliases with no shift when the first source register
1925   // is SP.
1926   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1927                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1928   def : AddSubRegAlias<mnemonic,
1929                        !cast<Instruction>(NAME#"Xrx64"),
1930                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1931 }
1932
1933 //---
1934 // Extract
1935 //---
1936 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1937                                       SDTCisPtrTy<3>]>;
1938 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1939
1940 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1941                      list<dag> patterns>
1942     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1943          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1944       Sched<[WriteExtr, ReadExtrHi]> {
1945   bits<5> Rd;
1946   bits<5> Rn;
1947   bits<5> Rm;
1948   bits<6> imm;
1949
1950   let Inst{30-23} = 0b00100111;
1951   let Inst{21}    = 0;
1952   let Inst{20-16} = Rm;
1953   let Inst{15-10} = imm;
1954   let Inst{9-5}   = Rn;
1955   let Inst{4-0}   = Rd;
1956 }
1957
1958 multiclass ExtractImm<string asm> {
1959   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1960                       [(set GPR32:$Rd,
1961                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1962     let Inst{31} = 0;
1963     let Inst{22} = 0;
1964     // imm<5> must be zero.
1965     let imm{5}   = 0;
1966   }
1967   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1968                       [(set GPR64:$Rd,
1969                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1970
1971     let Inst{31} = 1;
1972     let Inst{22} = 1;
1973   }
1974 }
1975
1976 //---
1977 // Bitfield
1978 //---
1979
1980 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1981 class BaseBitfieldImm<bits<2> opc,
1982                       RegisterClass regtype, Operand imm_type, string asm>
1983     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1984          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1985       Sched<[WriteIS, ReadI]> {
1986   bits<5> Rd;
1987   bits<5> Rn;
1988   bits<6> immr;
1989   bits<6> imms;
1990
1991   let Inst{30-29} = opc;
1992   let Inst{28-23} = 0b100110;
1993   let Inst{21-16} = immr;
1994   let Inst{15-10} = imms;
1995   let Inst{9-5}   = Rn;
1996   let Inst{4-0}   = Rd;
1997 }
1998
1999 multiclass BitfieldImm<bits<2> opc, string asm> {
2000   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2001     let Inst{31} = 0;
2002     let Inst{22} = 0;
2003     // imms<5> and immr<5> must be zero, else ReservedValue().
2004     let Inst{21} = 0;
2005     let Inst{15} = 0;
2006   }
2007   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2008     let Inst{31} = 1;
2009     let Inst{22} = 1;
2010   }
2011 }
2012
2013 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2014 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2015                       RegisterClass regtype, Operand imm_type, string asm>
2016     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2017                              imm_type:$imms),
2018          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2019       Sched<[WriteIS, ReadI]> {
2020   bits<5> Rd;
2021   bits<5> Rn;
2022   bits<6> immr;
2023   bits<6> imms;
2024
2025   let Inst{30-29} = opc;
2026   let Inst{28-23} = 0b100110;
2027   let Inst{21-16} = immr;
2028   let Inst{15-10} = imms;
2029   let Inst{9-5}   = Rn;
2030   let Inst{4-0}   = Rd;
2031 }
2032
2033 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2034   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2035     let Inst{31} = 0;
2036     let Inst{22} = 0;
2037     // imms<5> and immr<5> must be zero, else ReservedValue().
2038     let Inst{21} = 0;
2039     let Inst{15} = 0;
2040   }
2041   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2042     let Inst{31} = 1;
2043     let Inst{22} = 1;
2044   }
2045 }
2046
2047 //---
2048 // Logical
2049 //---
2050
2051 // Logical (immediate)
2052 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2053                      RegisterClass sregtype, Operand imm_type, string asm,
2054                      list<dag> pattern>
2055     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2056          asm, "\t$Rd, $Rn, $imm", "", pattern>,
2057       Sched<[WriteI, ReadI]> {
2058   bits<5>  Rd;
2059   bits<5>  Rn;
2060   bits<13> imm;
2061   let Inst{30-29} = opc;
2062   let Inst{28-23} = 0b100100;
2063   let Inst{22}    = imm{12};
2064   let Inst{21-16} = imm{11-6};
2065   let Inst{15-10} = imm{5-0};
2066   let Inst{9-5}   = Rn;
2067   let Inst{4-0}   = Rd;
2068
2069   let DecoderMethod = "DecodeLogicalImmInstruction";
2070 }
2071
2072 // Logical (shifted register)
2073 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2074                       logical_shifted_reg shifted_regtype, string asm,
2075                       list<dag> pattern>
2076     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2077         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2078       Sched<[WriteISReg, ReadI, ReadISReg]> {
2079   // The operands are in order to match the 'addr' MI operands, so we
2080   // don't need an encoder method and by-name matching. Just use the default
2081   // in-order handling. Since we're using by-order, make sure the names
2082   // do not match.
2083   bits<5> dst;
2084   bits<5> src1;
2085   bits<5> src2;
2086   bits<8> shift;
2087   let Inst{30-29} = opc;
2088   let Inst{28-24} = 0b01010;
2089   let Inst{23-22} = shift{7-6};
2090   let Inst{21}    = N;
2091   let Inst{20-16} = src2;
2092   let Inst{15-10} = shift{5-0};
2093   let Inst{9-5}   = src1;
2094   let Inst{4-0}   = dst;
2095
2096   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2097 }
2098
2099 // Aliases for register+register logical instructions.
2100 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2101     : InstAlias<asm#"\t$dst, $src1, $src2",
2102                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2103
2104 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2105                       string Alias> {
2106   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2107   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2108                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2109                                                logical_imm32:$imm))]> {
2110     let Inst{31} = 0;
2111     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2112   }
2113   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2114   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2115                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2116                                                logical_imm64:$imm))]> {
2117     let Inst{31} = 1;
2118   }
2119
2120   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2121                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2122                       logical_imm32_not:$imm), 0>;
2123   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2124                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2125                        logical_imm64_not:$imm), 0>;
2126 }
2127
2128 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2129                        string Alias> {
2130   let isCompare = 1, Defs = [NZCV] in {
2131   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2132       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2133     let Inst{31} = 0;
2134     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2135   }
2136   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2137       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2138     let Inst{31} = 1;
2139   }
2140   } // end Defs = [NZCV]
2141
2142   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2143                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2144                       logical_imm32_not:$imm), 0>;
2145   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2146                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2147                        logical_imm64_not:$imm), 0>;
2148 }
2149
2150 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2151     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2152              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2153       Sched<[WriteI, ReadI, ReadI]>;
2154
2155 // Split from LogicalImm as not all instructions have both.
2156 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2157                       SDPatternOperator OpNode> {
2158   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2159   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2160   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2161   }
2162
2163   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2164                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2165                                                  logical_shifted_reg32:$Rm))]> {
2166     let Inst{31} = 0;
2167   }
2168   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2169                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2170                                                  logical_shifted_reg64:$Rm))]> {
2171     let Inst{31} = 1;
2172   }
2173
2174   def : LogicalRegAlias<mnemonic,
2175                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2176   def : LogicalRegAlias<mnemonic,
2177                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2178 }
2179
2180 // Split from LogicalReg to allow setting NZCV Defs
2181 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2182                        SDPatternOperator OpNode = null_frag> {
2183   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2184   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2185   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2186
2187   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2188             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2189     let Inst{31} = 0;
2190   }
2191   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2192             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2193     let Inst{31} = 1;
2194   }
2195   } // Defs = [NZCV]
2196
2197   def : LogicalRegAlias<mnemonic,
2198                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2199   def : LogicalRegAlias<mnemonic,
2200                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2201 }
2202
2203 //---
2204 // Conditionally set flags
2205 //---
2206
2207 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2208 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2209                             string mnemonic, SDNode OpNode>
2210     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2211          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2212          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2213                              (i32 imm:$cond), NZCV))]>,
2214       Sched<[WriteI, ReadI]> {
2215   let Uses = [NZCV];
2216   let Defs = [NZCV];
2217
2218   bits<5> Rn;
2219   bits<5> imm;
2220   bits<4> nzcv;
2221   bits<4> cond;
2222
2223   let Inst{30}    = op;
2224   let Inst{29-21} = 0b111010010;
2225   let Inst{20-16} = imm;
2226   let Inst{15-12} = cond;
2227   let Inst{11-10} = 0b10;
2228   let Inst{9-5}   = Rn;
2229   let Inst{4}     = 0b0;
2230   let Inst{3-0}   = nzcv;
2231 }
2232
2233 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2234 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2235                             SDNode OpNode>
2236     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2237          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2238          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2239                              (i32 imm:$cond), NZCV))]>,
2240       Sched<[WriteI, ReadI, ReadI]> {
2241   let Uses = [NZCV];
2242   let Defs = [NZCV];
2243
2244   bits<5> Rn;
2245   bits<5> Rm;
2246   bits<4> nzcv;
2247   bits<4> cond;
2248
2249   let Inst{30}    = op;
2250   let Inst{29-21} = 0b111010010;
2251   let Inst{20-16} = Rm;
2252   let Inst{15-12} = cond;
2253   let Inst{11-10} = 0b00;
2254   let Inst{9-5}   = Rn;
2255   let Inst{4}     = 0b0;
2256   let Inst{3-0}   = nzcv;
2257 }
2258
2259 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2260   // immediate operand variants
2261   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2262     let Inst{31} = 0;
2263   }
2264   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2265     let Inst{31} = 1;
2266   }
2267   // register operand variants
2268   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2269     let Inst{31} = 0;
2270   }
2271   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2272     let Inst{31} = 1;
2273   }
2274 }
2275
2276 //---
2277 // Conditional select
2278 //---
2279
2280 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2281     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2282          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2283          [(set regtype:$Rd,
2284                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2285       Sched<[WriteI, ReadI, ReadI]> {
2286   let Uses = [NZCV];
2287
2288   bits<5> Rd;
2289   bits<5> Rn;
2290   bits<5> Rm;
2291   bits<4> cond;
2292
2293   let Inst{30}    = op;
2294   let Inst{29-21} = 0b011010100;
2295   let Inst{20-16} = Rm;
2296   let Inst{15-12} = cond;
2297   let Inst{11-10} = op2;
2298   let Inst{9-5}   = Rn;
2299   let Inst{4-0}   = Rd;
2300 }
2301
2302 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2303   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2304     let Inst{31} = 0;
2305   }
2306   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2307     let Inst{31} = 1;
2308   }
2309 }
2310
2311 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2312                        PatFrag frag>
2313     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2314          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2315          [(set regtype:$Rd,
2316                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2317                (i32 imm:$cond), NZCV))]>,
2318       Sched<[WriteI, ReadI, ReadI]> {
2319   let Uses = [NZCV];
2320
2321   bits<5> Rd;
2322   bits<5> Rn;
2323   bits<5> Rm;
2324   bits<4> cond;
2325
2326   let Inst{30}    = op;
2327   let Inst{29-21} = 0b011010100;
2328   let Inst{20-16} = Rm;
2329   let Inst{15-12} = cond;
2330   let Inst{11-10} = op2;
2331   let Inst{9-5}   = Rn;
2332   let Inst{4-0}   = Rd;
2333 }
2334
2335 def inv_cond_XFORM : SDNodeXForm<imm, [{
2336   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2337   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2338                                    MVT::i32);
2339 }]>;
2340
2341 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2342   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2343     let Inst{31} = 0;
2344   }
2345   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2346     let Inst{31} = 1;
2347   }
2348
2349   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2350             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2351                                            (inv_cond_XFORM imm:$cond))>;
2352
2353   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2354             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2355                                            (inv_cond_XFORM imm:$cond))>;
2356 }
2357
2358 //---
2359 // Special Mask Value
2360 //---
2361 def maski8_or_more : Operand<i32>,
2362   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2363 }
2364 def maski16_or_more : Operand<i32>,
2365   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2366 }
2367
2368
2369 //---
2370 // Load/store
2371 //---
2372
2373 // (unsigned immediate)
2374 // Indexed for 8-bit registers. offset is in range [0,4095].
2375 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2376 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2377 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2378 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2379 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2380
2381 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2382   let Name = "UImm12Offset" # Scale;
2383   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2384   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2385   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2386 }
2387
2388 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2389 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2390 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2391 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2392 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2393
2394 class uimm12_scaled<int Scale> : Operand<i64> {
2395   let ParserMatchClass
2396    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2397   let EncoderMethod
2398    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2399   let PrintMethod = "printUImm12Offset<" # Scale # ">";
2400 }
2401
2402 def uimm12s1 : uimm12_scaled<1>;
2403 def uimm12s2 : uimm12_scaled<2>;
2404 def uimm12s4 : uimm12_scaled<4>;
2405 def uimm12s8 : uimm12_scaled<8>;
2406 def uimm12s16 : uimm12_scaled<16>;
2407
2408 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2409                       string asm, list<dag> pattern>
2410     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2411   bits<5> Rt;
2412
2413   bits<5> Rn;
2414   bits<12> offset;
2415
2416   let Inst{31-30} = sz;
2417   let Inst{29-27} = 0b111;
2418   let Inst{26}    = V;
2419   let Inst{25-24} = 0b01;
2420   let Inst{23-22} = opc;
2421   let Inst{21-10} = offset;
2422   let Inst{9-5}   = Rn;
2423   let Inst{4-0}   = Rt;
2424
2425   let DecoderMethod = "DecodeUnsignedLdStInstruction";
2426 }
2427
2428 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2429                   Operand indextype, string asm, list<dag> pattern> {
2430   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2431   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2432                            (ins GPR64sp:$Rn, indextype:$offset),
2433                            asm, pattern>,
2434            Sched<[WriteLD]>;
2435
2436   def : InstAlias<asm # "\t$Rt, [$Rn]",
2437                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2438 }
2439
2440 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2441              Operand indextype, string asm, list<dag> pattern> {
2442   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2443   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2444                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2445                            asm, pattern>,
2446            Sched<[WriteST]>;
2447
2448   def : InstAlias<asm # "\t$Rt, [$Rn]",
2449                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2450 }
2451
2452 def PrefetchOperand : AsmOperandClass {
2453   let Name = "Prefetch";
2454   let ParserMethod = "tryParsePrefetch";
2455 }
2456 def prfop : Operand<i32> {
2457   let PrintMethod = "printPrefetchOp";
2458   let ParserMatchClass = PrefetchOperand;
2459 }
2460
2461 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2462 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2463     : BaseLoadStoreUI<sz, V, opc,
2464                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2465                       asm, pat>,
2466       Sched<[WriteLD]>;
2467
2468 //---
2469 // Load literal
2470 //---
2471
2472 // Load literal address: 19-bit immediate. The low two bits of the target
2473 // offset are implied zero and so are not part of the immediate.
2474 def am_ldrlit : Operand<iPTR> {
2475   let EncoderMethod = "getLoadLiteralOpValue";
2476   let DecoderMethod = "DecodePCRelLabel19";
2477   let PrintMethod = "printAlignedLabel";
2478   let ParserMatchClass = PCRelLabel19Operand;
2479 }
2480
2481 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2482 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2483     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2484         asm, "\t$Rt, $label", "", []>,
2485       Sched<[WriteLD]> {
2486   bits<5> Rt;
2487   bits<19> label;
2488   let Inst{31-30} = opc;
2489   let Inst{29-27} = 0b011;
2490   let Inst{26}    = V;
2491   let Inst{25-24} = 0b00;
2492   let Inst{23-5}  = label;
2493   let Inst{4-0}   = Rt;
2494 }
2495
2496 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2497 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2498     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2499         asm, "\t$Rt, $label", "", pat>,
2500       Sched<[WriteLD]> {
2501   bits<5> Rt;
2502   bits<19> label;
2503   let Inst{31-30} = opc;
2504   let Inst{29-27} = 0b011;
2505   let Inst{26}    = V;
2506   let Inst{25-24} = 0b00;
2507   let Inst{23-5}  = label;
2508   let Inst{4-0}   = Rt;
2509 }
2510
2511 //---
2512 // Load/store register offset
2513 //---
2514
2515 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2516 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2517 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2518 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2519 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2520
2521 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2522 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2523 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2524 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2525 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2526
2527 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2528   let Name = "Mem" # Reg # "Extend" # Width;
2529   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2530   let RenderMethod = "addMemExtendOperands";
2531   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2532 }
2533
2534 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2535   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2536   // the trivial shift.
2537   let RenderMethod = "addMemExtend8Operands";
2538 }
2539 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2540 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2541 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2542 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2543
2544 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2545   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2546   // the trivial shift.
2547   let RenderMethod = "addMemExtend8Operands";
2548 }
2549 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2550 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2551 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2552 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2553
2554 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2555         : Operand<i32> {
2556   let ParserMatchClass = ParserClass;
2557   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2558   let DecoderMethod = "DecodeMemExtend";
2559   let EncoderMethod = "getMemExtendOpValue";
2560   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2561 }
2562
2563 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
2564 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
2565 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
2566 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
2567 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2568
2569 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
2570 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
2571 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
2572 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
2573 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2574
2575 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2576                   Operand wextend, Operand xextend>  {
2577   // CodeGen-level pattern covering the entire addressing mode.
2578   ComplexPattern Wpat = windex;
2579   ComplexPattern Xpat = xindex;
2580
2581   // Asm-level Operand covering the valid "uxtw #3" style syntax.
2582   Operand Wext = wextend;
2583   Operand Xext = xextend;
2584 }
2585
2586 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2587 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2588 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2589 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2590 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2591                        ro_Xextend128>;
2592
2593 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2594                       string asm, dag ins, dag outs, list<dag> pat>
2595     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2596   bits<5> Rt;
2597   bits<5> Rn;
2598   bits<5> Rm;
2599   bits<2> extend;
2600   let Inst{31-30} = sz;
2601   let Inst{29-27} = 0b111;
2602   let Inst{26}    = V;
2603   let Inst{25-24} = 0b00;
2604   let Inst{23-22} = opc;
2605   let Inst{21}    = 1;
2606   let Inst{20-16} = Rm;
2607   let Inst{15}    = extend{1}; // sign extend Rm?
2608   let Inst{14}    = 1;
2609   let Inst{12}    = extend{0}; // do shift?
2610   let Inst{11-10} = 0b10;
2611   let Inst{9-5}   = Rn;
2612   let Inst{4-0}   = Rt;
2613 }
2614
2615 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2616   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
2617               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2618
2619 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2620                    string asm, ValueType Ty, SDPatternOperator loadop> {
2621   let AddedComplexity = 10 in
2622   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2623                  (outs regtype:$Rt),
2624                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2625                  [(set (Ty regtype:$Rt),
2626                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2627                                              ro_Wextend8:$extend)))]>,
2628            Sched<[WriteLDIdx, ReadAdrBase]> {
2629     let Inst{13} = 0b0;
2630   }
2631
2632   let AddedComplexity = 10 in
2633   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2634                  (outs regtype:$Rt),
2635                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2636                  [(set (Ty regtype:$Rt),
2637                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2638                                              ro_Xextend8:$extend)))]>,
2639            Sched<[WriteLDIdx, ReadAdrBase]> {
2640     let Inst{13} = 0b1;
2641   }
2642
2643   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2644 }
2645
2646 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2647                     string asm, ValueType Ty, SDPatternOperator storeop> {
2648   let AddedComplexity = 10 in
2649   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2650                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2651                  [(storeop (Ty regtype:$Rt),
2652                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2653                                          ro_Wextend8:$extend))]>,
2654             Sched<[WriteSTIdx, ReadAdrBase]> {
2655     let Inst{13} = 0b0;
2656   }
2657
2658   let AddedComplexity = 10 in
2659   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2660                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2661                  [(storeop (Ty regtype:$Rt),
2662                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2663                                          ro_Xextend8:$extend))]>,
2664             Sched<[WriteSTIdx, ReadAdrBase]> {
2665     let Inst{13} = 0b1;
2666   }
2667
2668   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2669 }
2670
2671 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2672                       string asm, dag ins, dag outs, list<dag> pat>
2673     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2674   bits<5> Rt;
2675   bits<5> Rn;
2676   bits<5> Rm;
2677   bits<2> extend;
2678   let Inst{31-30} = sz;
2679   let Inst{29-27} = 0b111;
2680   let Inst{26}    = V;
2681   let Inst{25-24} = 0b00;
2682   let Inst{23-22} = opc;
2683   let Inst{21}    = 1;
2684   let Inst{20-16} = Rm;
2685   let Inst{15}    = extend{1}; // sign extend Rm?
2686   let Inst{14}    = 1;
2687   let Inst{12}    = extend{0}; // do shift?
2688   let Inst{11-10} = 0b10;
2689   let Inst{9-5}   = Rn;
2690   let Inst{4-0}   = Rt;
2691 }
2692
2693 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2694                     string asm, ValueType Ty, SDPatternOperator loadop> {
2695   let AddedComplexity = 10 in
2696   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2697                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2698                  [(set (Ty regtype:$Rt),
2699                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2700                                               ro_Wextend16:$extend)))]>,
2701             Sched<[WriteLDIdx, ReadAdrBase]> {
2702     let Inst{13} = 0b0;
2703   }
2704
2705   let AddedComplexity = 10 in
2706   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2707                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2708                  [(set (Ty regtype:$Rt),
2709                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2710                                              ro_Xextend16:$extend)))]>,
2711             Sched<[WriteLDIdx, ReadAdrBase]> {
2712     let Inst{13} = 0b1;
2713   }
2714
2715   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2716 }
2717
2718 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2719                      string asm, ValueType Ty, SDPatternOperator storeop> {
2720   let AddedComplexity = 10 in
2721   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2722                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2723                 [(storeop (Ty regtype:$Rt),
2724                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2725                                          ro_Wextend16:$extend))]>,
2726            Sched<[WriteSTIdx, ReadAdrBase]> {
2727     let Inst{13} = 0b0;
2728   }
2729
2730   let AddedComplexity = 10 in
2731   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2732                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2733                 [(storeop (Ty regtype:$Rt),
2734                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2735                                          ro_Xextend16:$extend))]>,
2736            Sched<[WriteSTIdx, ReadAdrBase]> {
2737     let Inst{13} = 0b1;
2738   }
2739
2740   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2741 }
2742
2743 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2744                       string asm, dag ins, dag outs, list<dag> pat>
2745     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2746   bits<5> Rt;
2747   bits<5> Rn;
2748   bits<5> Rm;
2749   bits<2> extend;
2750   let Inst{31-30} = sz;
2751   let Inst{29-27} = 0b111;
2752   let Inst{26}    = V;
2753   let Inst{25-24} = 0b00;
2754   let Inst{23-22} = opc;
2755   let Inst{21}    = 1;
2756   let Inst{20-16} = Rm;
2757   let Inst{15}    = extend{1}; // sign extend Rm?
2758   let Inst{14}    = 1;
2759   let Inst{12}    = extend{0}; // do shift?
2760   let Inst{11-10} = 0b10;
2761   let Inst{9-5}   = Rn;
2762   let Inst{4-0}   = Rt;
2763 }
2764
2765 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2766                     string asm, ValueType Ty, SDPatternOperator loadop> {
2767   let AddedComplexity = 10 in
2768   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2769                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2770                  [(set (Ty regtype:$Rt),
2771                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2772                                               ro_Wextend32:$extend)))]>,
2773            Sched<[WriteLDIdx, ReadAdrBase]> {
2774     let Inst{13} = 0b0;
2775   }
2776
2777   let AddedComplexity = 10 in
2778   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2779                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2780                  [(set (Ty regtype:$Rt),
2781                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2782                                               ro_Xextend32:$extend)))]>,
2783            Sched<[WriteLDIdx, ReadAdrBase]> {
2784     let Inst{13} = 0b1;
2785   }
2786
2787   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2788 }
2789
2790 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2791                      string asm, ValueType Ty, SDPatternOperator storeop> {
2792   let AddedComplexity = 10 in
2793   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2794                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2795                 [(storeop (Ty regtype:$Rt),
2796                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2797                                          ro_Wextend32:$extend))]>,
2798             Sched<[WriteSTIdx, ReadAdrBase]> {
2799     let Inst{13} = 0b0;
2800   }
2801
2802   let AddedComplexity = 10 in
2803   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2804                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2805                 [(storeop (Ty regtype:$Rt),
2806                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2807                                         ro_Xextend32:$extend))]>,
2808             Sched<[WriteSTIdx, ReadAdrBase]> {
2809     let Inst{13} = 0b1;
2810   }
2811
2812   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2813 }
2814
2815 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2816                       string asm, dag ins, dag outs, list<dag> pat>
2817     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2818   bits<5> Rt;
2819   bits<5> Rn;
2820   bits<5> Rm;
2821   bits<2> extend;
2822   let Inst{31-30} = sz;
2823   let Inst{29-27} = 0b111;
2824   let Inst{26}    = V;
2825   let Inst{25-24} = 0b00;
2826   let Inst{23-22} = opc;
2827   let Inst{21}    = 1;
2828   let Inst{20-16} = Rm;
2829   let Inst{15}    = extend{1}; // sign extend Rm?
2830   let Inst{14}    = 1;
2831   let Inst{12}    = extend{0}; // do shift?
2832   let Inst{11-10} = 0b10;
2833   let Inst{9-5}   = Rn;
2834   let Inst{4-0}   = Rt;
2835 }
2836
2837 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2838                     string asm, ValueType Ty, SDPatternOperator loadop> {
2839   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2840   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2841                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2842                 [(set (Ty regtype:$Rt),
2843                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2844                                              ro_Wextend64:$extend)))]>,
2845            Sched<[WriteLDIdx, ReadAdrBase]> {
2846     let Inst{13} = 0b0;
2847   }
2848
2849   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2850   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2851                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2852                  [(set (Ty regtype:$Rt),
2853                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2854                                               ro_Xextend64:$extend)))]>,
2855            Sched<[WriteLDIdx, ReadAdrBase]> {
2856     let Inst{13} = 0b1;
2857   }
2858
2859   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2860 }
2861
2862 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2863                      string asm, ValueType Ty, SDPatternOperator storeop> {
2864   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2865   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2866                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2867                 [(storeop (Ty regtype:$Rt),
2868                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2869                                          ro_Wextend64:$extend))]>,
2870             Sched<[WriteSTIdx, ReadAdrBase]> {
2871     let Inst{13} = 0b0;
2872   }
2873
2874   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2875   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2876                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2877                 [(storeop (Ty regtype:$Rt),
2878                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2879                                          ro_Xextend64:$extend))]>,
2880             Sched<[WriteSTIdx, ReadAdrBase]> {
2881     let Inst{13} = 0b1;
2882   }
2883
2884   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2885 }
2886
2887 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2888                       string asm, dag ins, dag outs, list<dag> pat>
2889     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2890   bits<5> Rt;
2891   bits<5> Rn;
2892   bits<5> Rm;
2893   bits<2> extend;
2894   let Inst{31-30} = sz;
2895   let Inst{29-27} = 0b111;
2896   let Inst{26}    = V;
2897   let Inst{25-24} = 0b00;
2898   let Inst{23-22} = opc;
2899   let Inst{21}    = 1;
2900   let Inst{20-16} = Rm;
2901   let Inst{15}    = extend{1}; // sign extend Rm?
2902   let Inst{14}    = 1;
2903   let Inst{12}    = extend{0}; // do shift?
2904   let Inst{11-10} = 0b10;
2905   let Inst{9-5}   = Rn;
2906   let Inst{4-0}   = Rt;
2907 }
2908
2909 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2910                      string asm, ValueType Ty, SDPatternOperator loadop> {
2911   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2912   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2913                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2914                  [(set (Ty regtype:$Rt),
2915                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2916                                                ro_Wextend128:$extend)))]>,
2917             Sched<[WriteLDIdx, ReadAdrBase]> {
2918     let Inst{13} = 0b0;
2919   }
2920
2921   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2922   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2923                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2924                  [(set (Ty regtype:$Rt),
2925                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2926                                                ro_Xextend128:$extend)))]>,
2927             Sched<[WriteLDIdx, ReadAdrBase]> {
2928     let Inst{13} = 0b1;
2929   }
2930
2931   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2932 }
2933
2934 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2935                       string asm, ValueType Ty, SDPatternOperator storeop> {
2936   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2937   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2938                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2939                 [(storeop (Ty regtype:$Rt),
2940                           (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2941                                           ro_Wextend128:$extend))]>,
2942             Sched<[WriteSTIdx, ReadAdrBase]> {
2943     let Inst{13} = 0b0;
2944   }
2945
2946   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2947   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2948                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2949                 [(storeop (Ty regtype:$Rt),
2950                           (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2951                                           ro_Xextend128:$extend))]>,
2952             Sched<[WriteSTIdx, ReadAdrBase]> {
2953     let Inst{13} = 0b1;
2954   }
2955
2956   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2957 }
2958
2959 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2960 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2961                      string asm, list<dag> pat>
2962     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2963       Sched<[WriteLD]> {
2964   bits<5> Rt;
2965   bits<5> Rn;
2966   bits<5> Rm;
2967   bits<2> extend;
2968   let Inst{31-30} = sz;
2969   let Inst{29-27} = 0b111;
2970   let Inst{26}    = V;
2971   let Inst{25-24} = 0b00;
2972   let Inst{23-22} = opc;
2973   let Inst{21}    = 1;
2974   let Inst{20-16} = Rm;
2975   let Inst{15}    = extend{1}; // sign extend Rm?
2976   let Inst{14}    = 1;
2977   let Inst{12}    = extend{0}; // do shift?
2978   let Inst{11-10} = 0b10;
2979   let Inst{9-5}   = Rn;
2980   let Inst{4-0}   = Rt;
2981 }
2982
2983 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2984   def roW : BasePrefetchRO<sz, V, opc, (outs),
2985                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2986                 asm, [(AArch64Prefetch imm:$Rt,
2987                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2988                                                     ro_Wextend64:$extend))]> {
2989     let Inst{13} = 0b0;
2990   }
2991
2992   def roX : BasePrefetchRO<sz, V, opc, (outs),
2993                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2994                 asm,  [(AArch64Prefetch imm:$Rt,
2995                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2996                                                      ro_Xextend64:$extend))]> {
2997     let Inst{13} = 0b1;
2998   }
2999
3000   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3001                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3002                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3003 }
3004
3005 //---
3006 // Load/store unscaled immediate
3007 //---
3008
3009 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3010 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3011 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3012 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3013 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3014
3015 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3016                            string asm, list<dag> pattern>
3017     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3018   bits<5> Rt;
3019   bits<5> Rn;
3020   bits<9> offset;
3021   let Inst{31-30} = sz;
3022   let Inst{29-27} = 0b111;
3023   let Inst{26}    = V;
3024   let Inst{25-24} = 0b00;
3025   let Inst{23-22} = opc;
3026   let Inst{21}    = 0;
3027   let Inst{20-12} = offset;
3028   let Inst{11-10} = 0b00;
3029   let Inst{9-5}   = Rn;
3030   let Inst{4-0}   = Rt;
3031
3032   let DecoderMethod = "DecodeSignedLdStInstruction";
3033 }
3034
3035 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3036                    string asm, list<dag> pattern> {
3037   let AddedComplexity = 1 in // try this before LoadUI
3038   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3039                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3040           Sched<[WriteLD]>;
3041
3042   def : InstAlias<asm # "\t$Rt, [$Rn]",
3043                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3044 }
3045
3046 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3047                          string asm, list<dag> pattern> {
3048   let AddedComplexity = 1 in // try this before StoreUI
3049   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3050                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3051                                asm, pattern>,
3052           Sched<[WriteST]>;
3053
3054   def : InstAlias<asm # "\t$Rt, [$Rn]",
3055                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3056 }
3057
3058 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3059                             list<dag> pat> {
3060   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3061   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3062                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3063                                asm, pat>,
3064           Sched<[WriteLD]>;
3065
3066   def : InstAlias<asm # "\t$Rt, [$Rn]",
3067                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3068 }
3069
3070 //---
3071 // Load/store unscaled immediate, unprivileged
3072 //---
3073
3074 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3075                                 dag oops, dag iops, string asm>
3076     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3077   bits<5> Rt;
3078   bits<5> Rn;
3079   bits<9> offset;
3080   let Inst{31-30} = sz;
3081   let Inst{29-27} = 0b111;
3082   let Inst{26}    = V;
3083   let Inst{25-24} = 0b00;
3084   let Inst{23-22} = opc;
3085   let Inst{21}    = 0;
3086   let Inst{20-12} = offset;
3087   let Inst{11-10} = 0b10;
3088   let Inst{9-5}   = Rn;
3089   let Inst{4-0}   = Rt;
3090
3091   let DecoderMethod = "DecodeSignedLdStInstruction";
3092 }
3093
3094 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3095                             RegisterClass regtype, string asm> {
3096   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3097   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3098                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
3099           Sched<[WriteLD]>;
3100
3101   def : InstAlias<asm # "\t$Rt, [$Rn]",
3102                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3103 }
3104
3105 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3106                              RegisterClass regtype, string asm> {
3107   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3108   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3109                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3110                                  asm>,
3111           Sched<[WriteST]>;
3112
3113   def : InstAlias<asm # "\t$Rt, [$Rn]",
3114                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3115 }
3116
3117 //---
3118 // Load/store pre-indexed
3119 //---
3120
3121 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3122                           string asm, string cstr, list<dag> pat>
3123     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3124   bits<5> Rt;
3125   bits<5> Rn;
3126   bits<9> offset;
3127   let Inst{31-30} = sz;
3128   let Inst{29-27} = 0b111;
3129   let Inst{26}    = V;
3130   let Inst{25-24} = 0;
3131   let Inst{23-22} = opc;
3132   let Inst{21}    = 0;
3133   let Inst{20-12} = offset;
3134   let Inst{11-10} = 0b11;
3135   let Inst{9-5}   = Rn;
3136   let Inst{4-0}   = Rt;
3137
3138   let DecoderMethod = "DecodeSignedLdStInstruction";
3139 }
3140
3141 let hasSideEffects = 0 in {
3142 let mayStore = 0, mayLoad = 1 in
3143 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3144              string asm>
3145     : BaseLoadStorePreIdx<sz, V, opc,
3146                      (outs GPR64sp:$wback, regtype:$Rt),
3147                      (ins GPR64sp:$Rn, simm9:$offset), asm,
3148                      "$Rn = $wback,@earlyclobber $wback", []>,
3149       Sched<[WriteLD, WriteAdr]>;
3150
3151 let mayStore = 1, mayLoad = 0 in
3152 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3153                   string asm, SDPatternOperator storeop, ValueType Ty>
3154     : BaseLoadStorePreIdx<sz, V, opc,
3155                       (outs GPR64sp:$wback),
3156                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3157                       asm, "$Rn = $wback,@earlyclobber $wback",
3158       [(set GPR64sp:$wback,
3159             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3160       Sched<[WriteAdr, WriteST]>;
3161 } // hasSideEffects = 0
3162
3163 //---
3164 // Load/store post-indexed
3165 //---
3166
3167 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3168                           string asm, string cstr, list<dag> pat>
3169     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3170   bits<5> Rt;
3171   bits<5> Rn;
3172   bits<9> offset;
3173   let Inst{31-30} = sz;
3174   let Inst{29-27} = 0b111;
3175   let Inst{26}    = V;
3176   let Inst{25-24} = 0b00;
3177   let Inst{23-22} = opc;
3178   let Inst{21}    = 0b0;
3179   let Inst{20-12} = offset;
3180   let Inst{11-10} = 0b01;
3181   let Inst{9-5}   = Rn;
3182   let Inst{4-0}   = Rt;
3183
3184   let DecoderMethod = "DecodeSignedLdStInstruction";
3185 }
3186
3187 let hasSideEffects = 0 in {
3188 let mayStore = 0, mayLoad = 1 in
3189 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3190              string asm>
3191     : BaseLoadStorePostIdx<sz, V, opc,
3192                       (outs GPR64sp:$wback, regtype:$Rt),
3193                       (ins GPR64sp:$Rn, simm9:$offset),
3194                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
3195       Sched<[WriteLD, WriteI]>;
3196
3197 let mayStore = 1, mayLoad = 0 in
3198 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3199                    string asm, SDPatternOperator storeop, ValueType Ty>
3200     : BaseLoadStorePostIdx<sz, V, opc,
3201                       (outs GPR64sp:$wback),
3202                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3203                        asm, "$Rn = $wback,@earlyclobber $wback",
3204       [(set GPR64sp:$wback,
3205             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3206     Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3207 } // hasSideEffects = 0
3208
3209
3210 //---
3211 // Load/store pair
3212 //---
3213
3214 // (indexed, offset)
3215
3216 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3217                               string asm>
3218     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3219   bits<5> Rt;
3220   bits<5> Rt2;
3221   bits<5> Rn;
3222   bits<7> offset;
3223   let Inst{31-30} = opc;
3224   let Inst{29-27} = 0b101;
3225   let Inst{26}    = V;
3226   let Inst{25-23} = 0b010;
3227   let Inst{22}    = L;
3228   let Inst{21-15} = offset;
3229   let Inst{14-10} = Rt2;
3230   let Inst{9-5}   = Rn;
3231   let Inst{4-0}   = Rt;
3232
3233   let DecoderMethod = "DecodePairLdStInstruction";
3234 }
3235
3236 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3237                           Operand indextype, string asm> {
3238   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3239   def i : BaseLoadStorePairOffset<opc, V, 1,
3240                                   (outs regtype:$Rt, regtype:$Rt2),
3241                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
3242           Sched<[WriteLD, WriteLDHi]>;
3243
3244   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3245                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3246                                                   GPR64sp:$Rn, 0)>;
3247 }
3248
3249
3250 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3251                            Operand indextype, string asm> {
3252   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3253   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3254                                   (ins regtype:$Rt, regtype:$Rt2,
3255                                        GPR64sp:$Rn, indextype:$offset),
3256                                   asm>,
3257           Sched<[WriteSTP]>;
3258
3259   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3260                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3261                                                   GPR64sp:$Rn, 0)>;
3262 }
3263
3264 // (pre-indexed)
3265 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3266                               string asm>
3267     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3268   bits<5> Rt;
3269   bits<5> Rt2;
3270   bits<5> Rn;
3271   bits<7> offset;
3272   let Inst{31-30} = opc;
3273   let Inst{29-27} = 0b101;
3274   let Inst{26}    = V;
3275   let Inst{25-23} = 0b011;
3276   let Inst{22}    = L;
3277   let Inst{21-15} = offset;
3278   let Inst{14-10} = Rt2;
3279   let Inst{9-5}   = Rn;
3280   let Inst{4-0}   = Rt;
3281
3282   let DecoderMethod = "DecodePairLdStInstruction";
3283 }
3284
3285 let hasSideEffects = 0 in {
3286 let mayStore = 0, mayLoad = 1 in
3287 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3288                      Operand indextype, string asm>
3289     : BaseLoadStorePairPreIdx<opc, V, 1,
3290                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3291                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
3292       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3293
3294 let mayStore = 1, mayLoad = 0 in
3295 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3296                       Operand indextype, string asm>
3297     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3298                              (ins regtype:$Rt, regtype:$Rt2,
3299                                   GPR64sp:$Rn, indextype:$offset),
3300                              asm>,
3301       Sched<[WriteAdr, WriteSTP]>;
3302 } // hasSideEffects = 0
3303
3304 // (post-indexed)
3305
3306 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3307                               string asm>
3308     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3309   bits<5> Rt;
3310   bits<5> Rt2;
3311   bits<5> Rn;
3312   bits<7> offset;
3313   let Inst{31-30} = opc;
3314   let Inst{29-27} = 0b101;
3315   let Inst{26}    = V;
3316   let Inst{25-23} = 0b001;
3317   let Inst{22}    = L;
3318   let Inst{21-15} = offset;
3319   let Inst{14-10} = Rt2;
3320   let Inst{9-5}   = Rn;
3321   let Inst{4-0}   = Rt;
3322
3323   let DecoderMethod = "DecodePairLdStInstruction";
3324 }
3325
3326 let hasSideEffects = 0 in {
3327 let mayStore = 0, mayLoad = 1 in
3328 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3329                       Operand idxtype, string asm>
3330     : BaseLoadStorePairPostIdx<opc, V, 1,
3331                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3332                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3333       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3334
3335 let mayStore = 1, mayLoad = 0 in
3336 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3337                        Operand idxtype, string asm>
3338     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3339                              (ins regtype:$Rt, regtype:$Rt2,
3340                                   GPR64sp:$Rn, idxtype:$offset),
3341                              asm>,
3342       Sched<[WriteAdr, WriteSTP]>;
3343 } // hasSideEffects = 0
3344
3345 //  (no-allocate)
3346
3347 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3348                               string asm>
3349     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3350   bits<5> Rt;
3351   bits<5> Rt2;
3352   bits<5> Rn;
3353   bits<7> offset;
3354   let Inst{31-30} = opc;
3355   let Inst{29-27} = 0b101;
3356   let Inst{26}    = V;
3357   let Inst{25-23} = 0b000;
3358   let Inst{22}    = L;
3359   let Inst{21-15} = offset;
3360   let Inst{14-10} = Rt2;
3361   let Inst{9-5}   = Rn;
3362   let Inst{4-0}   = Rt;
3363
3364   let DecoderMethod = "DecodePairLdStInstruction";
3365 }
3366
3367 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3368                            Operand indextype, string asm> {
3369   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3370   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3371                                    (outs regtype:$Rt, regtype:$Rt2),
3372                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
3373           Sched<[WriteLD, WriteLDHi]>;
3374
3375
3376   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3377                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3378                                                   GPR64sp:$Rn, 0)>;
3379 }
3380
3381 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3382                       Operand indextype, string asm> {
3383   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3384   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3385                                    (ins regtype:$Rt, regtype:$Rt2,
3386                                         GPR64sp:$Rn, indextype:$offset),
3387                                    asm>,
3388           Sched<[WriteSTP]>;
3389
3390   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3391                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3392                                                   GPR64sp:$Rn, 0)>;
3393 }
3394
3395 //---
3396 // Load/store exclusive
3397 //---
3398
3399 // True exclusive operations write to and/or read from the system's exclusive
3400 // monitors, which as far as a compiler is concerned can be modelled as a
3401 // random shared memory address. Hence LoadExclusive mayStore.
3402 //
3403 // Since these instructions have the undefined register bits set to 1 in
3404 // their canonical form, we need a post encoder method to set those bits
3405 // to 1 when encoding these instructions. We do this using the
3406 // fixLoadStoreExclusive function. This function has template parameters:
3407 //
3408 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3409 //
3410 // hasRs indicates that the instruction uses the Rs field, so we won't set
3411 // it to 1 (and the same for Rt2). We don't need template parameters for
3412 // the other register fields since Rt and Rn are always used.
3413 //
3414 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3415 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3416                              dag oops, dag iops, string asm, string operands>
3417     : I<oops, iops, asm, operands, "", []> {
3418   let Inst{31-30} = sz;
3419   let Inst{29-24} = 0b001000;
3420   let Inst{23}    = o2;
3421   let Inst{22}    = L;
3422   let Inst{21}    = o1;
3423   let Inst{15}    = o0;
3424
3425   let DecoderMethod = "DecodeExclusiveLdStInstruction";
3426 }
3427
3428 // Neither Rs nor Rt2 operands.
3429 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3430                                dag oops, dag iops, string asm, string operands>
3431     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3432   bits<5> Rt;
3433   bits<5> Rn;
3434   let Inst{20-16} = 0b11111;
3435   let Unpredictable{20-16} = 0b11111;
3436   let Inst{14-10} = 0b11111;
3437   let Unpredictable{14-10} = 0b11111;
3438   let Inst{9-5} = Rn;
3439   let Inst{4-0} = Rt;
3440
3441   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3442 }
3443
3444 // Simple load acquires don't set the exclusive monitor
3445 let mayLoad = 1, mayStore = 0 in
3446 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3447                   RegisterClass regtype, string asm>
3448     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3449                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3450       Sched<[WriteLD]>;
3451
3452 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3453                     RegisterClass regtype, string asm>
3454     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3455                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3456       Sched<[WriteLD]>;
3457
3458 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3459                        RegisterClass regtype, string asm>
3460     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3461                              (outs regtype:$Rt, regtype:$Rt2),
3462                              (ins GPR64sp0:$Rn), asm,
3463                              "\t$Rt, $Rt2, [$Rn]">,
3464       Sched<[WriteLD, WriteLDHi]> {
3465   bits<5> Rt;
3466   bits<5> Rt2;
3467   bits<5> Rn;
3468   let Inst{14-10} = Rt2;
3469   let Inst{9-5} = Rn;
3470   let Inst{4-0} = Rt;
3471
3472   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3473 }
3474
3475 // Simple store release operations do not check the exclusive monitor.
3476 let mayLoad = 0, mayStore = 1 in
3477 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3478                    RegisterClass regtype, string asm>
3479     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3480                                (ins regtype:$Rt, GPR64sp0:$Rn),
3481                                asm, "\t$Rt, [$Rn]">,
3482       Sched<[WriteST]>;
3483
3484 let mayLoad = 1, mayStore = 1 in
3485 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3486                      RegisterClass regtype, string asm>
3487     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3488                              (ins regtype:$Rt, GPR64sp0:$Rn),
3489                              asm, "\t$Ws, $Rt, [$Rn]">,
3490       Sched<[WriteSTX]> {
3491   bits<5> Ws;
3492   bits<5> Rt;
3493   bits<5> Rn;
3494   let Inst{20-16} = Ws;
3495   let Inst{9-5} = Rn;
3496   let Inst{4-0} = Rt;
3497
3498   let Constraints = "@earlyclobber $Ws";
3499   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3500 }
3501
3502 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3503                          RegisterClass regtype, string asm>
3504     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3505                              (outs GPR32:$Ws),
3506                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3507                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3508       Sched<[WriteSTX]> {
3509   bits<5> Ws;
3510   bits<5> Rt;
3511   bits<5> Rt2;
3512   bits<5> Rn;
3513   let Inst{20-16} = Ws;
3514   let Inst{14-10} = Rt2;
3515   let Inst{9-5} = Rn;
3516   let Inst{4-0} = Rt;
3517
3518   let Constraints = "@earlyclobber $Ws";
3519 }
3520
3521 //---
3522 // Exception generation
3523 //---
3524
3525 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3526 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3527     : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3528       Sched<[WriteSys]> {
3529   bits<16> imm;
3530   let Inst{31-24} = 0b11010100;
3531   let Inst{23-21} = op1;
3532   let Inst{20-5}  = imm;
3533   let Inst{4-2}   = 0b000;
3534   let Inst{1-0}   = ll;
3535 }
3536
3537 let Predicates = [HasFPARMv8] in {
3538
3539 //---
3540 // Floating point to integer conversion
3541 //---
3542
3543 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3544                       RegisterClass srcType, RegisterClass dstType,
3545                       string asm, list<dag> pattern>
3546     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3547          asm, "\t$Rd, $Rn", "", pattern>,
3548       Sched<[WriteFCvt]> {
3549   bits<5> Rd;
3550   bits<5> Rn;
3551   let Inst{30-29} = 0b00;
3552   let Inst{28-24} = 0b11110;
3553   let Inst{23-22} = type;
3554   let Inst{21}    = 1;
3555   let Inst{20-19} = rmode;
3556   let Inst{18-16} = opcode;
3557   let Inst{15-10} = 0;
3558   let Inst{9-5}   = Rn;
3559   let Inst{4-0}   = Rd;
3560 }
3561
3562 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3563 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3564                       RegisterClass srcType, RegisterClass dstType,
3565                       Operand immType, string asm, list<dag> pattern>
3566     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3567          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3568       Sched<[WriteFCvt]> {
3569   bits<5> Rd;
3570   bits<5> Rn;
3571   bits<6> scale;
3572   let Inst{30-29} = 0b00;
3573   let Inst{28-24} = 0b11110;
3574   let Inst{23-22} = type;
3575   let Inst{21}    = 0;
3576   let Inst{20-19} = rmode;
3577   let Inst{18-16} = opcode;
3578   let Inst{15-10} = scale;
3579   let Inst{9-5}   = Rn;
3580   let Inst{4-0}   = Rd;
3581 }
3582
3583 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3584            SDPatternOperator OpN> {
3585   // Unscaled half-precision to 32-bit
3586   def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
3587                                      [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
3588     let Inst{31} = 0; // 32-bit GPR flag
3589     let Predicates = [HasFullFP16];
3590   }
3591
3592   // Unscaled half-precision to 64-bit
3593   def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
3594                                      [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
3595     let Inst{31} = 1; // 64-bit GPR flag
3596     let Predicates = [HasFullFP16];
3597   }
3598
3599   // Unscaled single-precision to 32-bit
3600   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3601                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3602     let Inst{31} = 0; // 32-bit GPR flag
3603   }
3604
3605   // Unscaled single-precision to 64-bit
3606   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3607                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3608     let Inst{31} = 1; // 64-bit GPR flag
3609   }
3610
3611   // Unscaled double-precision to 32-bit
3612   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3613                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3614     let Inst{31} = 0; // 32-bit GPR flag
3615   }
3616
3617   // Unscaled double-precision to 64-bit
3618   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3619                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3620     let Inst{31} = 1; // 64-bit GPR flag
3621   }
3622 }
3623
3624 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3625                              SDPatternOperator OpN> {
3626   // Scaled half-precision to 32-bit
3627   def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
3628                               fixedpoint_f16_i32, asm,
3629               [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
3630                                           fixedpoint_f16_i32:$scale)))]> {
3631     let Inst{31} = 0; // 32-bit GPR flag
3632     let scale{5} = 1;
3633     let Predicates = [HasFullFP16];
3634   }
3635
3636   // Scaled half-precision to 64-bit
3637   def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
3638                               fixedpoint_f16_i64, asm,
3639               [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
3640                                           fixedpoint_f16_i64:$scale)))]> {
3641     let Inst{31} = 1; // 64-bit GPR flag
3642     let Predicates = [HasFullFP16];
3643   }
3644
3645   // Scaled single-precision to 32-bit
3646   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3647                               fixedpoint_f32_i32, asm,
3648               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3649                                           fixedpoint_f32_i32:$scale)))]> {
3650     let Inst{31} = 0; // 32-bit GPR flag
3651     let scale{5} = 1;
3652   }
3653
3654   // Scaled single-precision to 64-bit
3655   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3656                               fixedpoint_f32_i64, asm,
3657               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3658                                           fixedpoint_f32_i64:$scale)))]> {
3659     let Inst{31} = 1; // 64-bit GPR flag
3660   }
3661
3662   // Scaled double-precision to 32-bit
3663   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3664                               fixedpoint_f64_i32, asm,
3665               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3666                                           fixedpoint_f64_i32:$scale)))]> {
3667     let Inst{31} = 0; // 32-bit GPR flag
3668     let scale{5} = 1;
3669   }
3670
3671   // Scaled double-precision to 64-bit
3672   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3673                               fixedpoint_f64_i64, asm,
3674               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3675                                           fixedpoint_f64_i64:$scale)))]> {
3676     let Inst{31} = 1; // 64-bit GPR flag
3677   }
3678 }
3679
3680 //---
3681 // Integer to floating point conversion
3682 //---
3683
3684 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3685 class BaseIntegerToFP<bit isUnsigned,
3686                       RegisterClass srcType, RegisterClass dstType,
3687                       Operand immType, string asm, list<dag> pattern>
3688     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3689          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3690       Sched<[WriteFCvt]> {
3691   bits<5> Rd;
3692   bits<5> Rn;
3693   bits<6> scale;
3694   let Inst{30-24} = 0b0011110;
3695   let Inst{21-17} = 0b00001;
3696   let Inst{16}    = isUnsigned;
3697   let Inst{15-10} = scale;
3698   let Inst{9-5}   = Rn;
3699   let Inst{4-0}   = Rd;
3700 }
3701
3702 class BaseIntegerToFPUnscaled<bit isUnsigned,
3703                       RegisterClass srcType, RegisterClass dstType,
3704                       ValueType dvt, string asm, SDNode node>
3705     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3706          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3707       Sched<[WriteFCvt]> {
3708   bits<5> Rd;
3709   bits<5> Rn;
3710   bits<6> scale;
3711   let Inst{30-24} = 0b0011110;
3712   let Inst{21-17} = 0b10001;
3713   let Inst{16}    = isUnsigned;
3714   let Inst{15-10} = 0b000000;
3715   let Inst{9-5}   = Rn;
3716   let Inst{4-0}   = Rd;
3717 }
3718
3719 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3720   // Unscaled
3721   def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
3722     let Inst{31} = 0; // 32-bit GPR flag
3723     let Inst{23-22} = 0b11; // 16-bit FPR flag
3724     let Predicates = [HasFullFP16];
3725   }
3726
3727   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3728     let Inst{31} = 0; // 32-bit GPR flag
3729     let Inst{23-22} = 0b00; // 32-bit FPR flag
3730   }
3731
3732   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3733     let Inst{31} = 0; // 32-bit GPR flag
3734     let Inst{23-22} = 0b01; // 64-bit FPR flag
3735   }
3736
3737   def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
3738     let Inst{31} = 1; // 64-bit GPR flag
3739     let Inst{23-22} = 0b11; // 16-bit FPR flag
3740     let Predicates = [HasFullFP16];
3741   }
3742
3743   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3744     let Inst{31} = 1; // 64-bit GPR flag
3745     let Inst{23-22} = 0b00; // 32-bit FPR flag
3746   }
3747
3748   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3749     let Inst{31} = 1; // 64-bit GPR flag
3750     let Inst{23-22} = 0b01; // 64-bit FPR flag
3751   }
3752
3753   // Scaled
3754   def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
3755                              [(set FPR16:$Rd,
3756                                    (fdiv (node GPR32:$Rn),
3757                                          fixedpoint_f16_i32:$scale))]> {
3758     let Inst{31} = 0; // 32-bit GPR flag
3759     let Inst{23-22} = 0b11; // 16-bit FPR flag
3760     let scale{5} = 1;
3761     let Predicates = [HasFullFP16];
3762   }
3763
3764   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3765                              [(set FPR32:$Rd,
3766                                    (fdiv (node GPR32:$Rn),
3767                                          fixedpoint_f32_i32:$scale))]> {
3768     let Inst{31} = 0; // 32-bit GPR flag
3769     let Inst{23-22} = 0b00; // 32-bit FPR flag
3770     let scale{5} = 1;
3771   }
3772
3773   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3774                              [(set FPR64:$Rd,
3775                                    (fdiv (node GPR32:$Rn),
3776                                          fixedpoint_f64_i32:$scale))]> {
3777     let Inst{31} = 0; // 32-bit GPR flag
3778     let Inst{23-22} = 0b01; // 64-bit FPR flag
3779     let scale{5} = 1;
3780   }
3781
3782   def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
3783                              [(set FPR16:$Rd,
3784                                    (fdiv (node GPR64:$Rn),
3785                                          fixedpoint_f16_i64:$scale))]> {
3786     let Inst{31} = 1; // 64-bit GPR flag
3787     let Inst{23-22} = 0b11; // 16-bit FPR flag
3788     let Predicates = [HasFullFP16];
3789   }
3790
3791   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3792                              [(set FPR32:$Rd,
3793                                    (fdiv (node GPR64:$Rn),
3794                                          fixedpoint_f32_i64:$scale))]> {
3795     let Inst{31} = 1; // 64-bit GPR flag
3796     let Inst{23-22} = 0b00; // 32-bit FPR flag
3797   }
3798
3799   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3800                              [(set FPR64:$Rd,
3801                                    (fdiv (node GPR64:$Rn),
3802                                          fixedpoint_f64_i64:$scale))]> {
3803     let Inst{31} = 1; // 64-bit GPR flag
3804     let Inst{23-22} = 0b01; // 64-bit FPR flag
3805   }
3806 }
3807
3808 //---
3809 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3810 //---
3811
3812 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3813 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3814                       RegisterClass srcType, RegisterClass dstType,
3815                       string asm>
3816     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3817         // We use COPY_TO_REGCLASS for these bitconvert operations.
3818         // copyPhysReg() expands the resultant COPY instructions after
3819         // regalloc is done. This gives greater freedom for the allocator
3820         // and related passes (coalescing, copy propagation, et. al.) to
3821         // be more effective.
3822         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3823       Sched<[WriteFCopy]> {
3824   bits<5> Rd;
3825   bits<5> Rn;
3826   let Inst{30-24} = 0b0011110;
3827   let Inst{21}    = 1;
3828   let Inst{20-19} = rmode;
3829   let Inst{18-16} = opcode;
3830   let Inst{15-10} = 0b000000;
3831   let Inst{9-5}   = Rn;
3832   let Inst{4-0}   = Rd;
3833 }
3834
3835 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3836 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3837                      RegisterClass srcType, RegisterOperand dstType, string asm,
3838                      string kind>
3839     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3840         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3841       Sched<[WriteFCopy]> {
3842   bits<5> Rd;
3843   bits<5> Rn;
3844   let Inst{30-23} = 0b00111101;
3845   let Inst{21}    = 1;
3846   let Inst{20-19} = rmode;
3847   let Inst{18-16} = opcode;
3848   let Inst{15-10} = 0b000000;
3849   let Inst{9-5}   = Rn;
3850   let Inst{4-0}   = Rd;
3851
3852   let DecoderMethod =  "DecodeFMOVLaneInstruction";
3853 }
3854
3855 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3856 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3857                      RegisterOperand srcType, RegisterClass dstType, string asm,
3858                      string kind>
3859     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3860         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3861       Sched<[WriteFCopy]> {
3862   bits<5> Rd;
3863   bits<5> Rn;
3864   let Inst{30-23} = 0b00111101;
3865   let Inst{21}    = 1;
3866   let Inst{20-19} = rmode;
3867   let Inst{18-16} = opcode;
3868   let Inst{15-10} = 0b000000;
3869   let Inst{9-5}   = Rn;
3870   let Inst{4-0}   = Rd;
3871
3872   let DecoderMethod =  "DecodeFMOVLaneInstruction";
3873 }
3874
3875
3876 multiclass UnscaledConversion<string asm> {
3877   def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
3878     let Inst{31} = 0; // 32-bit GPR flag
3879     let Inst{23-22} = 0b11; // 16-bit FPR flag
3880     let Predicates = [HasFullFP16];
3881   }
3882
3883   def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
3884     let Inst{31} = 1; // 64-bit GPR flag
3885     let Inst{23-22} = 0b11; // 16-bit FPR flag
3886     let Predicates = [HasFullFP16];
3887   }
3888
3889   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3890     let Inst{31} = 0; // 32-bit GPR flag
3891     let Inst{23-22} = 0b00; // 32-bit FPR flag
3892   }
3893
3894   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3895     let Inst{31} = 1; // 64-bit GPR flag
3896     let Inst{23-22} = 0b01; // 64-bit FPR flag
3897   }
3898
3899   def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
3900     let Inst{31} = 0; // 32-bit GPR flag
3901     let Inst{23-22} = 0b11; // 16-bit FPR flag
3902     let Predicates = [HasFullFP16];
3903   }
3904
3905   def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
3906     let Inst{31} = 1; // 64-bit GPR flag
3907     let Inst{23-22} = 0b11; // 16-bit FPR flag
3908     let Predicates = [HasFullFP16];
3909   }
3910
3911   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3912     let Inst{31} = 0; // 32-bit GPR flag
3913     let Inst{23-22} = 0b00; // 32-bit FPR flag
3914   }
3915
3916   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3917     let Inst{31} = 1; // 64-bit GPR flag
3918     let Inst{23-22} = 0b01; // 64-bit FPR flag
3919   }
3920
3921   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3922                                              asm, ".d"> {
3923     let Inst{31} = 1;
3924     let Inst{22} = 0;
3925   }
3926
3927   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3928                                                asm, ".d"> {
3929     let Inst{31} = 1;
3930     let Inst{22} = 0;
3931   }
3932 }
3933
3934 //---
3935 // Floating point conversion
3936 //---
3937
3938 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3939                        RegisterClass srcType, string asm, list<dag> pattern>
3940     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3941       Sched<[WriteFCvt]> {
3942   bits<5> Rd;
3943   bits<5> Rn;
3944   let Inst{31-24} = 0b00011110;
3945   let Inst{23-22} = type;
3946   let Inst{21-17} = 0b10001;
3947   let Inst{16-15} = opcode;
3948   let Inst{14-10} = 0b10000;
3949   let Inst{9-5}   = Rn;
3950   let Inst{4-0}   = Rd;
3951 }
3952
3953 multiclass FPConversion<string asm> {
3954   // Double-precision to Half-precision
3955   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3956                              [(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
3957
3958   // Double-precision to Single-precision
3959   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3960                              [(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
3961
3962   // Half-precision to Double-precision
3963   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3964                              [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>;
3965
3966   // Half-precision to Single-precision
3967   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3968                              [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>;
3969
3970   // Single-precision to Double-precision
3971   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3972                              [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
3973
3974   // Single-precision to Half-precision
3975   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3976                              [(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
3977 }
3978
3979 //---
3980 // Single operand floating point data processing
3981 //---
3982
3983 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3984 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3985                               ValueType vt, string asm, SDPatternOperator node>
3986     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3987          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3988       Sched<[WriteF]> {
3989   bits<5> Rd;
3990   bits<5> Rn;
3991   let Inst{31-24} = 0b00011110;
3992   let Inst{21-19} = 0b100;
3993   let Inst{18-15} = opcode;
3994   let Inst{14-10} = 0b10000;
3995   let Inst{9-5}   = Rn;
3996   let Inst{4-0}   = Rd;
3997 }
3998
3999 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4000                                SDPatternOperator node = null_frag> {
4001   def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
4002     let Inst{23-22} = 0b11; // 16-bit size flag
4003     let Predicates = [HasFullFP16];
4004   }
4005
4006   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4007     let Inst{23-22} = 0b00; // 32-bit size flag
4008   }
4009
4010   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4011     let Inst{23-22} = 0b01; // 64-bit size flag
4012   }
4013 }
4014
4015 //---
4016 // Two operand floating point data processing
4017 //---
4018
4019 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4020 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4021                            string asm, list<dag> pat>
4022     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4023          asm, "\t$Rd, $Rn, $Rm", "", pat>,
4024       Sched<[WriteF]> {
4025   bits<5> Rd;
4026   bits<5> Rn;
4027   bits<5> Rm;
4028   let Inst{31-24} = 0b00011110;
4029   let Inst{21}    = 1;
4030   let Inst{20-16} = Rm;
4031   let Inst{15-12} = opcode;
4032   let Inst{11-10} = 0b10;
4033   let Inst{9-5}   = Rn;
4034   let Inst{4-0}   = Rd;
4035 }
4036
4037 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4038                             SDPatternOperator node = null_frag> {
4039   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4040                          [(set (f16 FPR16:$Rd),
4041                                (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4042     let Inst{23-22} = 0b11; // 16-bit size flag
4043     let Predicates = [HasFullFP16];
4044   }
4045
4046   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4047                          [(set (f32 FPR32:$Rd),
4048                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4049     let Inst{23-22} = 0b00; // 32-bit size flag
4050   }
4051
4052   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4053                          [(set (f64 FPR64:$Rd),
4054                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4055     let Inst{23-22} = 0b01; // 64-bit size flag
4056   }
4057 }
4058
4059 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4060   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4061                   [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4062     let Inst{23-22} = 0b11; // 16-bit size flag
4063     let Predicates = [HasFullFP16];
4064   }
4065
4066   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4067                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4068     let Inst{23-22} = 0b00; // 32-bit size flag
4069   }
4070
4071   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4072                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4073     let Inst{23-22} = 0b01; // 64-bit size flag
4074   }
4075 }
4076
4077
4078 //---
4079 // Three operand floating point data processing
4080 //---
4081
4082 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4083                              RegisterClass regtype, string asm, list<dag> pat>
4084     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4085          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4086       Sched<[WriteFMul]> {
4087   bits<5> Rd;
4088   bits<5> Rn;
4089   bits<5> Rm;
4090   bits<5> Ra;
4091   let Inst{31-24} = 0b00011111;
4092   let Inst{21}    = isNegated;
4093   let Inst{20-16} = Rm;
4094   let Inst{15}    = isSub;
4095   let Inst{14-10} = Ra;
4096   let Inst{9-5}   = Rn;
4097   let Inst{4-0}   = Rd;
4098 }
4099
4100 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4101                               SDPatternOperator node> {
4102   def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4103             [(set FPR16:$Rd,
4104                   (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4105     let Inst{23-22} = 0b11; // 16-bit size flag
4106     let Predicates = [HasFullFP16];
4107   }
4108
4109   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4110             [(set FPR32:$Rd,
4111                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4112     let Inst{23-22} = 0b00; // 32-bit size flag
4113   }
4114
4115   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4116             [(set FPR64:$Rd,
4117                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
4118     let Inst{23-22} = 0b01; // 64-bit size flag
4119   }
4120 }
4121
4122 //---
4123 // Floating point data comparisons
4124 //---
4125
4126 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4127 class BaseOneOperandFPComparison<bit signalAllNans,
4128                                  RegisterClass regtype, string asm,
4129                                  list<dag> pat>
4130     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4131       Sched<[WriteFCmp]> {
4132   bits<5> Rn;
4133   let Inst{31-24} = 0b00011110;
4134   let Inst{21}    = 1;
4135
4136   let Inst{15-10} = 0b001000;
4137   let Inst{9-5}   = Rn;
4138   let Inst{4}     = signalAllNans;
4139   let Inst{3-0}   = 0b1000;
4140
4141   // Rm should be 0b00000 canonically, but we need to accept any value.
4142   let PostEncoderMethod = "fixOneOperandFPComparison";
4143 }
4144
4145 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4146 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4147                                 string asm, list<dag> pat>
4148     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4149       Sched<[WriteFCmp]> {
4150   bits<5> Rm;
4151   bits<5> Rn;
4152   let Inst{31-24} = 0b00011110;
4153   let Inst{21}    = 1;
4154   let Inst{20-16} = Rm;
4155   let Inst{15-10} = 0b001000;
4156   let Inst{9-5}   = Rn;
4157   let Inst{4}     = signalAllNans;
4158   let Inst{3-0}   = 0b0000;
4159 }
4160
4161 multiclass FPComparison<bit signalAllNans, string asm,
4162                         SDPatternOperator OpNode = null_frag> {
4163   let Defs = [NZCV] in {
4164   def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4165       [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4166     let Inst{23-22} = 0b11;
4167     let Predicates = [HasFullFP16];
4168   }
4169
4170   def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4171       [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4172     let Inst{23-22} = 0b11;
4173     let Predicates = [HasFullFP16];
4174   }
4175
4176   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4177       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4178     let Inst{23-22} = 0b00;
4179   }
4180
4181   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4182       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4183     let Inst{23-22} = 0b00;
4184   }
4185
4186   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4187       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4188     let Inst{23-22} = 0b01;
4189   }
4190
4191   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4192       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4193     let Inst{23-22} = 0b01;
4194   }
4195   } // Defs = [NZCV]
4196 }
4197
4198 //---
4199 // Floating point conditional comparisons
4200 //---
4201
4202 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4203 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4204                            string mnemonic, list<dag> pat>
4205     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4206          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4207       Sched<[WriteFCmp]> {
4208   let Uses = [NZCV];
4209   let Defs = [NZCV];
4210
4211   bits<5> Rn;
4212   bits<5> Rm;
4213   bits<4> nzcv;
4214   bits<4> cond;
4215
4216   let Inst{31-24} = 0b00011110;
4217   let Inst{21}    = 1;
4218   let Inst{20-16} = Rm;
4219   let Inst{15-12} = cond;
4220   let Inst{11-10} = 0b01;
4221   let Inst{9-5}   = Rn;
4222   let Inst{4}     = signalAllNans;
4223   let Inst{3-0}   = nzcv;
4224 }
4225
4226 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4227                             SDPatternOperator OpNode = null_frag> {
4228   def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
4229     let Inst{23-22} = 0b11;
4230     let Predicates = [HasFullFP16];
4231   }
4232
4233   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4234       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4235                           (i32 imm:$cond), NZCV))]> {
4236     let Inst{23-22} = 0b00;
4237   }
4238
4239   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4240       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4241                           (i32 imm:$cond), NZCV))]> {
4242     let Inst{23-22} = 0b01;
4243   }
4244 }
4245
4246 //---
4247 // Floating point conditional select
4248 //---
4249
4250 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4251     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4252          asm, "\t$Rd, $Rn, $Rm, $cond", "",
4253          [(set regtype:$Rd,
4254                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4255                           (i32 imm:$cond), NZCV))]>,
4256       Sched<[WriteF]> {
4257   bits<5> Rd;
4258   bits<5> Rn;
4259   bits<5> Rm;
4260   bits<4> cond;
4261
4262   let Inst{31-24} = 0b00011110;
4263   let Inst{21}    = 1;
4264   let Inst{20-16} = Rm;
4265   let Inst{15-12} = cond;
4266   let Inst{11-10} = 0b11;
4267   let Inst{9-5}   = Rn;
4268   let Inst{4-0}   = Rd;
4269 }
4270
4271 multiclass FPCondSelect<string asm> {
4272   let Uses = [NZCV] in {
4273   def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4274     let Inst{23-22} = 0b11;
4275     let Predicates = [HasFullFP16];
4276   }
4277
4278   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4279     let Inst{23-22} = 0b00;
4280   }
4281
4282   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4283     let Inst{23-22} = 0b01;
4284   }
4285   } // Uses = [NZCV]
4286 }
4287
4288 //---
4289 // Floating move immediate
4290 //---
4291
4292 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4293   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4294       [(set regtype:$Rd, fpimmtype:$imm)]>,
4295     Sched<[WriteFImm]> {
4296   bits<5> Rd;
4297   bits<8> imm;
4298   let Inst{31-24} = 0b00011110;
4299   let Inst{21}    = 1;
4300   let Inst{20-13} = imm;
4301   let Inst{12-5}  = 0b10000000;
4302   let Inst{4-0}   = Rd;
4303 }
4304
4305 multiclass FPMoveImmediate<string asm> {
4306   def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4307     let Inst{23-22} = 0b11;
4308     let Predicates = [HasFullFP16];
4309   }
4310
4311   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4312     let Inst{23-22} = 0b00;
4313   }
4314
4315   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4316     let Inst{23-22} = 0b01;
4317   }
4318 }
4319 } // end of 'let Predicates = [HasFPARMv8]'
4320
4321 //----------------------------------------------------------------------------
4322 // AdvSIMD
4323 //----------------------------------------------------------------------------
4324
4325 let Predicates = [HasNEON] in {
4326
4327 //----------------------------------------------------------------------------
4328 // AdvSIMD three register vector instructions
4329 //----------------------------------------------------------------------------
4330
4331 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4332 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
4333                         RegisterOperand regtype, string asm, string kind,
4334                         list<dag> pattern>
4335   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4336       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4337       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4338     Sched<[WriteV]> {
4339   bits<5> Rd;
4340   bits<5> Rn;
4341   bits<5> Rm;
4342   let Inst{31}    = 0;
4343   let Inst{30}    = Q;
4344   let Inst{29}    = U;
4345   let Inst{28-24} = 0b01110;
4346   let Inst{23-21} = size;
4347   let Inst{20-16} = Rm;
4348   let Inst{15-11} = opcode;
4349   let Inst{10}    = 1;
4350   let Inst{9-5}   = Rn;
4351   let Inst{4-0}   = Rd;
4352 }
4353
4354 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4355 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
4356                         RegisterOperand regtype, string asm, string kind,
4357                         list<dag> pattern>
4358   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4359       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4360       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4361     Sched<[WriteV]> {
4362   bits<5> Rd;
4363   bits<5> Rn;
4364   bits<5> Rm;
4365   let Inst{31}    = 0;
4366   let Inst{30}    = Q;
4367   let Inst{29}    = U;
4368   let Inst{28-24} = 0b01110;
4369   let Inst{23-21} = size;
4370   let Inst{20-16} = Rm;
4371   let Inst{15-11} = opcode;
4372   let Inst{10}    = 1;
4373   let Inst{9-5}   = Rn;
4374   let Inst{4-0}   = Rd;
4375 }
4376
4377 // All operand sizes distinguished in the encoding.
4378 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4379                                SDPatternOperator OpNode> {
4380   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4381                                       asm, ".8b",
4382          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4383   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4384                                       asm, ".16b",
4385          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4386   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4387                                       asm, ".4h",
4388          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4389   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4390                                       asm, ".8h",
4391          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4392   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4393                                       asm, ".2s",
4394          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4395   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4396                                       asm, ".4s",
4397          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4398   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
4399                                       asm, ".2d",
4400          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4401 }
4402
4403 // As above, but D sized elements unsupported.
4404 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4405                                   SDPatternOperator OpNode> {
4406   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4407                                       asm, ".8b",
4408         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4409   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4410                                       asm, ".16b",
4411         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4412   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4413                                       asm, ".4h",
4414         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4415   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4416                                       asm, ".8h",
4417         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4418   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4419                                       asm, ".2s",
4420         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4421   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4422                                       asm, ".4s",
4423         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4424 }
4425
4426 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4427                                   SDPatternOperator OpNode> {
4428   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
4429                                       asm, ".8b",
4430       [(set (v8i8 V64:$dst),
4431             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4432   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
4433                                       asm, ".16b",
4434       [(set (v16i8 V128:$dst),
4435             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4436   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
4437                                       asm, ".4h",
4438       [(set (v4i16 V64:$dst),
4439             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4440   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
4441                                       asm, ".8h",
4442       [(set (v8i16 V128:$dst),
4443             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4444   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
4445                                       asm, ".2s",
4446       [(set (v2i32 V64:$dst),
4447             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4448   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
4449                                       asm, ".4s",
4450       [(set (v4i32 V128:$dst),
4451             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4452 }
4453
4454 // As above, but only B sized elements supported.
4455 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4456                                 SDPatternOperator OpNode> {
4457   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4458                                       asm, ".8b",
4459     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4460   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4461                                       asm, ".16b",
4462     [(set (v16i8 V128:$Rd),
4463           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4464 }
4465
4466 // As above, but only floating point elements supported.
4467 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
4468                                  string asm, SDPatternOperator OpNode> {
4469   let Predicates = [HasNEON, HasFullFP16] in {
4470   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4471                                       asm, ".4h",
4472         [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4473   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4474                                       asm, ".8h",
4475         [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4476   } // Predicates = [HasNEON, HasFullFP16]
4477   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4478                                       asm, ".2s",
4479         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4480   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4481                                       asm, ".4s",
4482         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4483   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4484                                       asm, ".2d",
4485         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4486 }
4487
4488 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
4489                                     string asm,
4490                                     SDPatternOperator OpNode> {
4491   let Predicates = [HasNEON, HasFullFP16] in {
4492   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4493                                       asm, ".4h",
4494         [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4495   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4496                                       asm, ".8h",
4497         [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4498   } // Predicates = [HasNEON, HasFullFP16]
4499   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4500                                       asm, ".2s",
4501         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4502   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4503                                       asm, ".4s",
4504         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4505   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4506                                       asm, ".2d",
4507         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4508 }
4509
4510 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
4511                                  string asm, SDPatternOperator OpNode> {
4512   let Predicates = [HasNEON, HasFullFP16] in {
4513   def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
4514                                       asm, ".4h",
4515      [(set (v4f16 V64:$dst),
4516            (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4517   def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
4518                                       asm, ".8h",
4519      [(set (v8f16 V128:$dst),
4520            (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4521   } // Predicates = [HasNEON, HasFullFP16]
4522   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
4523                                       asm, ".2s",
4524      [(set (v2f32 V64:$dst),
4525            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4526   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
4527                                       asm, ".4s",
4528      [(set (v4f32 V128:$dst),
4529            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4530   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
4531                                       asm, ".2d",
4532      [(set (v2f64 V128:$dst),
4533            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4534 }
4535
4536 // As above, but D and B sized elements unsupported.
4537 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4538                                 SDPatternOperator OpNode> {
4539   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4540                                       asm, ".4h",
4541         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4542   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4543                                       asm, ".8h",
4544         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4545   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4546                                       asm, ".2s",
4547         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4548   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4549                                       asm, ".4s",
4550         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4551 }
4552
4553 // Logical three vector ops share opcode bits, and only use B sized elements.
4554 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4555                                   SDPatternOperator OpNode = null_frag> {
4556   def v8i8  : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
4557                                      asm, ".8b",
4558                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4559   def v16i8  : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
4560                                      asm, ".16b",
4561                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4562
4563   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4564           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4565   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4566           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4567   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4568           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4569
4570   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4571       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4572   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4573       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4574   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4575       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4576 }
4577
4578 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4579                                   string asm, SDPatternOperator OpNode> {
4580   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
4581                                      asm, ".8b",
4582              [(set (v8i8 V64:$dst),
4583                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4584   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
4585                                      asm, ".16b",
4586              [(set (v16i8 V128:$dst),
4587                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4588                            (v16i8 V128:$Rm)))]>;
4589
4590   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4591                            (v4i16 V64:$RHS))),
4592           (!cast<Instruction>(NAME#"v8i8")
4593             V64:$LHS, V64:$MHS, V64:$RHS)>;
4594   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4595                            (v2i32 V64:$RHS))),
4596           (!cast<Instruction>(NAME#"v8i8")
4597             V64:$LHS, V64:$MHS, V64:$RHS)>;
4598   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4599                            (v1i64 V64:$RHS))),
4600           (!cast<Instruction>(NAME#"v8i8")
4601             V64:$LHS, V64:$MHS, V64:$RHS)>;
4602
4603   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4604                            (v8i16 V128:$RHS))),
4605       (!cast<Instruction>(NAME#"v16i8")
4606         V128:$LHS, V128:$MHS, V128:$RHS)>;
4607   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4608                            (v4i32 V128:$RHS))),
4609       (!cast<Instruction>(NAME#"v16i8")
4610         V128:$LHS, V128:$MHS, V128:$RHS)>;
4611   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4612                            (v2i64 V128:$RHS))),
4613       (!cast<Instruction>(NAME#"v16i8")
4614         V128:$LHS, V128:$MHS, V128:$RHS)>;
4615 }
4616
4617
4618 //----------------------------------------------------------------------------
4619 // AdvSIMD two register vector instructions.
4620 //----------------------------------------------------------------------------
4621
4622 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4623 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4624                             bits<2> size2, RegisterOperand regtype, string asm,
4625                             string dstkind, string srckind, list<dag> pattern>
4626   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4627       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4628       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4629     Sched<[WriteV]> {
4630   bits<5> Rd;
4631   bits<5> Rn;
4632   let Inst{31}    = 0;
4633   let Inst{30}    = Q;
4634   let Inst{29}    = U;
4635   let Inst{28-24} = 0b01110;
4636   let Inst{23-22} = size;
4637   let Inst{21} = 0b1;
4638   let Inst{20-19} = size2;
4639   let Inst{18-17} = 0b00;
4640   let Inst{16-12} = opcode;
4641   let Inst{11-10} = 0b10;
4642   let Inst{9-5}   = Rn;
4643   let Inst{4-0}   = Rd;
4644 }
4645
4646 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4647 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4648                                 bits<2> size2, RegisterOperand regtype,
4649                                 string asm, string dstkind, string srckind,
4650                                 list<dag> pattern>
4651   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4652       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4653       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4654     Sched<[WriteV]> {
4655   bits<5> Rd;
4656   bits<5> Rn;
4657   let Inst{31}    = 0;
4658   let Inst{30}    = Q;
4659   let Inst{29}    = U;
4660   let Inst{28-24} = 0b01110;
4661   let Inst{23-22} = size;
4662   let Inst{21} = 0b1;
4663   let Inst{20-19} = size2;
4664   let Inst{18-17} = 0b00;
4665   let Inst{16-12} = opcode;
4666   let Inst{11-10} = 0b10;
4667   let Inst{9-5}   = Rn;
4668   let Inst{4-0}   = Rd;
4669 }
4670
4671 // Supports B, H, and S element sizes.
4672 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4673                             SDPatternOperator OpNode> {
4674   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4675                                       asm, ".8b", ".8b",
4676                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4677   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4678                                       asm, ".16b", ".16b",
4679                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4680   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4681                                       asm, ".4h", ".4h",
4682                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4683   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4684                                       asm, ".8h", ".8h",
4685                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4686   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4687                                       asm, ".2s", ".2s",
4688                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4689   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4690                                       asm, ".4s", ".4s",
4691                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4692 }
4693
4694 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4695                             RegisterOperand regtype, string asm, string dstkind,
4696                             string srckind, string amount>
4697   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4698       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4699       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
4700     Sched<[WriteV]> {
4701   bits<5> Rd;
4702   bits<5> Rn;
4703   let Inst{31}    = 0;
4704   let Inst{30}    = Q;
4705   let Inst{29-24} = 0b101110;
4706   let Inst{23-22} = size;
4707   let Inst{21-10} = 0b100001001110;
4708   let Inst{9-5}   = Rn;
4709   let Inst{4-0}   = Rd;
4710 }
4711
4712 multiclass SIMDVectorLShiftLongBySizeBHS {
4713   let hasSideEffects = 0 in {
4714   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4715                                              "shll", ".8h",  ".8b", "8">;
4716   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4717                                              "shll2", ".8h", ".16b", "8">;
4718   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4719                                              "shll", ".4s",  ".4h", "16">;
4720   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4721                                              "shll2", ".4s", ".8h", "16">;
4722   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4723                                              "shll", ".2d",  ".2s", "32">;
4724   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4725                                              "shll2", ".2d", ".4s", "32">;
4726   }
4727 }
4728
4729 // Supports all element sizes.
4730 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4731                              SDPatternOperator OpNode> {
4732   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4733                                       asm, ".4h", ".8b",
4734                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4735   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4736                                       asm, ".8h", ".16b",
4737                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4738   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4739                                       asm, ".2s", ".4h",
4740                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4741   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4742                                       asm, ".4s", ".8h",
4743                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4744   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4745                                       asm, ".1d", ".2s",
4746                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4747   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4748                                       asm, ".2d", ".4s",
4749                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4750 }
4751
4752 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4753                                  SDPatternOperator OpNode> {
4754   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4755                                           asm, ".4h", ".8b",
4756       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4757                                       (v8i8 V64:$Rn)))]>;
4758   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4759                                           asm, ".8h", ".16b",
4760       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4761                                       (v16i8 V128:$Rn)))]>;
4762   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4763                                           asm, ".2s", ".4h",
4764       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4765                                       (v4i16 V64:$Rn)))]>;
4766   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4767                                           asm, ".4s", ".8h",
4768       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4769                                       (v8i16 V128:$Rn)))]>;
4770   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4771                                           asm, ".1d", ".2s",
4772       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4773                                       (v2i32 V64:$Rn)))]>;
4774   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4775                                           asm, ".2d", ".4s",
4776       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4777                                       (v4i32 V128:$Rn)))]>;
4778 }
4779
4780 // Supports all element sizes, except 1xD.
4781 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4782                                   SDPatternOperator OpNode> {
4783   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4784                                     asm, ".8b", ".8b",
4785     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4786   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4787                                     asm, ".16b", ".16b",
4788     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4789   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4790                                     asm, ".4h", ".4h",
4791     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4792   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4793                                     asm, ".8h", ".8h",
4794     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4795   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4796                                     asm, ".2s", ".2s",
4797     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4798   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4799                                     asm, ".4s", ".4s",
4800     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4801   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
4802                                     asm, ".2d", ".2d",
4803     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4804 }
4805
4806 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4807                              SDPatternOperator OpNode = null_frag> {
4808   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4809                                 asm, ".8b", ".8b",
4810     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4811   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4812                                 asm, ".16b", ".16b",
4813     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4814   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4815                                 asm, ".4h", ".4h",
4816     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4817   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4818                                 asm, ".8h", ".8h",
4819     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4820   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4821                                 asm, ".2s", ".2s",
4822     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4823   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4824                                 asm, ".4s", ".4s",
4825     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4826   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
4827                                 asm, ".2d", ".2d",
4828     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4829 }
4830
4831
4832 // Supports only B element sizes.
4833 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4834                           SDPatternOperator OpNode> {
4835   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
4836                                 asm, ".8b", ".8b",
4837                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4838   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
4839                                 asm, ".16b", ".16b",
4840                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4841
4842 }
4843
4844 // Supports only B and H element sizes.
4845 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4846                                 SDPatternOperator OpNode> {
4847   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4848                                 asm, ".8b", ".8b",
4849                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4850   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4851                                 asm, ".16b", ".16b",
4852                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4853   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4854                                 asm, ".4h", ".4h",
4855                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4856   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4857                                 asm, ".8h", ".8h",
4858                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4859 }
4860
4861 // Supports only S and D element sizes, uses high bit of the size field
4862 // as an extra opcode bit.
4863 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4864                            SDPatternOperator OpNode> {
4865   let Predicates = [HasNEON, HasFullFP16] in {
4866   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4867                                 asm, ".4h", ".4h",
4868                           [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
4869   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4870                                 asm, ".8h", ".8h",
4871                           [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
4872   } // Predicates = [HasNEON, HasFullFP16]
4873   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4874                                 asm, ".2s", ".2s",
4875                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4876   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4877                                 asm, ".4s", ".4s",
4878                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4879   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
4880                                 asm, ".2d", ".2d",
4881                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4882 }
4883
4884 // Supports only S element size.
4885 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4886                            SDPatternOperator OpNode> {
4887   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4888                                 asm, ".2s", ".2s",
4889                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4890   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4891                                 asm, ".4s", ".4s",
4892                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4893 }
4894
4895
4896 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4897                            SDPatternOperator OpNode> {
4898   let Predicates = [HasNEON, HasFullFP16] in {
4899   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4900                                 asm, ".4h", ".4h",
4901                           [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
4902   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4903                                 asm, ".8h", ".8h",
4904                           [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
4905   } // Predicates = [HasNEON, HasFullFP16]
4906   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4907                                 asm, ".2s", ".2s",
4908                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4909   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4910                                 asm, ".4s", ".4s",
4911                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4912   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
4913                                 asm, ".2d", ".2d",
4914                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4915 }
4916
4917 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4918                            SDPatternOperator OpNode> {
4919   let Predicates = [HasNEON, HasFullFP16] in {
4920   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4921                                 asm, ".4h", ".4h",
4922                           [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4923   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4924                                 asm, ".8h", ".8h",
4925                           [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4926   } // Predicates = [HasNEON, HasFullFP16]
4927   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4928                                 asm, ".2s", ".2s",
4929                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4930   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4931                                 asm, ".4s", ".4s",
4932                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4933   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
4934                                 asm, ".2d", ".2d",
4935                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4936 }
4937
4938
4939 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4940                            RegisterOperand inreg, RegisterOperand outreg,
4941                            string asm, string outkind, string inkind,
4942                            list<dag> pattern>
4943   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4944       "{\t$Rd" # outkind # ", $Rn" # inkind #
4945       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4946     Sched<[WriteV]> {
4947   bits<5> Rd;
4948   bits<5> Rn;
4949   let Inst{31}    = 0;
4950   let Inst{30}    = Q;
4951   let Inst{29}    = U;
4952   let Inst{28-24} = 0b01110;
4953   let Inst{23-22} = size;
4954   let Inst{21-17} = 0b10000;
4955   let Inst{16-12} = opcode;
4956   let Inst{11-10} = 0b10;
4957   let Inst{9-5}   = Rn;
4958   let Inst{4-0}   = Rd;
4959 }
4960
4961 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4962                            RegisterOperand inreg, RegisterOperand outreg,
4963                            string asm, string outkind, string inkind,
4964                            list<dag> pattern>
4965   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4966       "{\t$Rd" # outkind # ", $Rn" # inkind #
4967       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4968     Sched<[WriteV]> {
4969   bits<5> Rd;
4970   bits<5> Rn;
4971   let Inst{31}    = 0;
4972   let Inst{30}    = Q;
4973   let Inst{29}    = U;
4974   let Inst{28-24} = 0b01110;
4975   let Inst{23-22} = size;
4976   let Inst{21-17} = 0b10000;
4977   let Inst{16-12} = opcode;
4978   let Inst{11-10} = 0b10;
4979   let Inst{9-5}   = Rn;
4980   let Inst{4-0}   = Rd;
4981 }
4982
4983 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4984                               SDPatternOperator OpNode> {
4985   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4986                                       asm, ".8b", ".8h",
4987         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4988   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4989                                       asm#"2", ".16b", ".8h", []>;
4990   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4991                                       asm, ".4h", ".4s",
4992         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4993   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4994                                       asm#"2", ".8h", ".4s", []>;
4995   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4996                                       asm, ".2s", ".2d",
4997         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4998   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4999                                       asm#"2", ".4s", ".2d", []>;
5000
5001   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
5002             (!cast<Instruction>(NAME # "v16i8")
5003                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5004   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
5005             (!cast<Instruction>(NAME # "v8i16")
5006                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5007   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
5008             (!cast<Instruction>(NAME # "v4i32")
5009                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5010 }
5011
5012 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
5013                            bits<5> opcode, RegisterOperand regtype, string asm,
5014                            string kind, string zero, ValueType dty,
5015                            ValueType sty, SDNode OpNode>
5016   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5017       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5018       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5019       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5020     Sched<[WriteV]> {
5021   bits<5> Rd;
5022   bits<5> Rn;
5023   let Inst{31}    = 0;
5024   let Inst{30}    = Q;
5025   let Inst{29}    = U;
5026   let Inst{28-24} = 0b01110;
5027   let Inst{23-22} = size;
5028   let Inst{21} = 0b1;
5029   let Inst{20-19} = size2;
5030   let Inst{18-17} = 0b00;
5031   let Inst{16-12} = opcode;
5032   let Inst{11-10} = 0b10;
5033   let Inst{9-5}   = Rn;
5034   let Inst{4-0}   = Rd;
5035 }
5036
5037 // Comparisons support all element sizes, except 1xD.
5038 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5039                             SDNode OpNode> {
5040   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
5041                                      asm, ".8b", "0",
5042                                      v8i8, v8i8, OpNode>;
5043   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
5044                                      asm, ".16b", "0",
5045                                      v16i8, v16i8, OpNode>;
5046   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
5047                                      asm, ".4h", "0",
5048                                      v4i16, v4i16, OpNode>;
5049   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
5050                                      asm, ".8h", "0",
5051                                      v8i16, v8i16, OpNode>;
5052   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
5053                                      asm, ".2s", "0",
5054                                      v2i32, v2i32, OpNode>;
5055   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
5056                                      asm, ".4s", "0",
5057                                      v4i32, v4i32, OpNode>;
5058   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
5059                                      asm, ".2d", "0",
5060                                      v2i64, v2i64, OpNode>;
5061 }
5062
5063 // FP Comparisons support only S and D element sizes (and H for v8.2a).
5064 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5065                               string asm, SDNode OpNode> {
5066
5067   let Predicates = [HasNEON, HasFullFP16] in {
5068   def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5069                                      asm, ".4h", "0.0",
5070                                      v4i16, v4f16, OpNode>;
5071   def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5072                                      asm, ".8h", "0.0",
5073                                      v8i16, v8f16, OpNode>;
5074   } // Predicates = [HasNEON, HasFullFP16]
5075   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
5076                                      asm, ".2s", "0.0",
5077                                      v2i32, v2f32, OpNode>;
5078   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
5079                                      asm, ".4s", "0.0",
5080                                      v4i32, v4f32, OpNode>;
5081   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
5082                                      asm, ".2d", "0.0",
5083                                      v2i64, v2f64, OpNode>;
5084
5085   let Predicates = [HasNEON, HasFullFP16] in {
5086   def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5087                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5088   def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5089                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5090   }
5091   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
5092                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5093   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
5094                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5095   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
5096                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5097   let Predicates = [HasNEON, HasFullFP16] in {
5098   def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5099                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5100   def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5101                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5102   }
5103   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
5104                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5105   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
5106                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5107   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
5108                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5109 }
5110
5111 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5112 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5113                              RegisterOperand outtype, RegisterOperand intype,
5114                              string asm, string VdTy, string VnTy,
5115                              list<dag> pattern>
5116   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5117       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5118     Sched<[WriteV]> {
5119   bits<5> Rd;
5120   bits<5> Rn;
5121   let Inst{31}    = 0;
5122   let Inst{30}    = Q;
5123   let Inst{29}    = U;
5124   let Inst{28-24} = 0b01110;
5125   let Inst{23-22} = size;
5126   let Inst{21-17} = 0b10000;
5127   let Inst{16-12} = opcode;
5128   let Inst{11-10} = 0b10;
5129   let Inst{9-5}   = Rn;
5130   let Inst{4-0}   = Rd;
5131 }
5132
5133 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5134                              RegisterOperand outtype, RegisterOperand intype,
5135                              string asm, string VdTy, string VnTy,
5136                              list<dag> pattern>
5137   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5138       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5139     Sched<[WriteV]> {
5140   bits<5> Rd;
5141   bits<5> Rn;
5142   let Inst{31}    = 0;
5143   let Inst{30}    = Q;
5144   let Inst{29}    = U;
5145   let Inst{28-24} = 0b01110;
5146   let Inst{23-22} = size;
5147   let Inst{21-17} = 0b10000;
5148   let Inst{16-12} = opcode;
5149   let Inst{11-10} = 0b10;
5150   let Inst{9-5}   = Rn;
5151   let Inst{4-0}   = Rd;
5152 }
5153
5154 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5155   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5156                                     asm, ".4s", ".4h", []>;
5157   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5158                                     asm#"2", ".4s", ".8h", []>;
5159   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5160                                     asm, ".2d", ".2s", []>;
5161   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5162                                     asm#"2", ".2d", ".4s", []>;
5163 }
5164
5165 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5166   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5167                                     asm, ".4h", ".4s", []>;
5168   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5169                                     asm#"2", ".8h", ".4s", []>;
5170   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5171                                     asm, ".2s", ".2d", []>;
5172   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5173                                     asm#"2", ".4s", ".2d", []>;
5174 }
5175
5176 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5177                                      Intrinsic OpNode> {
5178   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5179                                      asm, ".2s", ".2d",
5180                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5181   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5182                                     asm#"2", ".4s", ".2d", []>;
5183
5184   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5185             (!cast<Instruction>(NAME # "v4f32")
5186                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5187 }
5188
5189 //----------------------------------------------------------------------------
5190 // AdvSIMD three register different-size vector instructions.
5191 //----------------------------------------------------------------------------
5192
5193 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5194 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5195                       RegisterOperand outtype, RegisterOperand intype1,
5196                       RegisterOperand intype2, string asm,
5197                       string outkind, string inkind1, string inkind2,
5198                       list<dag> pattern>
5199   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5200       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5201       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5202     Sched<[WriteV]> {
5203   bits<5> Rd;
5204   bits<5> Rn;
5205   bits<5> Rm;
5206   let Inst{31}    = 0;
5207   let Inst{30}    = size{0};
5208   let Inst{29}    = U;
5209   let Inst{28-24} = 0b01110;
5210   let Inst{23-22} = size{2-1};
5211   let Inst{21}    = 1;
5212   let Inst{20-16} = Rm;
5213   let Inst{15-12} = opcode;
5214   let Inst{11-10} = 0b00;
5215   let Inst{9-5}   = Rn;
5216   let Inst{4-0}   = Rd;
5217 }
5218
5219 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5220 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5221                       RegisterOperand outtype, RegisterOperand intype1,
5222                       RegisterOperand intype2, string asm,
5223                       string outkind, string inkind1, string inkind2,
5224                       list<dag> pattern>
5225   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5226       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5227       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5228     Sched<[WriteV]> {
5229   bits<5> Rd;
5230   bits<5> Rn;
5231   bits<5> Rm;
5232   let Inst{31}    = 0;
5233   let Inst{30}    = size{0};
5234   let Inst{29}    = U;
5235   let Inst{28-24} = 0b01110;
5236   let Inst{23-22} = size{2-1};
5237   let Inst{21}    = 1;
5238   let Inst{20-16} = Rm;
5239   let Inst{15-12} = opcode;
5240   let Inst{11-10} = 0b00;
5241   let Inst{9-5}   = Rn;
5242   let Inst{4-0}   = Rd;
5243 }
5244
5245 // FIXME: TableGen doesn't know how to deal with expanded types that also
5246 //        change the element count (in this case, placing the results in
5247 //        the high elements of the result register rather than the low
5248 //        elements). Until that's fixed, we can't code-gen those.
5249 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5250                                     Intrinsic IntOp> {
5251   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5252                                                   V64, V128, V128,
5253                                                   asm, ".8b", ".8h", ".8h",
5254      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5255   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5256                                                   V128, V128, V128,
5257                                                   asm#"2", ".16b", ".8h", ".8h",
5258      []>;
5259   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5260                                                   V64, V128, V128,
5261                                                   asm, ".4h", ".4s", ".4s",
5262      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5263   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5264                                                   V128, V128, V128,
5265                                                   asm#"2", ".8h", ".4s", ".4s",
5266      []>;
5267   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5268                                                   V64, V128, V128,
5269                                                   asm, ".2s", ".2d", ".2d",
5270      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5271   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5272                                                   V128, V128, V128,
5273                                                   asm#"2", ".4s", ".2d", ".2d",
5274      []>;
5275
5276
5277   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5278   // a version attached to an instruction.
5279   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5280                                                    (v8i16 V128:$Rm))),
5281             (!cast<Instruction>(NAME # "v8i16_v16i8")
5282                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5283                 V128:$Rn, V128:$Rm)>;
5284   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5285                                                     (v4i32 V128:$Rm))),
5286             (!cast<Instruction>(NAME # "v4i32_v8i16")
5287                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5288                 V128:$Rn, V128:$Rm)>;
5289   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5290                                                     (v2i64 V128:$Rm))),
5291             (!cast<Instruction>(NAME # "v2i64_v4i32")
5292                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5293                 V128:$Rn, V128:$Rm)>;
5294 }
5295
5296 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5297                                       Intrinsic IntOp> {
5298   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5299                                             V128, V64, V64,
5300                                             asm, ".8h", ".8b", ".8b",
5301       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5302   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5303                                             V128, V128, V128,
5304                                             asm#"2", ".8h", ".16b", ".16b", []>;
5305   let Predicates = [HasCrypto] in {
5306     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5307                                               V128, V64, V64,
5308                                               asm, ".1q", ".1d", ".1d", []>;
5309     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5310                                               V128, V128, V128,
5311                                               asm#"2", ".1q", ".2d", ".2d", []>;
5312   }
5313
5314   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5315                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
5316       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5317 }
5318
5319 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5320                                  SDPatternOperator OpNode> {
5321   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5322                                                   V128, V64, V64,
5323                                                   asm, ".4s", ".4h", ".4h",
5324       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5325   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5326                                                   V128, V128, V128,
5327                                                   asm#"2", ".4s", ".8h", ".8h",
5328       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5329                                       (extract_high_v8i16 V128:$Rm)))]>;
5330   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5331                                                   V128, V64, V64,
5332                                                   asm, ".2d", ".2s", ".2s",
5333       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5334   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5335                                                   V128, V128, V128,
5336                                                   asm#"2", ".2d", ".4s", ".4s",
5337       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5338                                       (extract_high_v4i32 V128:$Rm)))]>;
5339 }
5340
5341 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5342                                   SDPatternOperator OpNode = null_frag> {
5343   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5344                                                   V128, V64, V64,
5345                                                   asm, ".8h", ".8b", ".8b",
5346       [(set (v8i16 V128:$Rd),
5347             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5348   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5349                                                  V128, V128, V128,
5350                                                  asm#"2", ".8h", ".16b", ".16b",
5351       [(set (v8i16 V128:$Rd),
5352             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5353                                 (extract_high_v16i8 V128:$Rm)))))]>;
5354   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5355                                                   V128, V64, V64,
5356                                                   asm, ".4s", ".4h", ".4h",
5357       [(set (v4i32 V128:$Rd),
5358             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5359   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5360                                                   V128, V128, V128,
5361                                                   asm#"2", ".4s", ".8h", ".8h",
5362       [(set (v4i32 V128:$Rd),
5363             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5364                                   (extract_high_v8i16 V128:$Rm)))))]>;
5365   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5366                                                   V128, V64, V64,
5367                                                   asm, ".2d", ".2s", ".2s",
5368       [(set (v2i64 V128:$Rd),
5369             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5370   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5371                                                   V128, V128, V128,
5372                                                   asm#"2", ".2d", ".4s", ".4s",
5373       [(set (v2i64 V128:$Rd),
5374             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5375                                  (extract_high_v4i32 V128:$Rm)))))]>;
5376 }
5377
5378 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5379                                           string asm,
5380                                           SDPatternOperator OpNode> {
5381   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5382                                                   V128, V64, V64,
5383                                                   asm, ".8h", ".8b", ".8b",
5384     [(set (v8i16 V128:$dst),
5385           (add (v8i16 V128:$Rd),
5386                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5387   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5388                                                  V128, V128, V128,
5389                                                  asm#"2", ".8h", ".16b", ".16b",
5390     [(set (v8i16 V128:$dst),
5391           (add (v8i16 V128:$Rd),
5392                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5393                                    (extract_high_v16i8 V128:$Rm))))))]>;
5394   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5395                                                   V128, V64, V64,
5396                                                   asm, ".4s", ".4h", ".4h",
5397     [(set (v4i32 V128:$dst),
5398           (add (v4i32 V128:$Rd),
5399                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5400   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5401                                                   V128, V128, V128,
5402                                                   asm#"2", ".4s", ".8h", ".8h",
5403     [(set (v4i32 V128:$dst),
5404           (add (v4i32 V128:$Rd),
5405                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5406                                     (extract_high_v8i16 V128:$Rm))))))]>;
5407   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5408                                                   V128, V64, V64,
5409                                                   asm, ".2d", ".2s", ".2s",
5410     [(set (v2i64 V128:$dst),
5411           (add (v2i64 V128:$Rd),
5412                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5413   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5414                                                   V128, V128, V128,
5415                                                   asm#"2", ".2d", ".4s", ".4s",
5416     [(set (v2i64 V128:$dst),
5417           (add (v2i64 V128:$Rd),
5418                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5419                                     (extract_high_v4i32 V128:$Rm))))))]>;
5420 }
5421
5422 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5423                                   SDPatternOperator OpNode = null_frag> {
5424   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5425                                                   V128, V64, V64,
5426                                                   asm, ".8h", ".8b", ".8b",
5427       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5428   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5429                                                  V128, V128, V128,
5430                                                  asm#"2", ".8h", ".16b", ".16b",
5431       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5432                                       (extract_high_v16i8 V128:$Rm)))]>;
5433   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5434                                                   V128, V64, V64,
5435                                                   asm, ".4s", ".4h", ".4h",
5436       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5437   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5438                                                   V128, V128, V128,
5439                                                   asm#"2", ".4s", ".8h", ".8h",
5440       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5441                                       (extract_high_v8i16 V128:$Rm)))]>;
5442   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5443                                                   V128, V64, V64,
5444                                                   asm, ".2d", ".2s", ".2s",
5445       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5446   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5447                                                   V128, V128, V128,
5448                                                   asm#"2", ".2d", ".4s", ".4s",
5449       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5450                                       (extract_high_v4i32 V128:$Rm)))]>;
5451 }
5452
5453 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5454                                       string asm,
5455                                       SDPatternOperator OpNode> {
5456   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5457                                                   V128, V64, V64,
5458                                                   asm, ".8h", ".8b", ".8b",
5459     [(set (v8i16 V128:$dst),
5460           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5461   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5462                                                  V128, V128, V128,
5463                                                  asm#"2", ".8h", ".16b", ".16b",
5464     [(set (v8i16 V128:$dst),
5465           (OpNode (v8i16 V128:$Rd),
5466                   (extract_high_v16i8 V128:$Rn),
5467                   (extract_high_v16i8 V128:$Rm)))]>;
5468   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5469                                                   V128, V64, V64,
5470                                                   asm, ".4s", ".4h", ".4h",
5471     [(set (v4i32 V128:$dst),
5472           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5473   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5474                                                   V128, V128, V128,
5475                                                   asm#"2", ".4s", ".8h", ".8h",
5476     [(set (v4i32 V128:$dst),
5477           (OpNode (v4i32 V128:$Rd),
5478                   (extract_high_v8i16 V128:$Rn),
5479                   (extract_high_v8i16 V128:$Rm)))]>;
5480   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5481                                                   V128, V64, V64,
5482                                                   asm, ".2d", ".2s", ".2s",
5483     [(set (v2i64 V128:$dst),
5484           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5485   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5486                                                   V128, V128, V128,
5487                                                   asm#"2", ".2d", ".4s", ".4s",
5488     [(set (v2i64 V128:$dst),
5489           (OpNode (v2i64 V128:$Rd),
5490                   (extract_high_v4i32 V128:$Rn),
5491                   (extract_high_v4i32 V128:$Rm)))]>;
5492 }
5493
5494 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5495                                            SDPatternOperator Accum> {
5496   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5497                                                   V128, V64, V64,
5498                                                   asm, ".4s", ".4h", ".4h",
5499     [(set (v4i32 V128:$dst),
5500           (Accum (v4i32 V128:$Rd),
5501                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5502                                                 (v4i16 V64:$Rm)))))]>;
5503   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5504                                                   V128, V128, V128,
5505                                                   asm#"2", ".4s", ".8h", ".8h",
5506     [(set (v4i32 V128:$dst),
5507           (Accum (v4i32 V128:$Rd),
5508                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5509                                             (extract_high_v8i16 V128:$Rm)))))]>;
5510   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5511                                                   V128, V64, V64,
5512                                                   asm, ".2d", ".2s", ".2s",
5513     [(set (v2i64 V128:$dst),
5514           (Accum (v2i64 V128:$Rd),
5515                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5516                                                 (v2i32 V64:$Rm)))))]>;
5517   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5518                                                   V128, V128, V128,
5519                                                   asm#"2", ".2d", ".4s", ".4s",
5520     [(set (v2i64 V128:$dst),
5521           (Accum (v2i64 V128:$Rd),
5522                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5523                                             (extract_high_v4i32 V128:$Rm)))))]>;
5524 }
5525
5526 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5527                                   SDPatternOperator OpNode> {
5528   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5529                                                   V128, V128, V64,
5530                                                   asm, ".8h", ".8h", ".8b",
5531        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5532   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5533                                                   V128, V128, V128,
5534                                                   asm#"2", ".8h", ".8h", ".16b",
5535        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5536                                        (extract_high_v16i8 V128:$Rm)))]>;
5537   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5538                                                   V128, V128, V64,
5539                                                   asm, ".4s", ".4s", ".4h",
5540        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5541   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5542                                                   V128, V128, V128,
5543                                                   asm#"2", ".4s", ".4s", ".8h",
5544        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5545                                        (extract_high_v8i16 V128:$Rm)))]>;
5546   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5547                                                   V128, V128, V64,
5548                                                   asm, ".2d", ".2d", ".2s",
5549        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5550   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5551                                                   V128, V128, V128,
5552                                                   asm#"2", ".2d", ".2d", ".4s",
5553        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5554                                        (extract_high_v4i32 V128:$Rm)))]>;
5555 }
5556
5557 //----------------------------------------------------------------------------
5558 // AdvSIMD bitwise extract from vector
5559 //----------------------------------------------------------------------------
5560
5561 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5562                              string asm, string kind>
5563   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5564       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5565       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5566       [(set (vty regtype:$Rd),
5567             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5568     Sched<[WriteV]> {
5569   bits<5> Rd;
5570   bits<5> Rn;
5571   bits<5> Rm;
5572   bits<4> imm;
5573   let Inst{31}    = 0;
5574   let Inst{30}    = size;
5575   let Inst{29-21} = 0b101110000;
5576   let Inst{20-16} = Rm;
5577   let Inst{15}    = 0;
5578   let Inst{14-11} = imm;
5579   let Inst{10}    = 0;
5580   let Inst{9-5}   = Rn;
5581   let Inst{4-0}   = Rd;
5582 }
5583
5584
5585 multiclass SIMDBitwiseExtract<string asm> {
5586   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5587     let imm{3} = 0;
5588   }
5589   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5590 }
5591
5592 //----------------------------------------------------------------------------
5593 // AdvSIMD zip vector
5594 //----------------------------------------------------------------------------
5595
5596 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5597                         string asm, string kind, SDNode OpNode, ValueType valty>
5598   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5599       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5600       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5601       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5602     Sched<[WriteV]> {
5603   bits<5> Rd;
5604   bits<5> Rn;
5605   bits<5> Rm;
5606   let Inst{31}    = 0;
5607   let Inst{30}    = size{0};
5608   let Inst{29-24} = 0b001110;
5609   let Inst{23-22} = size{2-1};
5610   let Inst{21}    = 0;
5611   let Inst{20-16} = Rm;
5612   let Inst{15}    = 0;
5613   let Inst{14-12} = opc;
5614   let Inst{11-10} = 0b10;
5615   let Inst{9-5}   = Rn;
5616   let Inst{4-0}   = Rd;
5617 }
5618
5619 multiclass SIMDZipVector<bits<3>opc, string asm,
5620                          SDNode OpNode> {
5621   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
5622       asm, ".8b", OpNode, v8i8>;
5623   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
5624       asm, ".16b", OpNode, v16i8>;
5625   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
5626       asm, ".4h", OpNode, v4i16>;
5627   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
5628       asm, ".8h", OpNode, v8i16>;
5629   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
5630       asm, ".2s", OpNode, v2i32>;
5631   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
5632       asm, ".4s", OpNode, v4i32>;
5633   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
5634       asm, ".2d", OpNode, v2i64>;
5635
5636   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5637         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5638   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5639         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
5640   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5641         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5642   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5643         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5644   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5645         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5646 }
5647
5648 //----------------------------------------------------------------------------
5649 // AdvSIMD three register scalar instructions
5650 //----------------------------------------------------------------------------
5651
5652 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5653 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
5654                         RegisterClass regtype, string asm,
5655                         list<dag> pattern>
5656   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5657       "\t$Rd, $Rn, $Rm", "", pattern>,
5658     Sched<[WriteV]> {
5659   bits<5> Rd;
5660   bits<5> Rn;
5661   bits<5> Rm;
5662   let Inst{31-30} = 0b01;
5663   let Inst{29}    = U;
5664   let Inst{28-24} = 0b11110;
5665   let Inst{23-21} = size;
5666   let Inst{20-16} = Rm;
5667   let Inst{15-11} = opcode;
5668   let Inst{10}    = 1;
5669   let Inst{9-5}   = Rn;
5670   let Inst{4-0}   = Rd;
5671 }
5672
5673 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5674 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5675                         dag oops, dag iops, string asm,
5676             list<dag> pattern>
5677   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5678     Sched<[WriteV]> {
5679   bits<5> Rd;
5680   bits<5> Rn;
5681   bits<5> Rm;
5682   let Inst{31-30} = 0b01;
5683   let Inst{29}    = U;
5684   let Inst{28-24} = 0b11110;
5685   let Inst{23-22} = size;
5686   let Inst{21}    = R;
5687   let Inst{20-16} = Rm;
5688   let Inst{15-11} = opcode;
5689   let Inst{10}    = 1;
5690   let Inst{9-5}   = Rn;
5691   let Inst{4-0}   = Rd;
5692 }
5693
5694 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5695                             SDPatternOperator OpNode> {
5696   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5697     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5698 }
5699
5700 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5701                                SDPatternOperator OpNode> {
5702   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5703     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5704   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
5705   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5706   def v1i8   : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
5707
5708   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5709             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5710   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5711             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5712 }
5713
5714 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5715                              SDPatternOperator OpNode> {
5716   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
5717                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5718   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5719 }
5720
5721 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5722                                  SDPatternOperator OpNode = null_frag> {
5723   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5724                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 
5725                                      asm, []>;
5726   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5727                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 
5728                                      asm, []>;
5729 }
5730
5731 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
5732                              SDPatternOperator OpNode = null_frag> {
5733   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5734     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5735       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5736     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5737       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5738     let Predicates = [HasNEON, HasFullFP16] in {
5739     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5740       [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
5741     } // Predicates = [HasNEON, HasFullFP16]
5742   }
5743
5744   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5745             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5746 }
5747
5748 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
5749                                 SDPatternOperator OpNode = null_frag> {
5750   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5751     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5752       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5753     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5754       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5755     let Predicates = [HasNEON, HasFullFP16] in {
5756     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5757       []>;
5758     } // Predicates = [HasNEON, HasFullFP16]
5759   }
5760
5761   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5762             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5763 }
5764
5765 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5766               dag oops, dag iops, string asm, string cstr, list<dag> pat>
5767   : I<oops, iops, asm,
5768       "\t$Rd, $Rn, $Rm", cstr, pat>,
5769     Sched<[WriteV]> {
5770   bits<5> Rd;
5771   bits<5> Rn;
5772   bits<5> Rm;
5773   let Inst{31-30} = 0b01;
5774   let Inst{29}    = U;
5775   let Inst{28-24} = 0b11110;
5776   let Inst{23-22} = size;
5777   let Inst{21}    = 1;
5778   let Inst{20-16} = Rm;
5779   let Inst{15-11} = opcode;
5780   let Inst{10}    = 0;
5781   let Inst{9-5}   = Rn;
5782   let Inst{4-0}   = Rd;
5783 }
5784
5785 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5786 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5787                                   SDPatternOperator OpNode = null_frag> {
5788   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5789                                       (outs FPR32:$Rd),
5790                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5791   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5792                                       (outs FPR64:$Rd),
5793                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5794             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5795 }
5796
5797 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5798 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5799                                   SDPatternOperator OpNode = null_frag> {
5800   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5801                                       (outs FPR32:$dst),
5802                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5803                                       asm, "$Rd = $dst", []>;
5804   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5805                                       (outs FPR64:$dst),
5806                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5807                                       asm, "$Rd = $dst",
5808             [(set (i64 FPR64:$dst),
5809                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5810 }
5811
5812 //----------------------------------------------------------------------------
5813 // AdvSIMD two register scalar instructions
5814 //----------------------------------------------------------------------------
5815
5816 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5817 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
5818                         RegisterClass regtype, RegisterClass regtype2,
5819                         string asm, list<dag> pat>
5820   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5821       "\t$Rd, $Rn", "", pat>,
5822     Sched<[WriteV]> {
5823   bits<5> Rd;
5824   bits<5> Rn;
5825   let Inst{31-30} = 0b01;
5826   let Inst{29}    = U;
5827   let Inst{28-24} = 0b11110;
5828   let Inst{23-22} = size;
5829   let Inst{21} = 0b1;
5830   let Inst{20-19} = size2;
5831   let Inst{18-17} = 0b00;
5832   let Inst{16-12} = opcode;
5833   let Inst{11-10} = 0b10;
5834   let Inst{9-5}   = Rn;
5835   let Inst{4-0}   = Rd;
5836 }
5837
5838 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5839 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5840                         RegisterClass regtype, RegisterClass regtype2,
5841                         string asm, list<dag> pat>
5842   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5843       "\t$Rd, $Rn", "$Rd = $dst", pat>,
5844     Sched<[WriteV]> {
5845   bits<5> Rd;
5846   bits<5> Rn;
5847   let Inst{31-30} = 0b01;
5848   let Inst{29}    = U;
5849   let Inst{28-24} = 0b11110;
5850   let Inst{23-22} = size;
5851   let Inst{21-17} = 0b10000;
5852   let Inst{16-12} = opcode;
5853   let Inst{11-10} = 0b10;
5854   let Inst{9-5}   = Rn;
5855   let Inst{4-0}   = Rd;
5856 }
5857
5858
5859 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5860 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
5861                         RegisterClass regtype, string asm, string zero>
5862   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5863       "\t$Rd, $Rn, #" # zero, "", []>,
5864     Sched<[WriteV]> {
5865   bits<5> Rd;
5866   bits<5> Rn;
5867   let Inst{31-30} = 0b01;
5868   let Inst{29}    = U;
5869   let Inst{28-24} = 0b11110;
5870   let Inst{23-22} = size;
5871   let Inst{21} = 0b1;
5872   let Inst{20-19} = size2;
5873   let Inst{18-17} = 0b00;
5874   let Inst{16-12} = opcode;
5875   let Inst{11-10} = 0b10;
5876   let Inst{9-5}   = Rn;
5877   let Inst{4-0}   = Rd;
5878 }
5879
5880 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5881   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5882      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5883     Sched<[WriteV]> {
5884   bits<5> Rd;
5885   bits<5> Rn;
5886   let Inst{31-17} = 0b011111100110000;
5887   let Inst{16-12} = opcode;
5888   let Inst{11-10} = 0b10;
5889   let Inst{9-5}   = Rn;
5890   let Inst{4-0}   = Rd;
5891 }
5892
5893 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5894                              SDPatternOperator OpNode> {
5895   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
5896
5897   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5898             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5899 }
5900
5901 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
5902                               SDPatternOperator OpNode> {
5903   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
5904   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
5905   let Predicates = [HasNEON, HasFullFP16] in {
5906   def v1i16rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
5907   }
5908
5909   def : InstAlias<asm # "\t$Rd, $Rn, #0",
5910                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
5911   def : InstAlias<asm # "\t$Rd, $Rn, #0",
5912                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5913   let Predicates = [HasNEON, HasFullFP16] in {
5914   def : InstAlias<asm # "\t$Rd, $Rn, #0",
5915                   (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
5916   }
5917
5918   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5919             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5920 }
5921
5922 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5923                           SDPatternOperator OpNode = null_frag> {
5924   def v1i64       : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
5925     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5926
5927   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5928             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5929 }
5930
5931 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
5932   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
5933   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
5934   let Predicates = [HasNEON, HasFullFP16] in {
5935   def v1f16       : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
5936   }
5937 }
5938
5939 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
5940                               SDPatternOperator OpNode> {
5941   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
5942                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5943   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
5944                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5945   let Predicates = [HasNEON, HasFullFP16] in {
5946   def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
5947                                 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
5948   }
5949 }
5950
5951 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5952                              SDPatternOperator OpNode = null_frag> {
5953   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5954     def v1i64  : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
5955            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5956     def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
5957            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5958     def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
5959     def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
5960   }
5961
5962   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5963             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5964 }
5965
5966 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5967                                  Intrinsic OpNode> {
5968   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5969     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5970         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5971     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5972         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5973     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5974     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5975   }
5976
5977   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5978             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5979 }
5980
5981
5982
5983 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5984 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5985                                  SDPatternOperator OpNode = null_frag> {
5986   def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
5987         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5988   def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
5989   def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
5990 }
5991
5992 //----------------------------------------------------------------------------
5993 // AdvSIMD scalar pairwise instructions
5994 //----------------------------------------------------------------------------
5995
5996 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5997 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5998                         RegisterOperand regtype, RegisterOperand vectype,
5999                         string asm, string kind>
6000   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6001       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
6002     Sched<[WriteV]> {
6003   bits<5> Rd;
6004   bits<5> Rn;
6005   let Inst{31-30} = 0b01;
6006   let Inst{29}    = U;
6007   let Inst{28-24} = 0b11110;
6008   let Inst{23-22} = size;
6009   let Inst{21-17} = 0b11000;
6010   let Inst{16-12} = opcode;
6011   let Inst{11-10} = 0b10;
6012   let Inst{9-5}   = Rn;
6013   let Inst{4-0}   = Rd;
6014 }
6015
6016 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6017   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6018                                       asm, ".2d">;
6019 }
6020
6021 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6022   let Predicates = [HasNEON, HasFullFP16] in {
6023   def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6024                                       asm, ".2h">;
6025   }
6026   def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
6027                                       asm, ".2s">;
6028   def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
6029                                       asm, ".2d">;
6030 }
6031
6032 //----------------------------------------------------------------------------
6033 // AdvSIMD across lanes instructions
6034 //----------------------------------------------------------------------------
6035
6036 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6037 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6038                           RegisterClass regtype, RegisterOperand vectype,
6039                           string asm, string kind, list<dag> pattern>
6040   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6041       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6042     Sched<[WriteV]> {
6043   bits<5> Rd;
6044   bits<5> Rn;
6045   let Inst{31}    = 0;
6046   let Inst{30}    = Q;
6047   let Inst{29}    = U;
6048   let Inst{28-24} = 0b01110;
6049   let Inst{23-22} = size;
6050   let Inst{21-17} = 0b11000;
6051   let Inst{16-12} = opcode;
6052   let Inst{11-10} = 0b10;
6053   let Inst{9-5}   = Rn;
6054   let Inst{4-0}   = Rd;
6055 }
6056
6057 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6058                               string asm> {
6059   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
6060                                    asm, ".8b", []>;
6061   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
6062                                    asm, ".16b", []>;
6063   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6064                                    asm, ".4h", []>;
6065   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6066                                    asm, ".8h", []>;
6067   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6068                                    asm, ".4s", []>;
6069 }
6070
6071 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6072   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6073                                    asm, ".8b", []>;
6074   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6075                                    asm, ".16b", []>;
6076   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6077                                    asm, ".4h", []>;
6078   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6079                                    asm, ".8h", []>;
6080   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6081                                    asm, ".4s", []>;
6082 }
6083
6084 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
6085                             Intrinsic intOp> {
6086   let Predicates = [HasNEON, HasFullFP16] in {
6087   def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6088                                    asm, ".4h",
6089         [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6090   def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6091                                    asm, ".8h",
6092         [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6093   } // Predicates = [HasNEON, HasFullFP16]
6094   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6095                                    asm, ".4s",
6096         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6097 }
6098
6099 //----------------------------------------------------------------------------
6100 // AdvSIMD INS/DUP instructions
6101 //----------------------------------------------------------------------------
6102
6103 // FIXME: There has got to be a better way to factor these. ugh.
6104
6105 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6106                      string operands, string constraints, list<dag> pattern>
6107   : I<outs, ins, asm, operands, constraints, pattern>,
6108     Sched<[WriteV]> {
6109   bits<5> Rd;
6110   bits<5> Rn;
6111   let Inst{31} = 0;
6112   let Inst{30} = Q;
6113   let Inst{29} = op;
6114   let Inst{28-21} = 0b01110000;
6115   let Inst{15} = 0;
6116   let Inst{10} = 1;
6117   let Inst{9-5} = Rn;
6118   let Inst{4-0} = Rd;
6119 }
6120
6121 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6122                       RegisterOperand vecreg, RegisterClass regtype>
6123   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6124                    "{\t$Rd" # size # ", $Rn" #
6125                    "|" # size # "\t$Rd, $Rn}", "",
6126                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6127   let Inst{20-16} = imm5;
6128   let Inst{14-11} = 0b0001;
6129 }
6130
6131 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6132                          ValueType vectype, ValueType insreg,
6133                          RegisterOperand vecreg, Operand idxtype,
6134                          ValueType elttype, SDNode OpNode>
6135   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6136                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6137                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6138                  [(set (vectype vecreg:$Rd),
6139                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6140   let Inst{14-11} = 0b0000;
6141 }
6142
6143 class SIMDDup64FromElement
6144   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6145                        VectorIndexD, i64, AArch64duplane64> {
6146   bits<1> idx;
6147   let Inst{20} = idx;
6148   let Inst{19-16} = 0b1000;
6149 }
6150
6151 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6152                            RegisterOperand vecreg>
6153   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6154                        VectorIndexS, i64, AArch64duplane32> {
6155   bits<2> idx;
6156   let Inst{20-19} = idx;
6157   let Inst{18-16} = 0b100;
6158 }
6159
6160 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6161                            RegisterOperand vecreg>
6162   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6163                        VectorIndexH, i64, AArch64duplane16> {
6164   bits<3> idx;
6165   let Inst{20-18} = idx;
6166   let Inst{17-16} = 0b10;
6167 }
6168
6169 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6170                           RegisterOperand vecreg>
6171   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6172                        VectorIndexB, i64, AArch64duplane8> {
6173   bits<4> idx;
6174   let Inst{20-17} = idx;
6175   let Inst{16} = 1;
6176 }
6177
6178 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6179                   Operand idxtype, string asm, list<dag> pattern>
6180   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6181                    "{\t$Rd, $Rn" # size # "$idx" #
6182                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6183   let Inst{14-11} = imm4;
6184 }
6185
6186 class SIMDSMov<bit Q, string size, RegisterClass regtype,
6187                Operand idxtype>
6188   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6189 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6190                Operand idxtype>
6191   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6192       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6193
6194 class SIMDMovAlias<string asm, string size, Instruction inst,
6195                    RegisterClass regtype, Operand idxtype>
6196     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6197                     "|" # size # "\t$dst, $src$idx}",
6198                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6199
6200 multiclass SMov {
6201   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6202     bits<4> idx;
6203     let Inst{20-17} = idx;
6204     let Inst{16} = 1;
6205   }
6206   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6207     bits<4> idx;
6208     let Inst{20-17} = idx;
6209     let Inst{16} = 1;
6210   }
6211   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6212     bits<3> idx;
6213     let Inst{20-18} = idx;
6214     let Inst{17-16} = 0b10;
6215   }
6216   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6217     bits<3> idx;
6218     let Inst{20-18} = idx;
6219     let Inst{17-16} = 0b10;
6220   }
6221   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6222     bits<2> idx;
6223     let Inst{20-19} = idx;
6224     let Inst{18-16} = 0b100;
6225   }
6226 }
6227
6228 multiclass UMov {
6229   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6230     bits<4> idx;
6231     let Inst{20-17} = idx;
6232     let Inst{16} = 1;
6233   }
6234   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6235     bits<3> idx;
6236     let Inst{20-18} = idx;
6237     let Inst{17-16} = 0b10;
6238   }
6239   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6240     bits<2> idx;
6241     let Inst{20-19} = idx;
6242     let Inst{18-16} = 0b100;
6243   }
6244   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6245     bits<1> idx;
6246     let Inst{20} = idx;
6247     let Inst{19-16} = 0b1000;
6248   }
6249   def : SIMDMovAlias<"mov", ".s",
6250                      !cast<Instruction>(NAME#"vi32"),
6251                      GPR32, VectorIndexS>;
6252   def : SIMDMovAlias<"mov", ".d",
6253                      !cast<Instruction>(NAME#"vi64"),
6254                      GPR64, VectorIndexD>;
6255 }
6256
6257 class SIMDInsFromMain<string size, ValueType vectype,
6258                       RegisterClass regtype, Operand idxtype>
6259   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6260                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6261                    "{\t$Rd" # size # "$idx, $Rn" #
6262                    "|" # size # "\t$Rd$idx, $Rn}",
6263                    "$Rd = $dst",
6264             [(set V128:$dst,
6265               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6266   let Inst{14-11} = 0b0011;
6267 }
6268
6269 class SIMDInsFromElement<string size, ValueType vectype,
6270                          ValueType elttype, Operand idxtype>
6271   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6272                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6273                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6274                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
6275                    "$Rd = $dst",
6276          [(set V128:$dst,
6277                (vector_insert
6278                  (vectype V128:$Rd),
6279                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6280                  idxtype:$idx))]>;
6281
6282 class SIMDInsMainMovAlias<string size, Instruction inst,
6283                           RegisterClass regtype, Operand idxtype>
6284     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6285                         "|" # size #"\t$dst$idx, $src}",
6286                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6287 class SIMDInsElementMovAlias<string size, Instruction inst,
6288                              Operand idxtype>
6289     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
6290                       # "|" # size #"\t$dst$idx, $src$idx2}",
6291                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6292
6293
6294 multiclass SIMDIns {
6295   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6296     bits<4> idx;
6297     let Inst{20-17} = idx;
6298     let Inst{16} = 1;
6299   }
6300   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6301     bits<3> idx;
6302     let Inst{20-18} = idx;
6303     let Inst{17-16} = 0b10;
6304   }
6305   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6306     bits<2> idx;
6307     let Inst{20-19} = idx;
6308     let Inst{18-16} = 0b100;
6309   }
6310   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6311     bits<1> idx;
6312     let Inst{20} = idx;
6313     let Inst{19-16} = 0b1000;
6314   }
6315
6316   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6317     bits<4> idx;
6318     bits<4> idx2;
6319     let Inst{20-17} = idx;
6320     let Inst{16} = 1;
6321     let Inst{14-11} = idx2;
6322   }
6323   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6324     bits<3> idx;
6325     bits<3> idx2;
6326     let Inst{20-18} = idx;
6327     let Inst{17-16} = 0b10;
6328     let Inst{14-12} = idx2;
6329     let Inst{11} = {?};
6330   }
6331   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6332     bits<2> idx;
6333     bits<2> idx2;
6334     let Inst{20-19} = idx;
6335     let Inst{18-16} = 0b100;
6336     let Inst{14-13} = idx2;
6337     let Inst{12-11} = {?,?};
6338   }
6339   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6340     bits<1> idx;
6341     bits<1> idx2;
6342     let Inst{20} = idx;
6343     let Inst{19-16} = 0b1000;
6344     let Inst{14} = idx2;
6345     let Inst{13-11} = {?,?,?};
6346   }
6347
6348   // For all forms of the INS instruction, the "mov" mnemonic is the
6349   // preferred alias. Why they didn't just call the instruction "mov" in
6350   // the first place is a very good question indeed...
6351   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6352                          GPR32, VectorIndexB>;
6353   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6354                          GPR32, VectorIndexH>;
6355   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6356                          GPR32, VectorIndexS>;
6357   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6358                          GPR64, VectorIndexD>;
6359
6360   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6361                          VectorIndexB>;
6362   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6363                          VectorIndexH>;
6364   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6365                          VectorIndexS>;
6366   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6367                          VectorIndexD>;
6368 }
6369
6370 //----------------------------------------------------------------------------
6371 // AdvSIMD TBL/TBX
6372 //----------------------------------------------------------------------------
6373
6374 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6375 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6376                           RegisterOperand listtype, string asm, string kind>
6377   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6378        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6379     Sched<[WriteV]> {
6380   bits<5> Vd;
6381   bits<5> Vn;
6382   bits<5> Vm;
6383   let Inst{31}    = 0;
6384   let Inst{30}    = Q;
6385   let Inst{29-21} = 0b001110000;
6386   let Inst{20-16} = Vm;
6387   let Inst{15}    = 0;
6388   let Inst{14-13} = len;
6389   let Inst{12}    = op;
6390   let Inst{11-10} = 0b00;
6391   let Inst{9-5}   = Vn;
6392   let Inst{4-0}   = Vd;
6393 }
6394
6395 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6396 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6397                           RegisterOperand listtype, string asm, string kind>
6398   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6399        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6400     Sched<[WriteV]> {
6401   bits<5> Vd;
6402   bits<5> Vn;
6403   bits<5> Vm;
6404   let Inst{31}    = 0;
6405   let Inst{30}    = Q;
6406   let Inst{29-21} = 0b001110000;
6407   let Inst{20-16} = Vm;
6408   let Inst{15}    = 0;
6409   let Inst{14-13} = len;
6410   let Inst{12}    = op;
6411   let Inst{11-10} = 0b00;
6412   let Inst{9-5}   = Vn;
6413   let Inst{4-0}   = Vd;
6414 }
6415
6416 class SIMDTableLookupAlias<string asm, Instruction inst,
6417                           RegisterOperand vectype, RegisterOperand listtype>
6418     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6419                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6420
6421 multiclass SIMDTableLookup<bit op, string asm> {
6422   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6423                                       asm, ".8b">;
6424   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6425                                       asm, ".8b">;
6426   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6427                                       asm, ".8b">;
6428   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6429                                       asm, ".8b">;
6430   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6431                                       asm, ".16b">;
6432   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6433                                       asm, ".16b">;
6434   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6435                                       asm, ".16b">;
6436   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6437                                       asm, ".16b">;
6438
6439   def : SIMDTableLookupAlias<asm # ".8b",
6440                          !cast<Instruction>(NAME#"v8i8One"),
6441                          V64, VecListOne128>;
6442   def : SIMDTableLookupAlias<asm # ".8b",
6443                          !cast<Instruction>(NAME#"v8i8Two"),
6444                          V64, VecListTwo128>;
6445   def : SIMDTableLookupAlias<asm # ".8b",
6446                          !cast<Instruction>(NAME#"v8i8Three"),
6447                          V64, VecListThree128>;
6448   def : SIMDTableLookupAlias<asm # ".8b",
6449                          !cast<Instruction>(NAME#"v8i8Four"),
6450                          V64, VecListFour128>;
6451   def : SIMDTableLookupAlias<asm # ".16b",
6452                          !cast<Instruction>(NAME#"v16i8One"),
6453                          V128, VecListOne128>;
6454   def : SIMDTableLookupAlias<asm # ".16b",
6455                          !cast<Instruction>(NAME#"v16i8Two"),
6456                          V128, VecListTwo128>;
6457   def : SIMDTableLookupAlias<asm # ".16b",
6458                          !cast<Instruction>(NAME#"v16i8Three"),
6459                          V128, VecListThree128>;
6460   def : SIMDTableLookupAlias<asm # ".16b",
6461                          !cast<Instruction>(NAME#"v16i8Four"),
6462                          V128, VecListFour128>;
6463 }
6464
6465 multiclass SIMDTableLookupTied<bit op, string asm> {
6466   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6467                                       asm, ".8b">;
6468   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6469                                       asm, ".8b">;
6470   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6471                                       asm, ".8b">;
6472   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6473                                       asm, ".8b">;
6474   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6475                                       asm, ".16b">;
6476   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6477                                       asm, ".16b">;
6478   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6479                                       asm, ".16b">;
6480   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6481                                       asm, ".16b">;
6482
6483   def : SIMDTableLookupAlias<asm # ".8b",
6484                          !cast<Instruction>(NAME#"v8i8One"),
6485                          V64, VecListOne128>;
6486   def : SIMDTableLookupAlias<asm # ".8b",
6487                          !cast<Instruction>(NAME#"v8i8Two"),
6488                          V64, VecListTwo128>;
6489   def : SIMDTableLookupAlias<asm # ".8b",
6490                          !cast<Instruction>(NAME#"v8i8Three"),
6491                          V64, VecListThree128>;
6492   def : SIMDTableLookupAlias<asm # ".8b",
6493                          !cast<Instruction>(NAME#"v8i8Four"),
6494                          V64, VecListFour128>;
6495   def : SIMDTableLookupAlias<asm # ".16b",
6496                          !cast<Instruction>(NAME#"v16i8One"),
6497                          V128, VecListOne128>;
6498   def : SIMDTableLookupAlias<asm # ".16b",
6499                          !cast<Instruction>(NAME#"v16i8Two"),
6500                          V128, VecListTwo128>;
6501   def : SIMDTableLookupAlias<asm # ".16b",
6502                          !cast<Instruction>(NAME#"v16i8Three"),
6503                          V128, VecListThree128>;
6504   def : SIMDTableLookupAlias<asm # ".16b",
6505                          !cast<Instruction>(NAME#"v16i8Four"),
6506                          V128, VecListFour128>;
6507 }
6508
6509
6510 //----------------------------------------------------------------------------
6511 // AdvSIMD scalar CPY
6512 //----------------------------------------------------------------------------
6513 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6514 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6515                         string kind, Operand idxtype>
6516   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6517        "{\t$dst, $src" # kind # "$idx" #
6518        "|\t$dst, $src$idx}", "", []>,
6519     Sched<[WriteV]> {
6520   bits<5> dst;
6521   bits<5> src;
6522   let Inst{31-21} = 0b01011110000;
6523   let Inst{15-10} = 0b000001;
6524   let Inst{9-5}   = src;
6525   let Inst{4-0}   = dst;
6526 }
6527
6528 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6529       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6530     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6531                     # "|\t$dst, $src$index}",
6532                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6533
6534
6535 multiclass SIMDScalarCPY<string asm> {
6536   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
6537     bits<4> idx;
6538     let Inst{20-17} = idx;
6539     let Inst{16} = 1;
6540   }
6541   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6542     bits<3> idx;
6543     let Inst{20-18} = idx;
6544     let Inst{17-16} = 0b10;
6545   }
6546   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6547     bits<2> idx;
6548     let Inst{20-19} = idx;
6549     let Inst{18-16} = 0b100;
6550   }
6551   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6552     bits<1> idx;
6553     let Inst{20} = idx;
6554     let Inst{19-16} = 0b1000;
6555   }
6556
6557   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6558                                                           VectorIndexD:$idx)))),
6559             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6560
6561   // 'DUP' mnemonic aliases.
6562   def : SIMDScalarCPYAlias<"dup", ".b",
6563                            !cast<Instruction>(NAME#"i8"),
6564                            FPR8, V128, VectorIndexB>;
6565   def : SIMDScalarCPYAlias<"dup", ".h",
6566                            !cast<Instruction>(NAME#"i16"),
6567                            FPR16, V128, VectorIndexH>;
6568   def : SIMDScalarCPYAlias<"dup", ".s",
6569                            !cast<Instruction>(NAME#"i32"),
6570                            FPR32, V128, VectorIndexS>;
6571   def : SIMDScalarCPYAlias<"dup", ".d",
6572                            !cast<Instruction>(NAME#"i64"),
6573                            FPR64, V128, VectorIndexD>;
6574 }
6575
6576 //----------------------------------------------------------------------------
6577 // AdvSIMD modified immediate instructions
6578 //----------------------------------------------------------------------------
6579
6580 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
6581                           string asm, string op_string,
6582                           string cstr, list<dag> pattern>
6583   : I<oops, iops, asm, op_string, cstr, pattern>,
6584     Sched<[WriteV]> {
6585   bits<5> Rd;
6586   bits<8> imm8;
6587   let Inst{31}    = 0;
6588   let Inst{30}    = Q;
6589   let Inst{29}    = op;
6590   let Inst{28-19} = 0b0111100000;
6591   let Inst{18-16} = imm8{7-5};
6592   let Inst{11} = op2;
6593   let Inst{10} = 1;
6594   let Inst{9-5}   = imm8{4-0};
6595   let Inst{4-0}   = Rd;
6596 }
6597
6598 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
6599                                 Operand immtype, dag opt_shift_iop,
6600                                 string opt_shift, string asm, string kind,
6601                                 list<dag> pattern>
6602   : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
6603                         !con((ins immtype:$imm8), opt_shift_iop), asm,
6604                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
6605                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6606                         "", pattern> {
6607   let DecoderMethod = "DecodeModImmInstruction";
6608 }
6609
6610 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6611                                 Operand immtype, dag opt_shift_iop,
6612                                 string opt_shift, string asm, string kind,
6613                                 list<dag> pattern>
6614   : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
6615                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6616                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6617                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6618                         "$Rd = $dst", pattern> {
6619   let DecoderMethod = "DecodeModImmTiedInstruction";
6620 }
6621
6622 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6623                                      RegisterOperand vectype, string asm,
6624                                      string kind, list<dag> pattern>
6625   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6626                               (ins logical_vec_shift:$shift),
6627                               "$shift", asm, kind, pattern> {
6628   bits<2> shift;
6629   let Inst{15}    = b15_b12{1};
6630   let Inst{14-13} = shift;
6631   let Inst{12}    = b15_b12{0};
6632 }
6633
6634 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6635                                      RegisterOperand vectype, string asm,
6636                                      string kind, list<dag> pattern>
6637   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6638                               (ins logical_vec_shift:$shift),
6639                               "$shift", asm, kind, pattern> {
6640   bits<2> shift;
6641   let Inst{15}    = b15_b12{1};
6642   let Inst{14-13} = shift;
6643   let Inst{12}    = b15_b12{0};
6644 }
6645
6646
6647 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6648                                          RegisterOperand vectype, string asm,
6649                                          string kind, list<dag> pattern>
6650   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6651                               (ins logical_vec_hw_shift:$shift),
6652                               "$shift", asm, kind, pattern> {
6653   bits<2> shift;
6654   let Inst{15} = b15_b12{1};
6655   let Inst{14} = 0;
6656   let Inst{13} = shift{0};
6657   let Inst{12} = b15_b12{0};
6658 }
6659
6660 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6661                                          RegisterOperand vectype, string asm,
6662                                          string kind, list<dag> pattern>
6663   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6664                               (ins logical_vec_hw_shift:$shift),
6665                               "$shift", asm, kind, pattern> {
6666   bits<2> shift;
6667   let Inst{15} = b15_b12{1};
6668   let Inst{14} = 0;
6669   let Inst{13} = shift{0};
6670   let Inst{12} = b15_b12{0};
6671 }
6672
6673 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6674                                       string asm> {
6675   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6676                                                  asm, ".4h", []>;
6677   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6678                                                  asm, ".8h", []>;
6679
6680   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6681                                              asm, ".2s", []>;
6682   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6683                                              asm, ".4s", []>;
6684 }
6685
6686 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6687                                       bits<2> w_cmode, string asm,
6688                                       SDNode OpNode> {
6689   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6690                                                  asm, ".4h",
6691              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6692                                              imm0_255:$imm8,
6693                                              (i32 imm:$shift)))]>;
6694   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6695                                                  asm, ".8h",
6696              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6697                                               imm0_255:$imm8,
6698                                               (i32 imm:$shift)))]>;
6699
6700   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6701                                              asm, ".2s",
6702              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6703                                              imm0_255:$imm8,
6704                                              (i32 imm:$shift)))]>;
6705   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6706                                              asm, ".4s",
6707              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6708                                               imm0_255:$imm8,
6709                                               (i32 imm:$shift)))]>;
6710 }
6711
6712 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6713                              RegisterOperand vectype, string asm,
6714                              string kind, list<dag> pattern>
6715   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6716                               (ins move_vec_shift:$shift),
6717                               "$shift", asm, kind, pattern> {
6718   bits<1> shift;
6719   let Inst{15-13} = cmode{3-1};
6720   let Inst{12}    = shift;
6721 }
6722
6723 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
6724                                    RegisterOperand vectype,
6725                                    Operand imm_type, string asm,
6726                                    string kind, list<dag> pattern>
6727   : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
6728                               asm, kind, pattern> {
6729   let Inst{15-12} = cmode;
6730 }
6731
6732 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6733                                    list<dag> pattern>
6734   : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6735                         "\t$Rd, $imm8", "", pattern> {
6736   let Inst{15-12} = cmode;
6737   let DecoderMethod = "DecodeModImmInstruction";
6738 }
6739
6740 //----------------------------------------------------------------------------
6741 // AdvSIMD indexed element
6742 //----------------------------------------------------------------------------
6743
6744 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6745 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6746                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6747                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6748                       string apple_kind, string dst_kind, string lhs_kind,
6749                       string rhs_kind, list<dag> pattern>
6750   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6751       asm,
6752       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6753       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6754     Sched<[WriteV]> {
6755   bits<5> Rd;
6756   bits<5> Rn;
6757   bits<5> Rm;
6758
6759   let Inst{31}    = 0;
6760   let Inst{30}    = Q;
6761   let Inst{29}    = U;
6762   let Inst{28}    = Scalar;
6763   let Inst{27-24} = 0b1111;
6764   let Inst{23-22} = size;
6765   // Bit 21 must be set by the derived class.
6766   let Inst{20-16} = Rm;
6767   let Inst{15-12} = opc;
6768   // Bit 11 must be set by the derived class.
6769   let Inst{10}    = 0;
6770   let Inst{9-5}   = Rn;
6771   let Inst{4-0}   = Rd;
6772 }
6773
6774 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6775 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6776                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6777                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6778                       string apple_kind, string dst_kind, string lhs_kind,
6779                       string rhs_kind, list<dag> pattern>
6780   : I<(outs dst_reg:$dst),
6781       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6782       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6783       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6784     Sched<[WriteV]> {
6785   bits<5> Rd;
6786   bits<5> Rn;
6787   bits<5> Rm;
6788
6789   let Inst{31}    = 0;
6790   let Inst{30}    = Q;
6791   let Inst{29}    = U;
6792   let Inst{28}    = Scalar;
6793   let Inst{27-24} = 0b1111;
6794   let Inst{23-22} = size;
6795   // Bit 21 must be set by the derived class.
6796   let Inst{20-16} = Rm;
6797   let Inst{15-12} = opc;
6798   // Bit 11 must be set by the derived class.
6799   let Inst{10}    = 0;
6800   let Inst{9-5}   = Rn;
6801   let Inst{4-0}   = Rd;
6802 }
6803
6804 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
6805                          SDPatternOperator OpNode> {
6806   let Predicates = [HasNEON, HasFullFP16] in {
6807   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
6808                                       V64, V64,
6809                                       V128_lo, VectorIndexH,
6810                                       asm, ".4h", ".4h", ".4h", ".h",
6811     [(set (v4f16 V64:$Rd),
6812         (OpNode (v4f16 V64:$Rn),
6813          (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6814     bits<3> idx;
6815     let Inst{11} = idx{2};
6816     let Inst{21} = idx{1};
6817     let Inst{20} = idx{0};
6818   }
6819
6820   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
6821                                       V128, V128,
6822                                       V128_lo, VectorIndexH,
6823                                       asm, ".8h", ".8h", ".8h", ".h",
6824     [(set (v8f16 V128:$Rd),
6825         (OpNode (v8f16 V128:$Rn),
6826          (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6827     bits<3> idx;
6828     let Inst{11} = idx{2};
6829     let Inst{21} = idx{1};
6830     let Inst{20} = idx{0};
6831   }
6832   } // Predicates = [HasNEON, HasFullFP16]
6833
6834   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6835                                       V64, V64,
6836                                       V128, VectorIndexS,
6837                                       asm, ".2s", ".2s", ".2s", ".s",
6838     [(set (v2f32 V64:$Rd),
6839         (OpNode (v2f32 V64:$Rn),
6840          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6841     bits<2> idx;
6842     let Inst{11} = idx{1};
6843     let Inst{21} = idx{0};
6844   }
6845
6846   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6847                                       V128, V128,
6848                                       V128, VectorIndexS,
6849                                       asm, ".4s", ".4s", ".4s", ".s",
6850     [(set (v4f32 V128:$Rd),
6851         (OpNode (v4f32 V128:$Rn),
6852          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6853     bits<2> idx;
6854     let Inst{11} = idx{1};
6855     let Inst{21} = idx{0};
6856   }
6857
6858   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6859                                       V128, V128,
6860                                       V128, VectorIndexD,
6861                                       asm, ".2d", ".2d", ".2d", ".d",
6862     [(set (v2f64 V128:$Rd),
6863         (OpNode (v2f64 V128:$Rn),
6864          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6865     bits<1> idx;
6866     let Inst{11} = idx{0};
6867     let Inst{21} = 0;
6868   }
6869
6870   let Predicates = [HasNEON, HasFullFP16] in {
6871   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
6872                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6873                                       asm, ".h", "", "", ".h",
6874     [(set (f16 FPR16Op:$Rd),
6875           (OpNode (f16 FPR16Op:$Rn),
6876                   (f16 (vector_extract (v8f16 V128_lo:$Rm),
6877                                        VectorIndexH:$idx))))]> {
6878     bits<3> idx;
6879     let Inst{11} = idx{2};
6880     let Inst{21} = idx{1};
6881     let Inst{20} = idx{0};
6882   }
6883   } // Predicates = [HasNEON, HasFullFP16]
6884
6885   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6886                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6887                                       asm, ".s", "", "", ".s",
6888     [(set (f32 FPR32Op:$Rd),
6889           (OpNode (f32 FPR32Op:$Rn),
6890                   (f32 (vector_extract (v4f32 V128:$Rm),
6891                                        VectorIndexS:$idx))))]> {
6892     bits<2> idx;
6893     let Inst{11} = idx{1};
6894     let Inst{21} = idx{0};
6895   }
6896
6897   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6898                                       FPR64Op, FPR64Op, V128, VectorIndexD,
6899                                       asm, ".d", "", "", ".d",
6900     [(set (f64 FPR64Op:$Rd),
6901           (OpNode (f64 FPR64Op:$Rn),
6902                   (f64 (vector_extract (v2f64 V128:$Rm),
6903                                        VectorIndexD:$idx))))]> {
6904     bits<1> idx;
6905     let Inst{11} = idx{0};
6906     let Inst{21} = 0;
6907   }
6908 }
6909
6910 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
6911   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6912   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6913                            (AArch64duplane32 (v4f32 V128:$Rm),
6914                                            VectorIndexS:$idx))),
6915             (!cast<Instruction>(INST # v2i32_indexed)
6916                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6917   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6918                            (AArch64dup (f32 FPR32Op:$Rm)))),
6919             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6920                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6921
6922
6923   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6924   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6925                            (AArch64duplane32 (v4f32 V128:$Rm),
6926                                            VectorIndexS:$idx))),
6927             (!cast<Instruction>(INST # "v4i32_indexed")
6928                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6929   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6930                            (AArch64dup (f32 FPR32Op:$Rm)))),
6931             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6932                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6933
6934   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6935   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6936                            (AArch64duplane64 (v2f64 V128:$Rm),
6937                                            VectorIndexD:$idx))),
6938             (!cast<Instruction>(INST # "v2i64_indexed")
6939                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6940   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6941                            (AArch64dup (f64 FPR64Op:$Rm)))),
6942             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6943                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6944
6945   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6946   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6947                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6948             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6949                 V128:$Rm, VectorIndexS:$idx)>;
6950   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6951                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6952             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6953                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6954
6955   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6956   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6957                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6958             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6959                 V128:$Rm, VectorIndexD:$idx)>;
6960 }
6961
6962 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
6963   let Predicates = [HasNEON, HasFullFP16] in {
6964   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
6965                                           V128_lo, VectorIndexH,
6966                                           asm, ".4h", ".4h", ".4h", ".h", []> {
6967     bits<3> idx;
6968     let Inst{11} = idx{2};
6969     let Inst{21} = idx{1};
6970     let Inst{20} = idx{0};
6971   }
6972
6973   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
6974                                           V128, V128,
6975                                           V128_lo, VectorIndexH,
6976                                           asm, ".8h", ".8h", ".8h", ".h", []> {
6977     bits<3> idx;
6978     let Inst{11} = idx{2};
6979     let Inst{21} = idx{1};
6980     let Inst{20} = idx{0};
6981   }
6982   } // Predicates = [HasNEON, HasFullFP16]
6983
6984   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6985                                           V128, VectorIndexS,
6986                                           asm, ".2s", ".2s", ".2s", ".s", []> {
6987     bits<2> idx;
6988     let Inst{11} = idx{1};
6989     let Inst{21} = idx{0};
6990   }
6991
6992   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6993                                       V128, V128,
6994                                       V128, VectorIndexS,
6995                                       asm, ".4s", ".4s", ".4s", ".s", []> {
6996     bits<2> idx;
6997     let Inst{11} = idx{1};
6998     let Inst{21} = idx{0};
6999   }
7000
7001   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
7002                                       V128, V128,
7003                                       V128, VectorIndexD,
7004                                       asm, ".2d", ".2d", ".2d", ".d", []> {
7005     bits<1> idx;
7006     let Inst{11} = idx{0};
7007     let Inst{21} = 0;
7008   }
7009
7010   let Predicates = [HasNEON, HasFullFP16] in {
7011   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
7012                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7013                                       asm, ".h", "", "", ".h", []> {
7014     bits<3> idx;
7015     let Inst{11} = idx{2};
7016     let Inst{21} = idx{1};
7017     let Inst{20} = idx{0};
7018   }
7019   } // Predicates = [HasNEON, HasFullFP16]
7020
7021   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7022                                       FPR32Op, FPR32Op, V128, VectorIndexS,
7023                                       asm, ".s", "", "", ".s", []> {
7024     bits<2> idx;
7025     let Inst{11} = idx{1};
7026     let Inst{21} = idx{0};
7027   }
7028
7029   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7030                                       FPR64Op, FPR64Op, V128, VectorIndexD,
7031                                       asm, ".d", "", "", ".d", []> {
7032     bits<1> idx;
7033     let Inst{11} = idx{0};
7034     let Inst{21} = 0;
7035   }
7036 }
7037
7038 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7039                          SDPatternOperator OpNode> {
7040   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7041                                       V128_lo, VectorIndexH,
7042                                       asm, ".4h", ".4h", ".4h", ".h",
7043     [(set (v4i16 V64:$Rd),
7044         (OpNode (v4i16 V64:$Rn),
7045          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7046     bits<3> idx;
7047     let Inst{11} = idx{2};
7048     let Inst{21} = idx{1};
7049     let Inst{20} = idx{0};
7050   }
7051
7052   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7053                                       V128, V128,
7054                                       V128_lo, VectorIndexH,
7055                                       asm, ".8h", ".8h", ".8h", ".h",
7056     [(set (v8i16 V128:$Rd),
7057        (OpNode (v8i16 V128:$Rn),
7058          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7059     bits<3> idx;
7060     let Inst{11} = idx{2};
7061     let Inst{21} = idx{1};
7062     let Inst{20} = idx{0};
7063   }
7064
7065   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7066                                       V64, V64,
7067                                       V128, VectorIndexS,
7068                                       asm, ".2s", ".2s", ".2s",  ".s",
7069     [(set (v2i32 V64:$Rd),
7070        (OpNode (v2i32 V64:$Rn),
7071           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7072     bits<2> idx;
7073     let Inst{11} = idx{1};
7074     let Inst{21} = idx{0};
7075   }
7076
7077   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7078                                       V128, V128,
7079                                       V128, VectorIndexS,
7080                                       asm, ".4s", ".4s", ".4s", ".s",
7081     [(set (v4i32 V128:$Rd),
7082        (OpNode (v4i32 V128:$Rn),
7083           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7084     bits<2> idx;
7085     let Inst{11} = idx{1};
7086     let Inst{21} = idx{0};
7087   }
7088
7089   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7090                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7091                                       asm, ".h", "", "", ".h", []> {
7092     bits<3> idx;
7093     let Inst{11} = idx{2};
7094     let Inst{21} = idx{1};
7095     let Inst{20} = idx{0};
7096   }
7097
7098   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7099                                       FPR32Op, FPR32Op, V128, VectorIndexS,
7100                                       asm, ".s", "", "", ".s",
7101       [(set (i32 FPR32Op:$Rd),
7102             (OpNode FPR32Op:$Rn,
7103                     (i32 (vector_extract (v4i32 V128:$Rm),
7104                                          VectorIndexS:$idx))))]> {
7105     bits<2> idx;
7106     let Inst{11} = idx{1};
7107     let Inst{21} = idx{0};
7108   }
7109 }
7110
7111 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
7112                                SDPatternOperator OpNode> {
7113   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7114                                       V64, V64,
7115                                       V128_lo, VectorIndexH,
7116                                       asm, ".4h", ".4h", ".4h", ".h",
7117     [(set (v4i16 V64:$Rd),
7118         (OpNode (v4i16 V64:$Rn),
7119          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7120     bits<3> idx;
7121     let Inst{11} = idx{2};
7122     let Inst{21} = idx{1};
7123     let Inst{20} = idx{0};
7124   }
7125
7126   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7127                                       V128, V128,
7128                                       V128_lo, VectorIndexH,
7129                                       asm, ".8h", ".8h", ".8h", ".h",
7130     [(set (v8i16 V128:$Rd),
7131        (OpNode (v8i16 V128:$Rn),
7132          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7133     bits<3> idx;
7134     let Inst{11} = idx{2};
7135     let Inst{21} = idx{1};
7136     let Inst{20} = idx{0};
7137   }
7138
7139   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7140                                       V64, V64,
7141                                       V128, VectorIndexS,
7142                                       asm, ".2s", ".2s", ".2s", ".s",
7143     [(set (v2i32 V64:$Rd),
7144        (OpNode (v2i32 V64:$Rn),
7145           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7146     bits<2> idx;
7147     let Inst{11} = idx{1};
7148     let Inst{21} = idx{0};
7149   }
7150
7151   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7152                                       V128, V128,
7153                                       V128, VectorIndexS,
7154                                       asm, ".4s", ".4s", ".4s", ".s",
7155     [(set (v4i32 V128:$Rd),
7156        (OpNode (v4i32 V128:$Rn),
7157           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7158     bits<2> idx;
7159     let Inst{11} = idx{1};
7160     let Inst{21} = idx{0};
7161   }
7162 }
7163
7164 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
7165                                    SDPatternOperator OpNode> {
7166   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
7167                                           V128_lo, VectorIndexH,
7168                                           asm, ".4h", ".4h", ".4h", ".h",
7169     [(set (v4i16 V64:$dst),
7170         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
7171          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7172     bits<3> idx;
7173     let Inst{11} = idx{2};
7174     let Inst{21} = idx{1};
7175     let Inst{20} = idx{0};
7176   }
7177
7178   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7179                                       V128, V128,
7180                                       V128_lo, VectorIndexH,
7181                                       asm, ".8h", ".8h", ".8h", ".h",
7182     [(set (v8i16 V128:$dst),
7183        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7184          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7185     bits<3> idx;
7186     let Inst{11} = idx{2};
7187     let Inst{21} = idx{1};
7188     let Inst{20} = idx{0};
7189   }
7190
7191   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7192                                       V64, V64,
7193                                       V128, VectorIndexS,
7194                                       asm, ".2s", ".2s", ".2s", ".s",
7195     [(set (v2i32 V64:$dst),
7196        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7197           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7198     bits<2> idx;
7199     let Inst{11} = idx{1};
7200     let Inst{21} = idx{0};
7201   }
7202
7203   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7204                                       V128, V128,
7205                                       V128, VectorIndexS,
7206                                       asm, ".4s", ".4s", ".4s", ".s",
7207     [(set (v4i32 V128:$dst),
7208        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7209           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7210     bits<2> idx;
7211     let Inst{11} = idx{1};
7212     let Inst{21} = idx{0};
7213   }
7214 }
7215
7216 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
7217                              SDPatternOperator OpNode> {
7218   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7219                                       V128, V64,
7220                                       V128_lo, VectorIndexH,
7221                                       asm, ".4s", ".4s", ".4h", ".h",
7222     [(set (v4i32 V128:$Rd),
7223         (OpNode (v4i16 V64:$Rn),
7224          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7225     bits<3> idx;
7226     let Inst{11} = idx{2};
7227     let Inst{21} = idx{1};
7228     let Inst{20} = idx{0};
7229   }
7230
7231   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7232                                       V128, V128,
7233                                       V128_lo, VectorIndexH,
7234                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7235     [(set (v4i32 V128:$Rd),
7236           (OpNode (extract_high_v8i16 V128:$Rn),
7237                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7238                                                       VectorIndexH:$idx))))]> {
7239
7240     bits<3> idx;
7241     let Inst{11} = idx{2};
7242     let Inst{21} = idx{1};
7243     let Inst{20} = idx{0};
7244   }
7245
7246   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7247                                       V128, V64,
7248                                       V128, VectorIndexS,
7249                                       asm, ".2d", ".2d", ".2s", ".s",
7250     [(set (v2i64 V128:$Rd),
7251         (OpNode (v2i32 V64:$Rn),
7252          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7253     bits<2> idx;
7254     let Inst{11} = idx{1};
7255     let Inst{21} = idx{0};
7256   }
7257
7258   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7259                                       V128, V128,
7260                                       V128, VectorIndexS,
7261                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7262     [(set (v2i64 V128:$Rd),
7263           (OpNode (extract_high_v4i32 V128:$Rn),
7264                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7265                                                       VectorIndexS:$idx))))]> {
7266     bits<2> idx;
7267     let Inst{11} = idx{1};
7268     let Inst{21} = idx{0};
7269   }
7270
7271   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7272                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7273                                       asm, ".h", "", "", ".h", []> {
7274     bits<3> idx;
7275     let Inst{11} = idx{2};
7276     let Inst{21} = idx{1};
7277     let Inst{20} = idx{0};
7278   }
7279
7280   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7281                                       FPR64Op, FPR32Op, V128, VectorIndexS,
7282                                       asm, ".s", "", "", ".s", []> {
7283     bits<2> idx;
7284     let Inst{11} = idx{1};
7285     let Inst{21} = idx{0};
7286   }
7287 }
7288
7289 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7290                                        SDPatternOperator Accum> {
7291   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7292                                       V128, V64,
7293                                       V128_lo, VectorIndexH,
7294                                       asm, ".4s", ".4s", ".4h", ".h",
7295     [(set (v4i32 V128:$dst),
7296           (Accum (v4i32 V128:$Rd),
7297                  (v4i32 (int_aarch64_neon_sqdmull
7298                              (v4i16 V64:$Rn),
7299                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7300                                                     VectorIndexH:$idx))))))]> {
7301     bits<3> idx;
7302     let Inst{11} = idx{2};
7303     let Inst{21} = idx{1};
7304     let Inst{20} = idx{0};
7305   }
7306
7307   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7308   // intermediate EXTRACT_SUBREG would be untyped.
7309   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7310                 (i32 (vector_extract (v4i32
7311                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7312                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7313                                                     VectorIndexH:$idx)))),
7314                          (i64 0))))),
7315             (EXTRACT_SUBREG
7316                 (!cast<Instruction>(NAME # v4i16_indexed)
7317                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7318                     V128_lo:$Rm, VectorIndexH:$idx),
7319                 ssub)>;
7320
7321   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7322                                       V128, V128,
7323                                       V128_lo, VectorIndexH,
7324                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7325     [(set (v4i32 V128:$dst),
7326           (Accum (v4i32 V128:$Rd),
7327                  (v4i32 (int_aarch64_neon_sqdmull
7328                             (extract_high_v8i16 V128:$Rn),
7329                             (extract_high_v8i16
7330                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7331                                                 VectorIndexH:$idx))))))]> {
7332     bits<3> idx;
7333     let Inst{11} = idx{2};
7334     let Inst{21} = idx{1};
7335     let Inst{20} = idx{0};
7336   }
7337
7338   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7339                                       V128, V64,
7340                                       V128, VectorIndexS,
7341                                       asm, ".2d", ".2d", ".2s", ".s",
7342     [(set (v2i64 V128:$dst),
7343         (Accum (v2i64 V128:$Rd),
7344                (v2i64 (int_aarch64_neon_sqdmull
7345                           (v2i32 V64:$Rn),
7346                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7347                                                  VectorIndexS:$idx))))))]> {
7348     bits<2> idx;
7349     let Inst{11} = idx{1};
7350     let Inst{21} = idx{0};
7351   }
7352
7353   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7354                                       V128, V128,
7355                                       V128, VectorIndexS,
7356                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7357     [(set (v2i64 V128:$dst),
7358           (Accum (v2i64 V128:$Rd),
7359                  (v2i64 (int_aarch64_neon_sqdmull
7360                             (extract_high_v4i32 V128:$Rn),
7361                             (extract_high_v4i32
7362                                 (AArch64duplane32 (v4i32 V128:$Rm),
7363                                                 VectorIndexS:$idx))))))]> {
7364     bits<2> idx;
7365     let Inst{11} = idx{1};
7366     let Inst{21} = idx{0};
7367   }
7368
7369   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7370                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7371                                       asm, ".h", "", "", ".h", []> {
7372     bits<3> idx;
7373     let Inst{11} = idx{2};
7374     let Inst{21} = idx{1};
7375     let Inst{20} = idx{0};
7376   }
7377
7378
7379   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7380                                       FPR64Op, FPR32Op, V128, VectorIndexS,
7381                                       asm, ".s", "", "", ".s",
7382     [(set (i64 FPR64Op:$dst),
7383           (Accum (i64 FPR64Op:$Rd),
7384                  (i64 (int_aarch64_neon_sqdmulls_scalar
7385                             (i32 FPR32Op:$Rn),
7386                             (i32 (vector_extract (v4i32 V128:$Rm),
7387                                                  VectorIndexS:$idx))))))]> {
7388
7389     bits<2> idx;
7390     let Inst{11} = idx{1};
7391     let Inst{21} = idx{0};
7392   }
7393 }
7394
7395 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7396                                    SDPatternOperator OpNode> {
7397   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7398   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7399                                       V128, V64,
7400                                       V128_lo, VectorIndexH,
7401                                       asm, ".4s", ".4s", ".4h", ".h",
7402     [(set (v4i32 V128:$Rd),
7403         (OpNode (v4i16 V64:$Rn),
7404          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7405     bits<3> idx;
7406     let Inst{11} = idx{2};
7407     let Inst{21} = idx{1};
7408     let Inst{20} = idx{0};
7409   }
7410
7411   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7412                                       V128, V128,
7413                                       V128_lo, VectorIndexH,
7414                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7415     [(set (v4i32 V128:$Rd),
7416           (OpNode (extract_high_v8i16 V128:$Rn),
7417                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7418                                                       VectorIndexH:$idx))))]> {
7419
7420     bits<3> idx;
7421     let Inst{11} = idx{2};
7422     let Inst{21} = idx{1};
7423     let Inst{20} = idx{0};
7424   }
7425
7426   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7427                                       V128, V64,
7428                                       V128, VectorIndexS,
7429                                       asm, ".2d", ".2d", ".2s", ".s",
7430     [(set (v2i64 V128:$Rd),
7431         (OpNode (v2i32 V64:$Rn),
7432          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7433     bits<2> idx;
7434     let Inst{11} = idx{1};
7435     let Inst{21} = idx{0};
7436   }
7437
7438   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7439                                       V128, V128,
7440                                       V128, VectorIndexS,
7441                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7442     [(set (v2i64 V128:$Rd),
7443           (OpNode (extract_high_v4i32 V128:$Rn),
7444                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7445                                                       VectorIndexS:$idx))))]> {
7446     bits<2> idx;
7447     let Inst{11} = idx{1};
7448     let Inst{21} = idx{0};
7449   }
7450   }
7451 }
7452
7453 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7454                                        SDPatternOperator OpNode> {
7455   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7456   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7457                                       V128, V64,
7458                                       V128_lo, VectorIndexH,
7459                                       asm, ".4s", ".4s", ".4h", ".h",
7460     [(set (v4i32 V128:$dst),
7461         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7462          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7463     bits<3> idx;
7464     let Inst{11} = idx{2};
7465     let Inst{21} = idx{1};
7466     let Inst{20} = idx{0};
7467   }
7468
7469   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7470                                       V128, V128,
7471                                       V128_lo, VectorIndexH,
7472                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7473     [(set (v4i32 V128:$dst),
7474           (OpNode (v4i32 V128:$Rd),
7475                   (extract_high_v8i16 V128:$Rn),
7476                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7477                                                       VectorIndexH:$idx))))]> {
7478     bits<3> idx;
7479     let Inst{11} = idx{2};
7480     let Inst{21} = idx{1};
7481     let Inst{20} = idx{0};
7482   }
7483
7484   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7485                                       V128, V64,
7486                                       V128, VectorIndexS,
7487                                       asm, ".2d", ".2d", ".2s", ".s",
7488     [(set (v2i64 V128:$dst),
7489         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7490          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7491     bits<2> idx;
7492     let Inst{11} = idx{1};
7493     let Inst{21} = idx{0};
7494   }
7495
7496   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7497                                       V128, V128,
7498                                       V128, VectorIndexS,
7499                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7500     [(set (v2i64 V128:$dst),
7501           (OpNode (v2i64 V128:$Rd),
7502                   (extract_high_v4i32 V128:$Rn),
7503                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7504                                                       VectorIndexS:$idx))))]> {
7505     bits<2> idx;
7506     let Inst{11} = idx{1};
7507     let Inst{21} = idx{0};
7508   }
7509   }
7510 }
7511
7512 //----------------------------------------------------------------------------
7513 // AdvSIMD scalar shift by immediate
7514 //----------------------------------------------------------------------------
7515
7516 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7517 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7518                      RegisterClass regtype1, RegisterClass regtype2,
7519                      Operand immtype, string asm, list<dag> pattern>
7520   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7521       asm, "\t$Rd, $Rn, $imm", "", pattern>,
7522     Sched<[WriteV]> {
7523   bits<5> Rd;
7524   bits<5> Rn;
7525   bits<7> imm;
7526   let Inst{31-30} = 0b01;
7527   let Inst{29}    = U;
7528   let Inst{28-23} = 0b111110;
7529   let Inst{22-16} = fixed_imm;
7530   let Inst{15-11} = opc;
7531   let Inst{10}    = 1;
7532   let Inst{9-5} = Rn;
7533   let Inst{4-0} = Rd;
7534 }
7535
7536 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7537 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7538                      RegisterClass regtype1, RegisterClass regtype2,
7539                      Operand immtype, string asm, list<dag> pattern>
7540   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7541       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7542     Sched<[WriteV]> {
7543   bits<5> Rd;
7544   bits<5> Rn;
7545   bits<7> imm;
7546   let Inst{31-30} = 0b01;
7547   let Inst{29}    = U;
7548   let Inst{28-23} = 0b111110;
7549   let Inst{22-16} = fixed_imm;
7550   let Inst{15-11} = opc;
7551   let Inst{10}    = 1;
7552   let Inst{9-5} = Rn;
7553   let Inst{4-0} = Rd;
7554 }
7555
7556
7557 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
7558   let Predicates = [HasNEON, HasFullFP16] in {
7559   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7560                               FPR16, FPR16, vecshiftR16, asm, []> {
7561     let Inst{19-16} = imm{3-0};
7562   }
7563   } // Predicates = [HasNEON, HasFullFP16]
7564   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7565                               FPR32, FPR32, vecshiftR32, asm, []> {
7566     let Inst{20-16} = imm{4-0};
7567   }
7568
7569   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7570                               FPR64, FPR64, vecshiftR64, asm, []> {
7571     let Inst{21-16} = imm{5-0};
7572   }
7573 }
7574
7575 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7576                              SDPatternOperator OpNode> {
7577   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7578                               FPR64, FPR64, vecshiftR64, asm,
7579   [(set (i64 FPR64:$Rd),
7580      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7581     let Inst{21-16} = imm{5-0};
7582   }
7583
7584   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7585             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7586 }
7587
7588 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7589                                  SDPatternOperator OpNode = null_frag> {
7590   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7591                               FPR64, FPR64, vecshiftR64, asm,
7592   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7593                                                    (i32 vecshiftR64:$imm)))]> {
7594     let Inst{21-16} = imm{5-0};
7595   }
7596
7597   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7598                            (i32 vecshiftR64:$imm))),
7599             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7600                                             vecshiftR64:$imm)>;
7601 }
7602
7603 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7604                              SDPatternOperator OpNode> {
7605   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7606                               FPR64, FPR64, vecshiftL64, asm,
7607     [(set (v1i64 FPR64:$Rd),
7608        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7609     let Inst{21-16} = imm{5-0};
7610   }
7611 }
7612
7613 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7614 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7615   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7616                               FPR64, FPR64, vecshiftL64, asm, []> {
7617     let Inst{21-16} = imm{5-0};
7618   }
7619 }
7620
7621 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7622 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7623                                SDPatternOperator OpNode = null_frag> {
7624   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7625                               FPR8, FPR16, vecshiftR8, asm, []> {
7626     let Inst{18-16} = imm{2-0};
7627   }
7628
7629   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7630                               FPR16, FPR32, vecshiftR16, asm, []> {
7631     let Inst{19-16} = imm{3-0};
7632   }
7633
7634   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7635                               FPR32, FPR64, vecshiftR32, asm,
7636     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7637     let Inst{20-16} = imm{4-0};
7638   }
7639 }
7640
7641 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7642                                 SDPatternOperator OpNode> {
7643   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7644                               FPR8, FPR8, vecshiftL8, asm, []> {
7645     let Inst{18-16} = imm{2-0};
7646   }
7647
7648   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7649                               FPR16, FPR16, vecshiftL16, asm, []> {
7650     let Inst{19-16} = imm{3-0};
7651   }
7652
7653   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7654                               FPR32, FPR32, vecshiftL32, asm,
7655     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7656     let Inst{20-16} = imm{4-0};
7657   }
7658
7659   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7660                               FPR64, FPR64, vecshiftL64, asm,
7661     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7662     let Inst{21-16} = imm{5-0};
7663   }
7664
7665   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7666             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7667 }
7668
7669 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7670   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7671                               FPR8, FPR8, vecshiftR8, asm, []> {
7672     let Inst{18-16} = imm{2-0};
7673   }
7674
7675   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7676                               FPR16, FPR16, vecshiftR16, asm, []> {
7677     let Inst{19-16} = imm{3-0};
7678   }
7679
7680   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7681                               FPR32, FPR32, vecshiftR32, asm, []> {
7682     let Inst{20-16} = imm{4-0};
7683   }
7684
7685   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7686                               FPR64, FPR64, vecshiftR64, asm, []> {
7687     let Inst{21-16} = imm{5-0};
7688   }
7689 }
7690
7691 //----------------------------------------------------------------------------
7692 // AdvSIMD vector x indexed element
7693 //----------------------------------------------------------------------------
7694
7695 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7696 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7697                      RegisterOperand dst_reg, RegisterOperand src_reg,
7698                      Operand immtype,
7699                      string asm, string dst_kind, string src_kind,
7700                      list<dag> pattern>
7701   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7702       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7703            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7704     Sched<[WriteV]> {
7705   bits<5> Rd;
7706   bits<5> Rn;
7707   let Inst{31}    = 0;
7708   let Inst{30}    = Q;
7709   let Inst{29}    = U;
7710   let Inst{28-23} = 0b011110;
7711   let Inst{22-16} = fixed_imm;
7712   let Inst{15-11} = opc;
7713   let Inst{10}    = 1;
7714   let Inst{9-5}   = Rn;
7715   let Inst{4-0}   = Rd;
7716 }
7717
7718 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7719 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7720                      RegisterOperand vectype1, RegisterOperand vectype2,
7721                      Operand immtype,
7722                      string asm, string dst_kind, string src_kind,
7723                      list<dag> pattern>
7724   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7725       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7726            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7727     Sched<[WriteV]> {
7728   bits<5> Rd;
7729   bits<5> Rn;
7730   let Inst{31}    = 0;
7731   let Inst{30}    = Q;
7732   let Inst{29}    = U;
7733   let Inst{28-23} = 0b011110;
7734   let Inst{22-16} = fixed_imm;
7735   let Inst{15-11} = opc;
7736   let Inst{10}    = 1;
7737   let Inst{9-5}   = Rn;
7738   let Inst{4-0}   = Rd;
7739 }
7740
7741 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7742                               Intrinsic OpNode> {
7743   let Predicates = [HasNEON, HasFullFP16] in {
7744   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7745                                   V64, V64, vecshiftR16,
7746                                   asm, ".4h", ".4h",
7747       [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
7748     bits<4> imm;
7749     let Inst{19-16} = imm;
7750   }
7751
7752   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7753                                   V128, V128, vecshiftR16,
7754                                   asm, ".8h", ".8h",
7755       [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
7756     bits<4> imm;
7757     let Inst{19-16} = imm;
7758   }
7759   } // Predicates = [HasNEON, HasFullFP16]
7760   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7761                                   V64, V64, vecshiftR32,
7762                                   asm, ".2s", ".2s",
7763       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7764     bits<5> imm;
7765     let Inst{20-16} = imm;
7766   }
7767
7768   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7769                                   V128, V128, vecshiftR32,
7770                                   asm, ".4s", ".4s",
7771       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7772     bits<5> imm;
7773     let Inst{20-16} = imm;
7774   }
7775
7776   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7777                                   V128, V128, vecshiftR64,
7778                                   asm, ".2d", ".2d",
7779       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7780     bits<6> imm;
7781     let Inst{21-16} = imm;
7782   }
7783 }
7784
7785 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
7786                                   Intrinsic OpNode> {
7787   let Predicates = [HasNEON, HasFullFP16] in {
7788   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7789                                   V64, V64, vecshiftR16,
7790                                   asm, ".4h", ".4h",
7791       [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
7792     bits<4> imm;
7793     let Inst{19-16} = imm;
7794   }
7795
7796   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7797                                   V128, V128, vecshiftR16,
7798                                   asm, ".8h", ".8h",
7799       [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
7800     bits<4> imm;
7801     let Inst{19-16} = imm;
7802   }
7803   } // Predicates = [HasNEON, HasFullFP16]
7804
7805   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7806                                   V64, V64, vecshiftR32,
7807                                   asm, ".2s", ".2s",
7808       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7809     bits<5> imm;
7810     let Inst{20-16} = imm;
7811   }
7812
7813   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7814                                   V128, V128, vecshiftR32,
7815                                   asm, ".4s", ".4s",
7816       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7817     bits<5> imm;
7818     let Inst{20-16} = imm;
7819   }
7820
7821   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7822                                   V128, V128, vecshiftR64,
7823                                   asm, ".2d", ".2d",
7824       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7825     bits<6> imm;
7826     let Inst{21-16} = imm;
7827   }
7828 }
7829
7830 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7831                                      SDPatternOperator OpNode> {
7832   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7833                                   V64, V128, vecshiftR16Narrow,
7834                                   asm, ".8b", ".8h",
7835       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7836     bits<3> imm;
7837     let Inst{18-16} = imm;
7838   }
7839
7840   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7841                                   V128, V128, vecshiftR16Narrow,
7842                                   asm#"2", ".16b", ".8h", []> {
7843     bits<3> imm;
7844     let Inst{18-16} = imm;
7845     let hasSideEffects = 0;
7846   }
7847
7848   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7849                                   V64, V128, vecshiftR32Narrow,
7850                                   asm, ".4h", ".4s",
7851       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7852     bits<4> imm;
7853     let Inst{19-16} = imm;
7854   }
7855
7856   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7857                                   V128, V128, vecshiftR32Narrow,
7858                                   asm#"2", ".8h", ".4s", []> {
7859     bits<4> imm;
7860     let Inst{19-16} = imm;
7861     let hasSideEffects = 0;
7862   }
7863
7864   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7865                                   V64, V128, vecshiftR64Narrow,
7866                                   asm, ".2s", ".2d",
7867       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7868     bits<5> imm;
7869     let Inst{20-16} = imm;
7870   }
7871
7872   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7873                                   V128, V128, vecshiftR64Narrow,
7874                                   asm#"2", ".4s", ".2d", []> {
7875     bits<5> imm;
7876     let Inst{20-16} = imm;
7877     let hasSideEffects = 0;
7878   }
7879
7880   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7881   // themselves, so put them here instead.
7882
7883   // Patterns involving what's effectively an insert high and a normal
7884   // intrinsic, represented by CONCAT_VECTORS.
7885   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7886                                                    vecshiftR16Narrow:$imm)),
7887             (!cast<Instruction>(NAME # "v16i8_shift")
7888                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7889                 V128:$Rn, vecshiftR16Narrow:$imm)>;
7890   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7891                                                      vecshiftR32Narrow:$imm)),
7892             (!cast<Instruction>(NAME # "v8i16_shift")
7893                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7894                 V128:$Rn, vecshiftR32Narrow:$imm)>;
7895   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7896                                                      vecshiftR64Narrow:$imm)),
7897             (!cast<Instruction>(NAME # "v4i32_shift")
7898                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7899                 V128:$Rn, vecshiftR64Narrow:$imm)>;
7900 }
7901
7902 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7903                                 SDPatternOperator OpNode> {
7904   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7905                                   V64, V64, vecshiftL8,
7906                                   asm, ".8b", ".8b",
7907                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7908                        (i32 vecshiftL8:$imm)))]> {
7909     bits<3> imm;
7910     let Inst{18-16} = imm;
7911   }
7912
7913   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7914                                   V128, V128, vecshiftL8,
7915                                   asm, ".16b", ".16b",
7916              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7917                    (i32 vecshiftL8:$imm)))]> {
7918     bits<3> imm;
7919     let Inst{18-16} = imm;
7920   }
7921
7922   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7923                                   V64, V64, vecshiftL16,
7924                                   asm, ".4h", ".4h",
7925               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7926                     (i32 vecshiftL16:$imm)))]> {
7927     bits<4> imm;
7928     let Inst{19-16} = imm;
7929   }
7930
7931   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7932                                   V128, V128, vecshiftL16,
7933                                   asm, ".8h", ".8h",
7934             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7935                   (i32 vecshiftL16:$imm)))]> {
7936     bits<4> imm;
7937     let Inst{19-16} = imm;
7938   }
7939
7940   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7941                                   V64, V64, vecshiftL32,
7942                                   asm, ".2s", ".2s",
7943               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7944                     (i32 vecshiftL32:$imm)))]> {
7945     bits<5> imm;
7946     let Inst{20-16} = imm;
7947   }
7948
7949   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7950                                   V128, V128, vecshiftL32,
7951                                   asm, ".4s", ".4s",
7952             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7953                   (i32 vecshiftL32:$imm)))]> {
7954     bits<5> imm;
7955     let Inst{20-16} = imm;
7956   }
7957
7958   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7959                                   V128, V128, vecshiftL64,
7960                                   asm, ".2d", ".2d",
7961             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7962                   (i32 vecshiftL64:$imm)))]> {
7963     bits<6> imm;
7964     let Inst{21-16} = imm;
7965   }
7966 }
7967
7968 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7969                                 SDPatternOperator OpNode> {
7970   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7971                                   V64, V64, vecshiftR8,
7972                                   asm, ".8b", ".8b",
7973                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7974                        (i32 vecshiftR8:$imm)))]> {
7975     bits<3> imm;
7976     let Inst{18-16} = imm;
7977   }
7978
7979   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7980                                   V128, V128, vecshiftR8,
7981                                   asm, ".16b", ".16b",
7982              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7983                    (i32 vecshiftR8:$imm)))]> {
7984     bits<3> imm;
7985     let Inst{18-16} = imm;
7986   }
7987
7988   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7989                                   V64, V64, vecshiftR16,
7990                                   asm, ".4h", ".4h",
7991               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7992                     (i32 vecshiftR16:$imm)))]> {
7993     bits<4> imm;
7994     let Inst{19-16} = imm;
7995   }
7996
7997   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7998                                   V128, V128, vecshiftR16,
7999                                   asm, ".8h", ".8h",
8000             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8001                   (i32 vecshiftR16:$imm)))]> {
8002     bits<4> imm;
8003     let Inst{19-16} = imm;
8004   }
8005
8006   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8007                                   V64, V64, vecshiftR32,
8008                                   asm, ".2s", ".2s",
8009               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8010                     (i32 vecshiftR32:$imm)))]> {
8011     bits<5> imm;
8012     let Inst{20-16} = imm;
8013   }
8014
8015   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8016                                   V128, V128, vecshiftR32,
8017                                   asm, ".4s", ".4s",
8018             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8019                   (i32 vecshiftR32:$imm)))]> {
8020     bits<5> imm;
8021     let Inst{20-16} = imm;
8022   }
8023
8024   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8025                                   V128, V128, vecshiftR64,
8026                                   asm, ".2d", ".2d",
8027             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8028                   (i32 vecshiftR64:$imm)))]> {
8029     bits<6> imm;
8030     let Inst{21-16} = imm;
8031   }
8032 }
8033
8034 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8035 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8036                                     SDPatternOperator OpNode = null_frag> {
8037   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8038                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
8039                  [(set (v8i8 V64:$dst),
8040                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8041                            (i32 vecshiftR8:$imm)))]> {
8042     bits<3> imm;
8043     let Inst{18-16} = imm;
8044   }
8045
8046   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8047                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
8048              [(set (v16i8 V128:$dst),
8049                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8050                        (i32 vecshiftR8:$imm)))]> {
8051     bits<3> imm;
8052     let Inst{18-16} = imm;
8053   }
8054
8055   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8056                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
8057               [(set (v4i16 V64:$dst),
8058                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8059                         (i32 vecshiftR16:$imm)))]> {
8060     bits<4> imm;
8061     let Inst{19-16} = imm;
8062   }
8063
8064   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8065                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
8066             [(set (v8i16 V128:$dst),
8067               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8068                       (i32 vecshiftR16:$imm)))]> {
8069     bits<4> imm;
8070     let Inst{19-16} = imm;
8071   }
8072
8073   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8074                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
8075               [(set (v2i32 V64:$dst),
8076                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8077                         (i32 vecshiftR32:$imm)))]> {
8078     bits<5> imm;
8079     let Inst{20-16} = imm;
8080   }
8081
8082   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8083                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
8084             [(set (v4i32 V128:$dst),
8085               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8086                       (i32 vecshiftR32:$imm)))]> {
8087     bits<5> imm;
8088     let Inst{20-16} = imm;
8089   }
8090
8091   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8092                                   V128, V128, vecshiftR64,
8093                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8094               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8095                       (i32 vecshiftR64:$imm)))]> {
8096     bits<6> imm;
8097     let Inst{21-16} = imm;
8098   }
8099 }
8100
8101 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
8102                                     SDPatternOperator OpNode = null_frag> {
8103   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8104                                   V64, V64, vecshiftL8,
8105                                   asm, ".8b", ".8b",
8106                     [(set (v8i8 V64:$dst),
8107                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8108                                   (i32 vecshiftL8:$imm)))]> {
8109     bits<3> imm;
8110     let Inst{18-16} = imm;
8111   }
8112
8113   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8114                                   V128, V128, vecshiftL8,
8115                                   asm, ".16b", ".16b",
8116                     [(set (v16i8 V128:$dst),
8117                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8118                                   (i32 vecshiftL8:$imm)))]> {
8119     bits<3> imm;
8120     let Inst{18-16} = imm;
8121   }
8122
8123   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8124                                   V64, V64, vecshiftL16,
8125                                   asm, ".4h", ".4h",
8126                     [(set (v4i16 V64:$dst),
8127                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8128                                    (i32 vecshiftL16:$imm)))]> {
8129     bits<4> imm;
8130     let Inst{19-16} = imm;
8131   }
8132
8133   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8134                                   V128, V128, vecshiftL16,
8135                                   asm, ".8h", ".8h",
8136                     [(set (v8i16 V128:$dst),
8137                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8138                                   (i32 vecshiftL16:$imm)))]> {
8139     bits<4> imm;
8140     let Inst{19-16} = imm;
8141   }
8142
8143   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8144                                   V64, V64, vecshiftL32,
8145                                   asm, ".2s", ".2s",
8146                     [(set (v2i32 V64:$dst),
8147                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8148                                   (i32 vecshiftL32:$imm)))]> {
8149     bits<5> imm;
8150     let Inst{20-16} = imm;
8151   }
8152
8153   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8154                                   V128, V128, vecshiftL32,
8155                                   asm, ".4s", ".4s",
8156                     [(set (v4i32 V128:$dst),
8157                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8158                                   (i32 vecshiftL32:$imm)))]> {
8159     bits<5> imm;
8160     let Inst{20-16} = imm;
8161   }
8162
8163   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8164                                   V128, V128, vecshiftL64,
8165                                   asm, ".2d", ".2d",
8166                     [(set (v2i64 V128:$dst),
8167                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8168                                   (i32 vecshiftL64:$imm)))]> {
8169     bits<6> imm;
8170     let Inst{21-16} = imm;
8171   }
8172 }
8173
8174 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
8175                                    SDPatternOperator OpNode> {
8176   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8177                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
8178       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
8179     bits<3> imm;
8180     let Inst{18-16} = imm;
8181   }
8182
8183   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8184                                   V128, V128, vecshiftL8,
8185                                   asm#"2", ".8h", ".16b",
8186       [(set (v8i16 V128:$Rd),
8187             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
8188     bits<3> imm;
8189     let Inst{18-16} = imm;
8190   }
8191
8192   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8193                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
8194       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
8195     bits<4> imm;
8196     let Inst{19-16} = imm;
8197   }
8198
8199   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8200                                   V128, V128, vecshiftL16,
8201                                   asm#"2", ".4s", ".8h",
8202       [(set (v4i32 V128:$Rd),
8203             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
8204
8205     bits<4> imm;
8206     let Inst{19-16} = imm;
8207   }
8208
8209   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8210                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
8211       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
8212     bits<5> imm;
8213     let Inst{20-16} = imm;
8214   }
8215
8216   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8217                                   V128, V128, vecshiftL32,
8218                                   asm#"2", ".2d", ".4s",
8219       [(set (v2i64 V128:$Rd),
8220             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
8221     bits<5> imm;
8222     let Inst{20-16} = imm;
8223   }
8224 }
8225
8226
8227 //---
8228 // Vector load/store
8229 //---
8230 // SIMD ldX/stX no-index memory references don't allow the optional
8231 // ", #0" constant and handle post-indexing explicitly, so we use
8232 // a more specialized parse method for them. Otherwise, it's the same as
8233 // the general GPR64sp handling.
8234
8235 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
8236                    string asm, dag oops, dag iops, list<dag> pattern>
8237   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
8238   bits<5> Vt;
8239   bits<5> Rn;
8240   let Inst{31} = 0;
8241   let Inst{30} = Q;
8242   let Inst{29-23} = 0b0011000;
8243   let Inst{22} = L;
8244   let Inst{21-16} = 0b000000;
8245   let Inst{15-12} = opcode;
8246   let Inst{11-10} = size;
8247   let Inst{9-5} = Rn;
8248   let Inst{4-0} = Vt;
8249 }
8250
8251 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
8252                        string asm, dag oops, dag iops>
8253   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
8254   bits<5> Vt;
8255   bits<5> Rn;
8256   bits<5> Xm;
8257   let Inst{31} = 0;
8258   let Inst{30} = Q;
8259   let Inst{29-23} = 0b0011001;
8260   let Inst{22} = L;
8261   let Inst{21} = 0;
8262   let Inst{20-16} = Xm;
8263   let Inst{15-12} = opcode;
8264   let Inst{11-10} = size;
8265   let Inst{9-5} = Rn;
8266   let Inst{4-0} = Vt;
8267 }
8268
8269 // The immediate form of AdvSIMD post-indexed addressing is encoded with
8270 // register post-index addressing from the zero register.
8271 multiclass SIMDLdStAliases<string asm, string layout, string Count,
8272                            int Offset, int Size> {
8273   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8274   //      "ld1\t$Vt, [$Rn], #16"
8275   // may get mapped to
8276   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8277   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8278                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8279                       GPR64sp:$Rn,
8280                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8281                       XZR), 1>;
8282
8283   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8284   //      "ld1.8b\t$Vt, [$Rn], #16"
8285   // may get mapped to
8286   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8287   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8288                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8289                       GPR64sp:$Rn,
8290                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8291                       XZR), 0>;
8292
8293   // E.g. "ld1.8b { v0, v1 }, [x1]"
8294   //      "ld1\t$Vt, [$Rn]"
8295   // may get mapped to
8296   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8297   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8298                   (!cast<Instruction>(NAME # Count # "v" # layout)
8299                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8300                       GPR64sp:$Rn), 0>;
8301
8302   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8303   //      "ld1\t$Vt, [$Rn], $Xm"
8304   // may get mapped to
8305   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8306   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8307                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8308                       GPR64sp:$Rn,
8309                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8310                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8311 }
8312
8313 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
8314                        int Offset64, bits<4> opcode> {
8315   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8316     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8317                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8318                            (ins GPR64sp:$Rn), []>;
8319     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8320                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8321                            (ins GPR64sp:$Rn), []>;
8322     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8323                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8324                            (ins GPR64sp:$Rn), []>;
8325     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8326                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8327                            (ins GPR64sp:$Rn), []>;
8328     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8329                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8330                            (ins GPR64sp:$Rn), []>;
8331     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8332                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8333                            (ins GPR64sp:$Rn), []>;
8334     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8335                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8336                            (ins GPR64sp:$Rn), []>;
8337
8338
8339     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8340                        (outs GPR64sp:$wback,
8341                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
8342                        (ins GPR64sp:$Rn,
8343                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8344     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8345                        (outs GPR64sp:$wback,
8346                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
8347                        (ins GPR64sp:$Rn,
8348                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8349     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8350                        (outs GPR64sp:$wback,
8351                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
8352                        (ins GPR64sp:$Rn,
8353                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8354     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8355                        (outs GPR64sp:$wback,
8356                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
8357                        (ins GPR64sp:$Rn,
8358                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8359     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8360                        (outs GPR64sp:$wback,
8361                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
8362                        (ins GPR64sp:$Rn,
8363                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8364     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8365                        (outs GPR64sp:$wback,
8366                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
8367                        (ins GPR64sp:$Rn,
8368                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8369     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8370                        (outs GPR64sp:$wback,
8371                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
8372                        (ins GPR64sp:$Rn,
8373                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8374   }
8375
8376   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8377   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8378   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8379   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8380   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8381   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8382   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8383 }
8384
8385 // Only ld1/st1 has a v1d version.
8386 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
8387                        int Offset64, bits<4> opcode> {
8388   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8389     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8390                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8391                                  GPR64sp:$Rn), []>;
8392     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8393                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8394                                 GPR64sp:$Rn), []>;
8395     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8396                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8397                                 GPR64sp:$Rn), []>;
8398     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8399                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8400                                 GPR64sp:$Rn), []>;
8401     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8402                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8403                                 GPR64sp:$Rn), []>;
8404     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8405                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8406                                 GPR64sp:$Rn), []>;
8407     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8408                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8409                                 GPR64sp:$Rn), []>;
8410
8411     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8412                        (outs GPR64sp:$wback),
8413                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8414                             GPR64sp:$Rn,
8415                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8416     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8417                        (outs GPR64sp:$wback),
8418                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8419                             GPR64sp:$Rn,
8420                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8421     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8422                        (outs GPR64sp:$wback),
8423                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8424                             GPR64sp:$Rn,
8425                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8426     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8427                        (outs GPR64sp:$wback),
8428                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8429                             GPR64sp:$Rn,
8430                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8431     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8432                        (outs GPR64sp:$wback),
8433                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8434                             GPR64sp:$Rn,
8435                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8436     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8437                        (outs GPR64sp:$wback),
8438                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8439                             GPR64sp:$Rn,
8440                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8441     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8442                        (outs GPR64sp:$wback),
8443                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8444                             GPR64sp:$Rn,
8445                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8446   }
8447
8448   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8449   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8450   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8451   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8452   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8453   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8454   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8455 }
8456
8457 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8458                        int Offset128, int Offset64, bits<4> opcode>
8459   : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8460
8461   // LD1 instructions have extra "1d" variants.
8462   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8463     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8464                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8465                            (ins GPR64sp:$Rn), []>;
8466
8467     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8468                        (outs GPR64sp:$wback,
8469                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
8470                        (ins GPR64sp:$Rn,
8471                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8472   }
8473
8474   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8475 }
8476
8477 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8478                        int Offset128, int Offset64, bits<4> opcode>
8479   : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8480
8481   // ST1 instructions have extra "1d" variants.
8482   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8483     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8484                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8485                                 GPR64sp:$Rn), []>;
8486
8487     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8488                        (outs GPR64sp:$wback),
8489                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8490                             GPR64sp:$Rn,
8491                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8492   }
8493
8494   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8495 }
8496
8497 multiclass SIMDLd1Multiple<string asm> {
8498   defm One   : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8,  0b0111>;
8499   defm Two   : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8500   defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8501   defm Four  : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8502 }
8503
8504 multiclass SIMDSt1Multiple<string asm> {
8505   defm One   : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8,  0b0111>;
8506   defm Two   : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8507   defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8508   defm Four  : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8509 }
8510
8511 multiclass SIMDLd2Multiple<string asm> {
8512   defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8513 }
8514
8515 multiclass SIMDSt2Multiple<string asm> {
8516   defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8517 }
8518
8519 multiclass SIMDLd3Multiple<string asm> {
8520   defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8521 }
8522
8523 multiclass SIMDSt3Multiple<string asm> {
8524   defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8525 }
8526
8527 multiclass SIMDLd4Multiple<string asm> {
8528   defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8529 }
8530
8531 multiclass SIMDSt4Multiple<string asm> {
8532   defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8533 }
8534
8535 //---
8536 // AdvSIMD Load/store single-element
8537 //---
8538
8539 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8540                          string asm, string operands, string cst,
8541                          dag oops, dag iops, list<dag> pattern>
8542   : I<oops, iops, asm, operands, cst, pattern> {
8543   bits<5> Vt;
8544   bits<5> Rn;
8545   let Inst{31} = 0;
8546   let Inst{29-24} = 0b001101;
8547   let Inst{22} = L;
8548   let Inst{21} = R;
8549   let Inst{15-13} = opcode;
8550   let Inst{9-5} = Rn;
8551   let Inst{4-0} = Vt;
8552 }
8553
8554 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8555                          string asm, string operands, string cst,
8556                          dag oops, dag iops, list<dag> pattern>
8557   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8558   bits<5> Vt;
8559   bits<5> Rn;
8560   let Inst{31} = 0;
8561   let Inst{29-24} = 0b001101;
8562   let Inst{22} = L;
8563   let Inst{21} = R;
8564   let Inst{15-13} = opcode;
8565   let Inst{9-5} = Rn;
8566   let Inst{4-0} = Vt;
8567 }
8568
8569
8570 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8571 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8572                   Operand listtype>
8573   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8574                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
8575                        []> {
8576   let Inst{30} = Q;
8577   let Inst{23} = 0;
8578   let Inst{20-16} = 0b00000;
8579   let Inst{12} = S;
8580   let Inst{11-10} = size;
8581 }
8582 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8583 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8584                       string asm, Operand listtype, Operand GPR64pi>
8585   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8586                        "$Rn = $wback",
8587                        (outs GPR64sp:$wback, listtype:$Vt),
8588                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8589   bits<5> Xm;
8590   let Inst{30} = Q;
8591   let Inst{23} = 1;
8592   let Inst{20-16} = Xm;
8593   let Inst{12} = S;
8594   let Inst{11-10} = size;
8595 }
8596
8597 multiclass SIMDLdrAliases<string asm, string layout, string Count,
8598                           int Offset, int Size> {
8599   // E.g. "ld1r { v0.8b }, [x1], #1"
8600   //      "ld1r.8b\t$Vt, [$Rn], #1"
8601   // may get mapped to
8602   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8603   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8604                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8605                       GPR64sp:$Rn,
8606                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8607                       XZR), 1>;
8608
8609   // E.g. "ld1r.8b { v0 }, [x1], #1"
8610   //      "ld1r.8b\t$Vt, [$Rn], #1"
8611   // may get mapped to
8612   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8613   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8614                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8615                       GPR64sp:$Rn,
8616                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8617                       XZR), 0>;
8618
8619   // E.g. "ld1r.8b { v0 }, [x1]"
8620   //      "ld1r.8b\t$Vt, [$Rn]"
8621   // may get mapped to
8622   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8623   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8624                   (!cast<Instruction>(NAME # "v" # layout)
8625                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8626                       GPR64sp:$Rn), 0>;
8627
8628   // E.g. "ld1r.8b { v0 }, [x1], x2"
8629   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
8630   // may get mapped to
8631   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8632   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8633                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8634                       GPR64sp:$Rn,
8635                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8636                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8637 }
8638
8639 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8640   int Offset1, int Offset2, int Offset4, int Offset8> {
8641   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8642                         !cast<Operand>("VecList" # Count # "8b")>;
8643   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8644                         !cast<Operand>("VecList" # Count #"16b")>;
8645   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8646                         !cast<Operand>("VecList" # Count #"4h")>;
8647   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8648                         !cast<Operand>("VecList" # Count #"8h")>;
8649   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8650                         !cast<Operand>("VecList" # Count #"2s")>;
8651   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8652                         !cast<Operand>("VecList" # Count #"4s")>;
8653   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8654                         !cast<Operand>("VecList" # Count #"1d")>;
8655   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8656                         !cast<Operand>("VecList" # Count #"2d")>;
8657
8658   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8659                                  !cast<Operand>("VecList" # Count # "8b"),
8660                                  !cast<Operand>("GPR64pi" # Offset1)>;
8661   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8662                                  !cast<Operand>("VecList" # Count # "16b"),
8663                                  !cast<Operand>("GPR64pi" # Offset1)>;
8664   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8665                                  !cast<Operand>("VecList" # Count # "4h"),
8666                                  !cast<Operand>("GPR64pi" # Offset2)>;
8667   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8668                                  !cast<Operand>("VecList" # Count # "8h"),
8669                                  !cast<Operand>("GPR64pi" # Offset2)>;
8670   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8671                                  !cast<Operand>("VecList" # Count # "2s"),
8672                                  !cast<Operand>("GPR64pi" # Offset4)>;
8673   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8674                                  !cast<Operand>("VecList" # Count # "4s"),
8675                                  !cast<Operand>("GPR64pi" # Offset4)>;
8676   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8677                                  !cast<Operand>("VecList" # Count # "1d"),
8678                                  !cast<Operand>("GPR64pi" # Offset8)>;
8679   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8680                                  !cast<Operand>("VecList" # Count # "2d"),
8681                                  !cast<Operand>("GPR64pi" # Offset8)>;
8682
8683   defm : SIMDLdrAliases<asm, "8b",  Count, Offset1,  64>;
8684   defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8685   defm : SIMDLdrAliases<asm, "4h",  Count, Offset2,  64>;
8686   defm : SIMDLdrAliases<asm, "8h",  Count, Offset2, 128>;
8687   defm : SIMDLdrAliases<asm, "2s",  Count, Offset4,  64>;
8688   defm : SIMDLdrAliases<asm, "4s",  Count, Offset4, 128>;
8689   defm : SIMDLdrAliases<asm, "1d",  Count, Offset8,  64>;
8690   defm : SIMDLdrAliases<asm, "2d",  Count, Offset8, 128>;
8691 }
8692
8693 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8694                       dag oops, dag iops, list<dag> pattern>
8695   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8696                        pattern> {
8697   // idx encoded in Q:S:size fields.
8698   bits<4> idx;
8699   let Inst{30} = idx{3};
8700   let Inst{23} = 0;
8701   let Inst{20-16} = 0b00000;
8702   let Inst{12} = idx{2};
8703   let Inst{11-10} = idx{1-0};
8704 }
8705 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8706                       dag oops, dag iops, list<dag> pattern>
8707   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8708                            oops, iops, pattern> {
8709   // idx encoded in Q:S:size fields.
8710   bits<4> idx;
8711   let Inst{30} = idx{3};
8712   let Inst{23} = 0;
8713   let Inst{20-16} = 0b00000;
8714   let Inst{12} = idx{2};
8715   let Inst{11-10} = idx{1-0};
8716 }
8717 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8718                           dag oops, dag iops>
8719   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8720                        "$Rn = $wback", oops, iops, []> {
8721   // idx encoded in Q:S:size fields.
8722   bits<4> idx;
8723   bits<5> Xm;
8724   let Inst{30} = idx{3};
8725   let Inst{23} = 1;
8726   let Inst{20-16} = Xm;
8727   let Inst{12} = idx{2};
8728   let Inst{11-10} = idx{1-0};
8729 }
8730 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8731                           dag oops, dag iops>
8732   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8733                            "$Rn = $wback", oops, iops, []> {
8734   // idx encoded in Q:S:size fields.
8735   bits<4> idx;
8736   bits<5> Xm;
8737   let Inst{30} = idx{3};
8738   let Inst{23} = 1;
8739   let Inst{20-16} = Xm;
8740   let Inst{12} = idx{2};
8741   let Inst{11-10} = idx{1-0};
8742 }
8743
8744 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8745                       dag oops, dag iops, list<dag> pattern>
8746   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8747                        pattern> {
8748   // idx encoded in Q:S:size<1> fields.
8749   bits<3> idx;
8750   let Inst{30} = idx{2};
8751   let Inst{23} = 0;
8752   let Inst{20-16} = 0b00000;
8753   let Inst{12} = idx{1};
8754   let Inst{11} = idx{0};
8755   let Inst{10} = size;
8756 }
8757 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8758                       dag oops, dag iops, list<dag> pattern>
8759   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8760                            oops, iops, pattern> {
8761   // idx encoded in Q:S:size<1> fields.
8762   bits<3> idx;
8763   let Inst{30} = idx{2};
8764   let Inst{23} = 0;
8765   let Inst{20-16} = 0b00000;
8766   let Inst{12} = idx{1};
8767   let Inst{11} = idx{0};
8768   let Inst{10} = size;
8769 }
8770
8771 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8772                           dag oops, dag iops>
8773   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8774                        "$Rn = $wback", oops, iops, []> {
8775   // idx encoded in Q:S:size<1> fields.
8776   bits<3> idx;
8777   bits<5> Xm;
8778   let Inst{30} = idx{2};
8779   let Inst{23} = 1;
8780   let Inst{20-16} = Xm;
8781   let Inst{12} = idx{1};
8782   let Inst{11} = idx{0};
8783   let Inst{10} = size;
8784 }
8785 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8786                           dag oops, dag iops>
8787   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8788                            "$Rn = $wback", oops, iops, []> {
8789   // idx encoded in Q:S:size<1> fields.
8790   bits<3> idx;
8791   bits<5> Xm;
8792   let Inst{30} = idx{2};
8793   let Inst{23} = 1;
8794   let Inst{20-16} = Xm;
8795   let Inst{12} = idx{1};
8796   let Inst{11} = idx{0};
8797   let Inst{10} = size;
8798 }
8799 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8800                       dag oops, dag iops, list<dag> pattern>
8801   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8802                        pattern> {
8803   // idx encoded in Q:S fields.
8804   bits<2> idx;
8805   let Inst{30} = idx{1};
8806   let Inst{23} = 0;
8807   let Inst{20-16} = 0b00000;
8808   let Inst{12} = idx{0};
8809   let Inst{11-10} = size;
8810 }
8811 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8812                       dag oops, dag iops, list<dag> pattern>
8813   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8814                            oops, iops, pattern> {
8815   // idx encoded in Q:S fields.
8816   bits<2> idx;
8817   let Inst{30} = idx{1};
8818   let Inst{23} = 0;
8819   let Inst{20-16} = 0b00000;
8820   let Inst{12} = idx{0};
8821   let Inst{11-10} = size;
8822 }
8823 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8824                           string asm, dag oops, dag iops>
8825   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8826                        "$Rn = $wback", oops, iops, []> {
8827   // idx encoded in Q:S fields.
8828   bits<2> idx;
8829   bits<5> Xm;
8830   let Inst{30} = idx{1};
8831   let Inst{23} = 1;
8832   let Inst{20-16} = Xm;
8833   let Inst{12} = idx{0};
8834   let Inst{11-10} = size;
8835 }
8836 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8837                           string asm, dag oops, dag iops>
8838   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8839                            "$Rn = $wback", oops, iops, []> {
8840   // idx encoded in Q:S fields.
8841   bits<2> idx;
8842   bits<5> Xm;
8843   let Inst{30} = idx{1};
8844   let Inst{23} = 1;
8845   let Inst{20-16} = Xm;
8846   let Inst{12} = idx{0};
8847   let Inst{11-10} = size;
8848 }
8849 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8850                       dag oops, dag iops, list<dag> pattern>
8851   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8852                        pattern> {
8853   // idx encoded in Q field.
8854   bits<1> idx;
8855   let Inst{30} = idx;
8856   let Inst{23} = 0;
8857   let Inst{20-16} = 0b00000;
8858   let Inst{12} = 0;
8859   let Inst{11-10} = size;
8860 }
8861 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8862                       dag oops, dag iops, list<dag> pattern>
8863   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8864                            oops, iops, pattern> {
8865   // idx encoded in Q field.
8866   bits<1> idx;
8867   let Inst{30} = idx;
8868   let Inst{23} = 0;
8869   let Inst{20-16} = 0b00000;
8870   let Inst{12} = 0;
8871   let Inst{11-10} = size;
8872 }
8873 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8874                           string asm, dag oops, dag iops>
8875   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8876                        "$Rn = $wback", oops, iops, []> {
8877   // idx encoded in Q field.
8878   bits<1> idx;
8879   bits<5> Xm;
8880   let Inst{30} = idx;
8881   let Inst{23} = 1;
8882   let Inst{20-16} = Xm;
8883   let Inst{12} = 0;
8884   let Inst{11-10} = size;
8885 }
8886 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8887                           string asm, dag oops, dag iops>
8888   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8889                            "$Rn = $wback", oops, iops, []> {
8890   // idx encoded in Q field.
8891   bits<1> idx;
8892   bits<5> Xm;
8893   let Inst{30} = idx;
8894   let Inst{23} = 1;
8895   let Inst{20-16} = Xm;
8896   let Inst{12} = 0;
8897   let Inst{11-10} = size;
8898 }
8899
8900 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8901 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8902                          RegisterOperand listtype,
8903                          RegisterOperand GPR64pi> {
8904   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8905                            (outs listtype:$dst),
8906                            (ins listtype:$Vt, VectorIndexB:$idx,
8907                                 GPR64sp:$Rn), []>;
8908
8909   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8910                             (outs GPR64sp:$wback, listtype:$dst),
8911                             (ins listtype:$Vt, VectorIndexB:$idx,
8912                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8913 }
8914 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8915 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8916                          RegisterOperand listtype,
8917                          RegisterOperand GPR64pi> {
8918   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8919                             (outs listtype:$dst),
8920                             (ins listtype:$Vt, VectorIndexH:$idx,
8921                                  GPR64sp:$Rn), []>;
8922
8923   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8924                             (outs GPR64sp:$wback, listtype:$dst),
8925                             (ins listtype:$Vt, VectorIndexH:$idx,
8926                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8927 }
8928 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8929 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8930                          RegisterOperand listtype,
8931                          RegisterOperand GPR64pi> {
8932   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8933                             (outs listtype:$dst),
8934                             (ins listtype:$Vt, VectorIndexS:$idx,
8935                                  GPR64sp:$Rn), []>;
8936
8937   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8938                             (outs GPR64sp:$wback, listtype:$dst),
8939                             (ins listtype:$Vt, VectorIndexS:$idx,
8940                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8941 }
8942 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8943 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8944                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8945   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8946                             (outs listtype:$dst),
8947                             (ins listtype:$Vt, VectorIndexD:$idx,
8948                                  GPR64sp:$Rn), []>;
8949
8950   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8951                             (outs GPR64sp:$wback, listtype:$dst),
8952                             (ins listtype:$Vt, VectorIndexD:$idx,
8953                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8954 }
8955 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8956 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8957                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8958   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8959                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8960                                         GPR64sp:$Rn), []>;
8961
8962   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8963                                     (outs GPR64sp:$wback),
8964                                     (ins listtype:$Vt, VectorIndexB:$idx,
8965                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
8966 }
8967 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8968 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8969                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8970   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8971                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8972                                          GPR64sp:$Rn), []>;
8973
8974   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8975                             (outs GPR64sp:$wback),
8976                             (ins listtype:$Vt, VectorIndexH:$idx,
8977                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8978 }
8979 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8980 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8981                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8982   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8983                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8984                                          GPR64sp:$Rn), []>;
8985
8986   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8987                             (outs GPR64sp:$wback),
8988                             (ins listtype:$Vt, VectorIndexS:$idx,
8989                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8990 }
8991 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8992 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8993                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8994   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8995                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8996                                          GPR64sp:$Rn), []>;
8997
8998   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8999                             (outs GPR64sp:$wback),
9000                             (ins listtype:$Vt, VectorIndexD:$idx,
9001                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9002 }
9003
9004 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
9005                                  string Count, int Offset, Operand idxtype> {
9006   // E.g. "ld1 { v0.8b }[0], [x1], #1"
9007   //      "ld1\t$Vt, [$Rn], #1"
9008   // may get mapped to
9009   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9010   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
9011                   (!cast<Instruction>(NAME # Type  # "_POST")
9012                       GPR64sp:$Rn,
9013                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9014                       idxtype:$idx, XZR), 1>;
9015
9016   // E.g. "ld1.8b { v0 }[0], [x1], #1"
9017   //      "ld1.8b\t$Vt, [$Rn], #1"
9018   // may get mapped to
9019   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9020   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9021                   (!cast<Instruction>(NAME # Type # "_POST")
9022                       GPR64sp:$Rn,
9023                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9024                       idxtype:$idx, XZR), 0>;
9025
9026   // E.g. "ld1.8b { v0 }[0], [x1]"
9027   //      "ld1.8b\t$Vt, [$Rn]"
9028   // may get mapped to
9029   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9030   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9031                       (!cast<Instruction>(NAME # Type)
9032                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9033                          idxtype:$idx, GPR64sp:$Rn), 0>;
9034
9035   // E.g. "ld1.8b { v0 }[0], [x1], x2"
9036   //      "ld1.8b\t$Vt, [$Rn], $Xm"
9037   // may get mapped to
9038   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9039   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9040                       (!cast<Instruction>(NAME # Type # "_POST")
9041                          GPR64sp:$Rn,
9042                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9043                          idxtype:$idx,
9044                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9045 }
9046
9047 multiclass SIMDLdSt1SingleAliases<string asm> {
9048   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
9049   defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9050   defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9051   defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9052 }
9053
9054 multiclass SIMDLdSt2SingleAliases<string asm> {
9055   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
9056   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
9057   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
9058   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9059 }
9060
9061 multiclass SIMDLdSt3SingleAliases<string asm> {
9062   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
9063   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
9064   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9065   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9066 }
9067
9068 multiclass SIMDLdSt4SingleAliases<string asm> {
9069   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
9070   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
9071   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9072   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9073 }
9074 } // end of 'let Predicates = [HasNEON]'
9075
9076 //----------------------------------------------------------------------------
9077 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9078 //----------------------------------------------------------------------------
9079
9080 let Predicates = [HasNEON, HasRDM] in {
9081
9082 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9083                                     RegisterOperand regtype, string asm, 
9084                                     string kind, list<dag> pattern>
9085   : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 
9086                                 pattern> {
9087 }
9088 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9089                                              SDPatternOperator Accum> {
9090   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9091     [(set (v4i16 V64:$dst),
9092           (Accum (v4i16 V64:$Rd),
9093                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9094                                                    (v4i16 V64:$Rm)))))]>;         
9095   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
9096     [(set (v8i16 V128:$dst),
9097           (Accum (v8i16 V128:$Rd),
9098                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
9099                                                    (v8i16 V128:$Rm)))))]>;
9100   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
9101     [(set (v2i32 V64:$dst),
9102           (Accum (v2i32 V64:$Rd),
9103                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
9104                                                    (v2i32 V64:$Rm)))))]>;
9105   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
9106     [(set (v4i32 V128:$dst),
9107           (Accum (v4i32 V128:$Rd),
9108                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
9109                                                    (v4i32 V128:$Rm)))))]>;
9110 }
9111
9112 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
9113                                      SDPatternOperator Accum> {
9114   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9115                                           V64, V64, V128_lo, VectorIndexH,
9116                                           asm, ".4h", ".4h", ".4h", ".h",
9117     [(set (v4i16 V64:$dst),
9118           (Accum (v4i16 V64:$Rd),
9119                  (v4i16 (int_aarch64_neon_sqrdmulh
9120                           (v4i16 V64:$Rn),
9121                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9122                                                     VectorIndexH:$idx))))))]> {
9123     bits<3> idx;
9124     let Inst{11} = idx{2};
9125     let Inst{21} = idx{1};
9126     let Inst{20} = idx{0};
9127   }
9128
9129   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9130                                           V128, V128, V128_lo, VectorIndexH,
9131                                           asm, ".8h", ".8h", ".8h", ".h",
9132     [(set (v8i16 V128:$dst),
9133           (Accum (v8i16 V128:$Rd),
9134                  (v8i16 (int_aarch64_neon_sqrdmulh
9135                           (v8i16 V128:$Rn),
9136                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9137                                                    VectorIndexH:$idx))))))]> {
9138     bits<3> idx;
9139     let Inst{11} = idx{2};
9140     let Inst{21} = idx{1};
9141     let Inst{20} = idx{0};
9142   }
9143
9144   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9145                                           V64, V64, V128, VectorIndexS,
9146                                           asm, ".2s", ".2s", ".2s", ".s",
9147     [(set (v2i32 V64:$dst),
9148         (Accum (v2i32 V64:$Rd),
9149                (v2i32 (int_aarch64_neon_sqrdmulh
9150                         (v2i32 V64:$Rn),
9151                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
9152                                                  VectorIndexS:$idx))))))]> {
9153     bits<2> idx;
9154     let Inst{11} = idx{1};
9155     let Inst{21} = idx{0};
9156   }
9157
9158   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 
9159   // an intermediate EXTRACT_SUBREG would be untyped.
9160   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 
9161   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
9162   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9163                        (i32 (vector_extract 
9164                                (v4i32 (insert_subvector
9165                                        (undef), 
9166                                         (v2i32 (int_aarch64_neon_sqrdmulh 
9167                                                  (v2i32 V64:$Rn),
9168                                                  (v2i32 (AArch64duplane32 
9169                                                           (v4i32 V128:$Rm),
9170                                                           VectorIndexS:$idx)))),
9171                                       (i32 0))),
9172                                (i64 0))))),
9173             (EXTRACT_SUBREG
9174                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
9175                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 
9176                                                 FPR32Op:$Rd, 
9177                                                 ssub)), 
9178                           V64:$Rn,
9179                           V128:$Rm, 
9180                           VectorIndexS:$idx)),
9181                 ssub)>;
9182
9183   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9184                                           V128, V128, V128, VectorIndexS,
9185                                           asm, ".4s", ".4s", ".4s", ".s",
9186     [(set (v4i32 V128:$dst),
9187           (Accum (v4i32 V128:$Rd),
9188                  (v4i32 (int_aarch64_neon_sqrdmulh
9189                           (v4i32 V128:$Rn),
9190                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
9191                                                    VectorIndexS:$idx))))))]> {
9192     bits<2> idx;
9193     let Inst{11} = idx{1};
9194     let Inst{21} = idx{0};
9195   }
9196
9197   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9198   // an intermediate EXTRACT_SUBREG would be untyped.
9199   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9200                         (i32 (vector_extract 
9201                                (v4i32 (int_aarch64_neon_sqrdmulh 
9202                                         (v4i32 V128:$Rn),
9203                                         (v4i32 (AArch64duplane32 
9204                                                  (v4i32 V128:$Rm),
9205                                                  VectorIndexS:$idx)))),
9206                                (i64 0))))),
9207             (EXTRACT_SUBREG
9208                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
9209                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 
9210                                                FPR32Op:$Rd, 
9211                                                ssub)), 
9212                          V128:$Rn,
9213                          V128:$Rm, 
9214                          VectorIndexS:$idx)),
9215                 ssub)>;
9216
9217   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9218                                         FPR16Op, FPR16Op, V128_lo,
9219                                         VectorIndexH, asm, ".h", "", "", ".h", 
9220                                         []> {
9221     bits<3> idx;
9222     let Inst{11} = idx{2};
9223     let Inst{21} = idx{1};
9224     let Inst{20} = idx{0};
9225   }
9226
9227   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9228                                         FPR32Op, FPR32Op, V128, VectorIndexS,
9229                                         asm, ".s", "", "", ".s",
9230     [(set (i32 FPR32Op:$dst),
9231           (Accum (i32 FPR32Op:$Rd),
9232                  (i32 (int_aarch64_neon_sqrdmulh
9233                         (i32 FPR32Op:$Rn),
9234                         (i32 (vector_extract (v4i32 V128:$Rm),
9235                                              VectorIndexS:$idx))))))]> {
9236     bits<2> idx;
9237     let Inst{11} = idx{1};
9238     let Inst{21} = idx{0};
9239   }
9240 }
9241 } // let Predicates = [HasNeon, HasRDM]
9242
9243 //----------------------------------------------------------------------------
9244 // Crypto extensions
9245 //----------------------------------------------------------------------------
9246
9247 let Predicates = [HasCrypto] in {
9248 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9249 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
9250               list<dag> pat>
9251   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
9252     Sched<[WriteV]>{
9253   bits<5> Rd;
9254   bits<5> Rn;
9255   let Inst{31-16} = 0b0100111000101000;
9256   let Inst{15-12} = opc;
9257   let Inst{11-10} = 0b10;
9258   let Inst{9-5}   = Rn;
9259   let Inst{4-0}   = Rd;
9260 }
9261
9262 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9263   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9264             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9265
9266 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9267   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9268             "$Rd = $dst",
9269             [(set (v16i8 V128:$dst),
9270                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9271
9272 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9273 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9274                      dag oops, dag iops, list<dag> pat>
9275   : I<oops, iops, asm,
9276       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9277       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9278     Sched<[WriteV]>{
9279   bits<5> Rd;
9280   bits<5> Rn;
9281   bits<5> Rm;
9282   let Inst{31-21} = 0b01011110000;
9283   let Inst{20-16} = Rm;
9284   let Inst{15}    = 0;
9285   let Inst{14-12} = opc;
9286   let Inst{11-10} = 0b00;
9287   let Inst{9-5}   = Rn;
9288   let Inst{4-0}   = Rd;
9289 }
9290
9291 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9292   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9293                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9294                    [(set (v4i32 FPR128:$dst),
9295                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9296                                  (v4i32 V128:$Rm)))]>;
9297
9298 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9299   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9300                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
9301                    [(set (v4i32 V128:$dst),
9302                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9303                                  (v4i32 V128:$Rm)))]>;
9304
9305 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9306   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9307                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
9308                    [(set (v4i32 FPR128:$dst),
9309                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
9310                                  (v4i32 V128:$Rm)))]>;
9311
9312 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9313 class SHA2OpInst<bits<4> opc, string asm, string kind,
9314                  string cstr, dag oops, dag iops,
9315                  list<dag> pat>
9316   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
9317                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
9318     Sched<[WriteV]>{
9319   bits<5> Rd;
9320   bits<5> Rn;
9321   let Inst{31-16} = 0b0101111000101000;
9322   let Inst{15-12} = opc;
9323   let Inst{11-10} = 0b10;
9324   let Inst{9-5}   = Rn;
9325   let Inst{4-0}   = Rd;
9326 }
9327
9328 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
9329   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
9330                (ins V128:$Rd, V128:$Rn),
9331                [(set (v4i32 V128:$dst),
9332                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
9333
9334 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
9335   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
9336                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
9337 } // end of 'let Predicates = [HasCrypto]'
9338
9339 //----------------------------------------------------------------------------
9340 // v8.1 atomic instructions extension:
9341 // * CAS
9342 // * CASP
9343 // * SWP
9344 // * LDOPregister<OP>, and aliases STOPregister<OP>
9345
9346 // Instruction encodings:
9347 //
9348 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
9349 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
9350 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
9351 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
9352 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
9353 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
9354
9355 // Instruction syntax:
9356 //
9357 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9358 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
9359 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
9360 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
9361 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9362 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
9363 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9364 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
9365 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
9366 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
9367
9368 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9369 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
9370                       string cstr, list<dag> pattern>
9371       : I<oops, iops, asm, operands, cstr, pattern> {
9372   bits<2> Sz;
9373   bit NP;
9374   bit Acq;
9375   bit Rel;
9376   bits<5> Rs;
9377   bits<5> Rn;
9378   bits<5> Rt;
9379   let Inst{31-30} = Sz;
9380   let Inst{29-24} = 0b001000;
9381   let Inst{23} = NP;
9382   let Inst{22} = Acq;
9383   let Inst{21} = 0b1;
9384   let Inst{20-16} = Rs;
9385   let Inst{15} = Rel;
9386   let Inst{14-10} = 0b11111;
9387   let Inst{9-5} = Rn;
9388   let Inst{4-0} = Rt;
9389   let Predicates = [HasLSE];
9390 }
9391
9392 class BaseCAS<string order, string size, RegisterClass RC>
9393       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9394                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
9395                         "$out = $Rs",[]>,
9396         Sched<[WriteAtomic]> {
9397   let NP = 1;
9398 }
9399
9400 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
9401   let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
9402   let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
9403   let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
9404   let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
9405 }
9406
9407 class BaseCASP<string order, string size, RegisterOperand RC>
9408       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9409                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
9410                         "$out = $Rs",[]>,
9411         Sched<[WriteAtomic]> {
9412   let NP = 0;
9413 }
9414
9415 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9416   let Sz = 0b00, Acq = Acq, Rel = Rel in 
9417     def s : BaseCASP<order, "", WSeqPairClassOperand>;
9418   let Sz = 0b01, Acq = Acq, Rel = Rel in 
9419     def d : BaseCASP<order, "", XSeqPairClassOperand>;
9420 }
9421
9422 let Predicates = [HasLSE] in
9423 class BaseSWP<string order, string size, RegisterClass RC>
9424       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9425           "\t$Rs, $Rt, [$Rn]","",[]>,
9426         Sched<[WriteAtomic]> {
9427   bits<2> Sz;
9428   bit Acq;
9429   bit Rel;
9430   bits<5> Rs;
9431   bits<3> opc = 0b000;
9432   bits<5> Rn;
9433   bits<5> Rt;
9434   let Inst{31-30} = Sz;
9435   let Inst{29-24} = 0b111000;
9436   let Inst{23} = Acq;
9437   let Inst{22} = Rel;
9438   let Inst{21} = 0b1;
9439   let Inst{20-16} = Rs;
9440   let Inst{15} = 0b1;
9441   let Inst{14-12} = opc;
9442   let Inst{11-10} = 0b00;
9443   let Inst{9-5} = Rn;
9444   let Inst{4-0} = Rt;
9445   let Predicates = [HasLSE];
9446 }
9447
9448 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9449   let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
9450   let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
9451   let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
9452   let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
9453 }
9454
9455 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9456 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9457       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9458           "\t$Rs, $Rt, [$Rn]","",[]>,
9459         Sched<[WriteAtomic]> {
9460   bits<2> Sz;
9461   bit Acq;
9462   bit Rel;
9463   bits<5> Rs;
9464   bits<3> opc;
9465   bits<5> Rn;
9466   bits<5> Rt;
9467   let Inst{31-30} = Sz;
9468   let Inst{29-24} = 0b111000;
9469   let Inst{23} = Acq;
9470   let Inst{22} = Rel;
9471   let Inst{21} = 0b1;
9472   let Inst{20-16} = Rs;
9473   let Inst{15} = 0b0;
9474   let Inst{14-12} = opc;
9475   let Inst{11-10} = 0b00;
9476   let Inst{9-5} = Rn;
9477   let Inst{4-0} = Rt;
9478   let Predicates = [HasLSE];
9479 }
9480
9481 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 
9482                         string order> {
9483   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 
9484     def b : BaseLDOPregister<op, order, "b", GPR32>;
9485   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 
9486     def h : BaseLDOPregister<op, order, "h", GPR32>;
9487   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 
9488     def s : BaseLDOPregister<op, order, "", GPR32>;
9489   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 
9490     def d : BaseLDOPregister<op, order, "", GPR64>;
9491 }
9492
9493 let Predicates = [HasLSE] in
9494 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9495                         Instruction inst> :
9496       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9497
9498 multiclass STOPregister<string asm, string instr> {
9499   def : BaseSTOPregister<asm # "lb", GPR32, WZR, 
9500                     !cast<Instruction>(instr # "Lb")>;
9501   def : BaseSTOPregister<asm # "lh", GPR32, WZR, 
9502                     !cast<Instruction>(instr # "Lh")>;
9503   def : BaseSTOPregister<asm # "l",  GPR32, WZR, 
9504                     !cast<Instruction>(instr # "Ls")>;
9505   def : BaseSTOPregister<asm # "l",  GPR64, XZR, 
9506                     !cast<Instruction>(instr # "Ld")>;
9507   def : BaseSTOPregister<asm # "b",  GPR32, WZR, 
9508                     !cast<Instruction>(instr # "b")>;
9509   def : BaseSTOPregister<asm # "h",  GPR32, WZR, 
9510                     !cast<Instruction>(instr # "h")>;
9511   def : BaseSTOPregister<asm,        GPR32, WZR, 
9512                     !cast<Instruction>(instr # "s")>;
9513   def : BaseSTOPregister<asm,        GPR64, XZR, 
9514                     !cast<Instruction>(instr # "d")>;
9515 }
9516
9517 //----------------------------------------------------------------------------
9518 // Allow the size specifier tokens to be upper case, not just lower.
9519 def : TokenAlias<".8B", ".8b">;
9520 def : TokenAlias<".4H", ".4h">;
9521 def : TokenAlias<".2S", ".2s">;
9522 def : TokenAlias<".1D", ".1d">;
9523 def : TokenAlias<".16B", ".16b">;
9524 def : TokenAlias<".8H", ".8h">;
9525 def : TokenAlias<".4S", ".4s">;
9526 def : TokenAlias<".2D", ".2d">;
9527 def : TokenAlias<".1Q", ".1q">;
9528 def : TokenAlias<".2H", ".2h">;
9529 def : TokenAlias<".B", ".b">;
9530 def : TokenAlias<".H", ".h">;
9531 def : TokenAlias<".S", ".s">;
9532 def : TokenAlias<".D", ".d">;
9533 def : TokenAlias<".Q", ".q">;