]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AArch64/AArch64InstrFormats.td
MFV r337184: 9457 libzfs_import.c:add_config() has a memory leak
[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 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
193 def SImm10s8Operand : AsmOperandClass {
194   let Name = "SImm10s8";
195   let DiagnosticType = "InvalidMemoryIndexedSImm10";
196 }
197
198 //===----------------------------------------------------------------------===//
199 // Operand Definitions.
200 //
201
202 // ADR[P] instruction labels.
203 def AdrpOperand : AsmOperandClass {
204   let Name = "AdrpLabel";
205   let ParserMethod = "tryParseAdrpLabel";
206   let DiagnosticType = "InvalidLabel";
207 }
208 def adrplabel : Operand<i64> {
209   let EncoderMethod = "getAdrLabelOpValue";
210   let PrintMethod = "printAdrpLabel";
211   let ParserMatchClass = AdrpOperand;
212 }
213
214 def AdrOperand : AsmOperandClass {
215   let Name = "AdrLabel";
216   let ParserMethod = "tryParseAdrLabel";
217   let DiagnosticType = "InvalidLabel";
218 }
219 def adrlabel : Operand<i64> {
220   let EncoderMethod = "getAdrLabelOpValue";
221   let ParserMatchClass = AdrOperand;
222 }
223
224 def simm10Scaled : Operand<i64> {
225   let ParserMatchClass = SImm10s8Operand;
226   let DecoderMethod = "DecodeSImm<10>";
227   let PrintMethod = "printImmScale<8>";
228 }
229
230 // simm9 predicate - True if the immediate is in the range [-256, 255].
231 def SImm9Operand : AsmOperandClass {
232   let Name = "SImm9";
233   let DiagnosticType = "InvalidMemoryIndexedSImm9";
234 }
235 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
236   let ParserMatchClass = SImm9Operand;
237 }
238
239 // simm7sN predicate - True if the immediate is a multiple of N in the range
240 // [-64 * N, 63 * N].
241 class SImm7Scaled<int Scale> : AsmOperandClass {
242   let Name = "SImm7s" # Scale;
243   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
244 }
245
246 def SImm7s4Operand : SImm7Scaled<4>;
247 def SImm7s8Operand : SImm7Scaled<8>;
248 def SImm7s16Operand : SImm7Scaled<16>;
249
250 def simm7s4 : Operand<i32> {
251   let ParserMatchClass = SImm7s4Operand;
252   let PrintMethod = "printImmScale<4>";
253 }
254
255 def simm7s8 : Operand<i32> {
256   let ParserMatchClass = SImm7s8Operand;
257   let PrintMethod = "printImmScale<8>";
258 }
259
260 def simm7s16 : Operand<i32> {
261   let ParserMatchClass = SImm7s16Operand;
262   let PrintMethod = "printImmScale<16>";
263 }
264
265 def am_indexed7s8   : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
266 def am_indexed7s16  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
267 def am_indexed7s32  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
268 def am_indexed7s64  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
269 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
270
271 class AsmImmRange<int Low, int High> : AsmOperandClass {
272   let Name = "Imm" # Low # "_" # High;
273   let DiagnosticType = "InvalidImm" # Low # "_" # High;
274   let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
275 }
276
277 def Imm1_8Operand : AsmImmRange<1, 8>;
278 def Imm1_16Operand : AsmImmRange<1, 16>;
279 def Imm1_32Operand : AsmImmRange<1, 32>;
280 def Imm1_64Operand : AsmImmRange<1, 64>;
281
282 class BranchTarget<int N> : AsmOperandClass {
283   let Name = "BranchTarget" # N;
284   let DiagnosticType = "InvalidLabel";
285   let PredicateMethod = "isBranchTarget<" # N # ">";
286 }
287
288 class PCRelLabel<int N> : BranchTarget<N> {
289   let Name = "PCRelLabel" # N;
290 }
291
292 def BranchTarget14Operand : BranchTarget<14>;
293 def BranchTarget26Operand : BranchTarget<26>;
294 def PCRelLabel19Operand   : PCRelLabel<19>;
295
296 def MovZSymbolG3AsmOperand : AsmOperandClass {
297   let Name = "MovZSymbolG3";
298   let RenderMethod = "addImmOperands";
299 }
300
301 def movz_symbol_g3 : Operand<i32> {
302   let ParserMatchClass = MovZSymbolG3AsmOperand;
303 }
304
305 def MovZSymbolG2AsmOperand : AsmOperandClass {
306   let Name = "MovZSymbolG2";
307   let RenderMethod = "addImmOperands";
308 }
309
310 def movz_symbol_g2 : Operand<i32> {
311   let ParserMatchClass = MovZSymbolG2AsmOperand;
312 }
313
314 def MovZSymbolG1AsmOperand : AsmOperandClass {
315   let Name = "MovZSymbolG1";
316   let RenderMethod = "addImmOperands";
317 }
318
319 def movz_symbol_g1 : Operand<i32> {
320   let ParserMatchClass = MovZSymbolG1AsmOperand;
321 }
322
323 def MovZSymbolG0AsmOperand : AsmOperandClass {
324   let Name = "MovZSymbolG0";
325   let RenderMethod = "addImmOperands";
326 }
327
328 def movz_symbol_g0 : Operand<i32> {
329   let ParserMatchClass = MovZSymbolG0AsmOperand;
330 }
331
332 def MovKSymbolG3AsmOperand : AsmOperandClass {
333   let Name = "MovKSymbolG3";
334   let RenderMethod = "addImmOperands";
335 }
336
337 def movk_symbol_g3 : Operand<i32> {
338   let ParserMatchClass = MovKSymbolG3AsmOperand;
339 }
340
341 def MovKSymbolG2AsmOperand : AsmOperandClass {
342   let Name = "MovKSymbolG2";
343   let RenderMethod = "addImmOperands";
344 }
345
346 def movk_symbol_g2 : Operand<i32> {
347   let ParserMatchClass = MovKSymbolG2AsmOperand;
348 }
349
350 def MovKSymbolG1AsmOperand : AsmOperandClass {
351   let Name = "MovKSymbolG1";
352   let RenderMethod = "addImmOperands";
353 }
354
355 def movk_symbol_g1 : Operand<i32> {
356   let ParserMatchClass = MovKSymbolG1AsmOperand;
357 }
358
359 def MovKSymbolG0AsmOperand : AsmOperandClass {
360   let Name = "MovKSymbolG0";
361   let RenderMethod = "addImmOperands";
362 }
363
364 def movk_symbol_g0 : Operand<i32> {
365   let ParserMatchClass = MovKSymbolG0AsmOperand;
366 }
367
368 class fixedpoint_i32<ValueType FloatVT>
369   : Operand<FloatVT>,
370     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
371   let EncoderMethod = "getFixedPointScaleOpValue";
372   let DecoderMethod = "DecodeFixedPointScaleImm32";
373   let ParserMatchClass = Imm1_32Operand;
374 }
375
376 class fixedpoint_i64<ValueType FloatVT>
377   : Operand<FloatVT>,
378     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
379   let EncoderMethod = "getFixedPointScaleOpValue";
380   let DecoderMethod = "DecodeFixedPointScaleImm64";
381   let ParserMatchClass = Imm1_64Operand;
382 }
383
384 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
385 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
386 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
387
388 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
389 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
390 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
391
392 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
393   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
394 }]> {
395   let EncoderMethod = "getVecShiftR8OpValue";
396   let DecoderMethod = "DecodeVecShiftR8Imm";
397   let ParserMatchClass = Imm1_8Operand;
398 }
399 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
400   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
401 }]> {
402   let EncoderMethod = "getVecShiftR16OpValue";
403   let DecoderMethod = "DecodeVecShiftR16Imm";
404   let ParserMatchClass = Imm1_16Operand;
405 }
406 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
407   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
408 }]> {
409   let EncoderMethod = "getVecShiftR16OpValue";
410   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
411   let ParserMatchClass = Imm1_8Operand;
412 }
413 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
414   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
415 }]> {
416   let EncoderMethod = "getVecShiftR32OpValue";
417   let DecoderMethod = "DecodeVecShiftR32Imm";
418   let ParserMatchClass = Imm1_32Operand;
419 }
420 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
421   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
422 }]> {
423   let EncoderMethod = "getVecShiftR32OpValue";
424   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
425   let ParserMatchClass = Imm1_16Operand;
426 }
427 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
428   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
429 }]> {
430   let EncoderMethod = "getVecShiftR64OpValue";
431   let DecoderMethod = "DecodeVecShiftR64Imm";
432   let ParserMatchClass = Imm1_64Operand;
433 }
434 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
435   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
436 }]> {
437   let EncoderMethod = "getVecShiftR64OpValue";
438   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
439   let ParserMatchClass = Imm1_32Operand;
440 }
441
442 def Imm0_1Operand : AsmImmRange<0, 1>;
443 def Imm0_7Operand : AsmImmRange<0, 7>;
444 def Imm0_15Operand : AsmImmRange<0, 15>;
445 def Imm0_31Operand : AsmImmRange<0, 31>;
446 def Imm0_63Operand : AsmImmRange<0, 63>;
447
448 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
449   return (((uint32_t)Imm) < 8);
450 }]> {
451   let EncoderMethod = "getVecShiftL8OpValue";
452   let DecoderMethod = "DecodeVecShiftL8Imm";
453   let ParserMatchClass = Imm0_7Operand;
454 }
455 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
456   return (((uint32_t)Imm) < 16);
457 }]> {
458   let EncoderMethod = "getVecShiftL16OpValue";
459   let DecoderMethod = "DecodeVecShiftL16Imm";
460   let ParserMatchClass = Imm0_15Operand;
461 }
462 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
463   return (((uint32_t)Imm) < 32);
464 }]> {
465   let EncoderMethod = "getVecShiftL32OpValue";
466   let DecoderMethod = "DecodeVecShiftL32Imm";
467   let ParserMatchClass = Imm0_31Operand;
468 }
469 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
470   return (((uint32_t)Imm) < 64);
471 }]> {
472   let EncoderMethod = "getVecShiftL64OpValue";
473   let DecoderMethod = "DecodeVecShiftL64Imm";
474   let ParserMatchClass = Imm0_63Operand;
475 }
476
477
478 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
479 // instructions for splatting repeating bit patterns across the immediate.
480 def logical_imm32_XFORM : SDNodeXForm<imm, [{
481   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
482   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
483 }]>;
484 def logical_imm64_XFORM : SDNodeXForm<imm, [{
485   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
486   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
487 }]>;
488
489 let DiagnosticType = "LogicalSecondSource" in {
490   def LogicalImm32Operand : AsmOperandClass {
491     let Name = "LogicalImm32";
492   }
493   def LogicalImm64Operand : AsmOperandClass {
494     let Name = "LogicalImm64";
495   }
496   def LogicalImm32NotOperand : AsmOperandClass {
497     let Name = "LogicalImm32Not";
498   }
499   def LogicalImm64NotOperand : AsmOperandClass {
500     let Name = "LogicalImm64Not";
501   }
502 }
503 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
504   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
505 }], logical_imm32_XFORM> {
506   let PrintMethod = "printLogicalImm32";
507   let ParserMatchClass = LogicalImm32Operand;
508 }
509 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
510   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
511 }], logical_imm64_XFORM> {
512   let PrintMethod = "printLogicalImm64";
513   let ParserMatchClass = LogicalImm64Operand;
514 }
515 def logical_imm32_not : Operand<i32> {
516   let ParserMatchClass = LogicalImm32NotOperand;
517 }
518 def logical_imm64_not : Operand<i64> {
519   let ParserMatchClass = LogicalImm64NotOperand;
520 }
521
522 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
523 def Imm0_65535Operand : AsmImmRange<0, 65535>;
524 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
525   return ((uint32_t)Imm) < 65536;
526 }]> {
527   let ParserMatchClass = Imm0_65535Operand;
528   let PrintMethod = "printImmHex";
529 }
530
531 // imm0_255 predicate - True if the immediate is in the range [0,255].
532 def Imm0_255Operand : AsmImmRange<0,255>;
533
534 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
535   return ((uint32_t)Imm) < 256;
536 }]> {
537   let ParserMatchClass = Imm0_255Operand;
538   let PrintMethod = "printImm";
539 }
540
541 // imm0_127 predicate - True if the immediate is in the range [0,127]
542 def Imm0_127Operand : AsmImmRange<0, 127>;
543 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
544   return ((uint32_t)Imm) < 128;
545 }]> {
546   let ParserMatchClass = Imm0_127Operand;
547   let PrintMethod = "printImm";
548 }
549
550 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
551 // for all shift-amounts.
552
553 // imm0_63 predicate - True if the immediate is in the range [0,63]
554 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
555   return ((uint64_t)Imm) < 64;
556 }]> {
557   let ParserMatchClass = Imm0_63Operand;
558 }
559
560 // imm0_31 predicate - True if the immediate is in the range [0,31]
561 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
562   return ((uint64_t)Imm) < 32;
563 }]> {
564   let ParserMatchClass = Imm0_31Operand;
565 }
566
567 // True if the 32-bit immediate is in the range [0,31]
568 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
569   return ((uint64_t)Imm) < 32;
570 }]> {
571   let ParserMatchClass = Imm0_31Operand;
572 }
573
574 // imm0_1 predicate - True if the immediate is in the range [0,1]
575 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
576   return ((uint64_t)Imm) < 2;
577 }]> {
578   let ParserMatchClass = Imm0_1Operand;
579 }
580
581 // imm0_15 predicate - True if the immediate is in the range [0,15]
582 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
583   return ((uint64_t)Imm) < 16;
584 }]> {
585   let ParserMatchClass = Imm0_15Operand;
586 }
587
588 // imm0_7 predicate - True if the immediate is in the range [0,7]
589 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
590   return ((uint64_t)Imm) < 8;
591 }]> {
592   let ParserMatchClass = Imm0_7Operand;
593 }
594
595 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
596 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
597   return ((uint32_t)Imm) < 16;
598 }]> {
599   let ParserMatchClass = Imm0_15Operand;
600 }
601
602 // An arithmetic shifter operand:
603 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
604 //  {5-0} - imm6
605 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
606   let PrintMethod = "printShifter";
607   let ParserMatchClass = !cast<AsmOperandClass>(
608                          "ArithmeticShifterOperand" # width);
609 }
610
611 def arith_shift32 : arith_shift<i32, 32>;
612 def arith_shift64 : arith_shift<i64, 64>;
613
614 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
615     : Operand<Ty>,
616       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
617   let PrintMethod = "printShiftedRegister";
618   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
619 }
620
621 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
622 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
623
624 // An arithmetic shifter operand:
625 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
626 //  {5-0} - imm6
627 class logical_shift<int width> : Operand<i32> {
628   let PrintMethod = "printShifter";
629   let ParserMatchClass = !cast<AsmOperandClass>(
630                          "LogicalShifterOperand" # width);
631 }
632
633 def logical_shift32 : logical_shift<32>;
634 def logical_shift64 : logical_shift<64>;
635
636 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
637     : Operand<Ty>,
638       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
639   let PrintMethod = "printShiftedRegister";
640   let MIOperandInfo = (ops regclass, shiftop);
641 }
642
643 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
644 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
645
646 // A logical vector shifter operand:
647 //  {7-6} - shift type: 00 = lsl
648 //  {5-0} - imm6: #0, #8, #16, or #24
649 def logical_vec_shift : Operand<i32> {
650   let PrintMethod = "printShifter";
651   let EncoderMethod = "getVecShifterOpValue";
652   let ParserMatchClass = LogicalVecShifterOperand;
653 }
654
655 // A logical vector half-word shifter operand:
656 //  {7-6} - shift type: 00 = lsl
657 //  {5-0} - imm6: #0 or #8
658 def logical_vec_hw_shift : Operand<i32> {
659   let PrintMethod = "printShifter";
660   let EncoderMethod = "getVecShifterOpValue";
661   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
662 }
663
664 // A vector move shifter operand:
665 //  {0} - imm1: #8 or #16
666 def move_vec_shift : Operand<i32> {
667   let PrintMethod = "printShifter";
668   let EncoderMethod = "getMoveVecShifterOpValue";
669   let ParserMatchClass = MoveVecShifterOperand;
670 }
671
672 let DiagnosticType = "AddSubSecondSource" in {
673   def AddSubImmOperand : AsmOperandClass {
674     let Name = "AddSubImm";
675     let ParserMethod = "tryParseAddSubImm";
676   }
677   def AddSubImmNegOperand : AsmOperandClass {
678     let Name = "AddSubImmNeg";
679     let ParserMethod = "tryParseAddSubImm";
680   }
681 }
682 // An ADD/SUB immediate shifter operand:
683 //  second operand:
684 //  {7-6} - shift type: 00 = lsl
685 //  {5-0} - imm6: #0 or #12
686 class addsub_shifted_imm<ValueType Ty>
687     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
688   let PrintMethod = "printAddSubImm";
689   let EncoderMethod = "getAddSubImmOpValue";
690   let ParserMatchClass = AddSubImmOperand;
691   let MIOperandInfo = (ops i32imm, i32imm);
692 }
693
694 class addsub_shifted_imm_neg<ValueType Ty>
695     : Operand<Ty> {
696   let EncoderMethod = "getAddSubImmOpValue";
697   let ParserMatchClass = AddSubImmNegOperand;
698   let MIOperandInfo = (ops i32imm, i32imm);
699 }
700
701 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
702 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
703 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
704 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
705
706 def gi_addsub_shifted_imm32 :
707     GIComplexOperandMatcher<s32, "selectArithImmed">,
708     GIComplexPatternEquiv<addsub_shifted_imm32>;
709
710 def gi_addsub_shifted_imm64 :
711     GIComplexOperandMatcher<s64, "selectArithImmed">,
712     GIComplexPatternEquiv<addsub_shifted_imm64>;
713
714 class neg_addsub_shifted_imm<ValueType Ty>
715     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
716   let PrintMethod = "printAddSubImm";
717   let EncoderMethod = "getAddSubImmOpValue";
718   let ParserMatchClass = AddSubImmOperand;
719   let MIOperandInfo = (ops i32imm, i32imm);
720 }
721
722 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
723 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
724
725 // An extend operand:
726 //  {5-3} - extend type
727 //  {2-0} - imm3
728 def arith_extend : Operand<i32> {
729   let PrintMethod = "printArithExtend";
730   let ParserMatchClass = ExtendOperand;
731 }
732 def arith_extend64 : Operand<i32> {
733   let PrintMethod = "printArithExtend";
734   let ParserMatchClass = ExtendOperand64;
735 }
736
737 // 'extend' that's a lsl of a 64-bit register.
738 def arith_extendlsl64 : Operand<i32> {
739   let PrintMethod = "printArithExtend";
740   let ParserMatchClass = ExtendOperandLSL64;
741 }
742
743 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
744                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
745   let PrintMethod = "printExtendedRegister";
746   let MIOperandInfo = (ops GPR32, arith_extend);
747 }
748
749 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
750                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
751   let PrintMethod = "printExtendedRegister";
752   let MIOperandInfo = (ops GPR32, arith_extend64);
753 }
754
755 // Floating-point immediate.
756 def fpimm16 : Operand<f16>,
757               FPImmLeaf<f16, [{
758       return AArch64_AM::getFP16Imm(Imm) != -1;
759     }], SDNodeXForm<fpimm, [{
760       APFloat InVal = N->getValueAPF();
761       uint32_t enc = AArch64_AM::getFP16Imm(InVal);
762       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
763     }]>> {
764   let ParserMatchClass = FPImmOperand;
765   let PrintMethod = "printFPImmOperand";
766 }
767 def fpimm32 : Operand<f32>,
768               FPImmLeaf<f32, [{
769       return AArch64_AM::getFP32Imm(Imm) != -1;
770     }], SDNodeXForm<fpimm, [{
771       APFloat InVal = N->getValueAPF();
772       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
773       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
774     }]>> {
775   let ParserMatchClass = FPImmOperand;
776   let PrintMethod = "printFPImmOperand";
777 }
778 def fpimm64 : Operand<f64>,
779               FPImmLeaf<f64, [{
780       return AArch64_AM::getFP64Imm(Imm) != -1;
781     }], SDNodeXForm<fpimm, [{
782       APFloat InVal = N->getValueAPF();
783       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
784       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
785     }]>> {
786   let ParserMatchClass = FPImmOperand;
787   let PrintMethod = "printFPImmOperand";
788 }
789
790 def fpimm8 : Operand<i32> {
791   let ParserMatchClass = FPImmOperand;
792   let PrintMethod = "printFPImmOperand";
793 }
794
795 def fpimm0 : FPImmLeaf<fAny, [{
796   return Imm.isExactlyValue(+0.0);
797 }]>;
798
799 // Vector lane operands
800 class AsmVectorIndex<string Suffix> : AsmOperandClass {
801   let Name = "VectorIndex" # Suffix;
802   let DiagnosticType = "InvalidIndex" # Suffix;
803 }
804 def VectorIndex1Operand : AsmVectorIndex<"1">;
805 def VectorIndexBOperand : AsmVectorIndex<"B">;
806 def VectorIndexHOperand : AsmVectorIndex<"H">;
807 def VectorIndexSOperand : AsmVectorIndex<"S">;
808 def VectorIndexDOperand : AsmVectorIndex<"D">;
809
810 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
811   return ((uint64_t)Imm) == 1;
812 }]> {
813   let ParserMatchClass = VectorIndex1Operand;
814   let PrintMethod = "printVectorIndex";
815   let MIOperandInfo = (ops i64imm);
816 }
817 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
818   return ((uint64_t)Imm) < 16;
819 }]> {
820   let ParserMatchClass = VectorIndexBOperand;
821   let PrintMethod = "printVectorIndex";
822   let MIOperandInfo = (ops i64imm);
823 }
824 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
825   return ((uint64_t)Imm) < 8;
826 }]> {
827   let ParserMatchClass = VectorIndexHOperand;
828   let PrintMethod = "printVectorIndex";
829   let MIOperandInfo = (ops i64imm);
830 }
831 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
832   return ((uint64_t)Imm) < 4;
833 }]> {
834   let ParserMatchClass = VectorIndexSOperand;
835   let PrintMethod = "printVectorIndex";
836   let MIOperandInfo = (ops i64imm);
837 }
838 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
839   return ((uint64_t)Imm) < 2;
840 }]> {
841   let ParserMatchClass = VectorIndexDOperand;
842   let PrintMethod = "printVectorIndex";
843   let MIOperandInfo = (ops i64imm);
844 }
845
846 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
847 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
848 // are encoded as the eight bit value 'abcdefgh'.
849 def simdimmtype10 : Operand<i32>,
850                     FPImmLeaf<f64, [{
851       return AArch64_AM::isAdvSIMDModImmType10(
852                  Imm.bitcastToAPInt().getZExtValue());
853     }], SDNodeXForm<fpimm, [{
854       APFloat InVal = N->getValueAPF();
855       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
856                                                            .bitcastToAPInt()
857                                                            .getZExtValue());
858       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
859     }]>> {
860   let ParserMatchClass = SIMDImmType10Operand;
861   let PrintMethod = "printSIMDType10Operand";
862 }
863
864
865 //---
866 // System management
867 //---
868
869 // Base encoding for system instruction operands.
870 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
871 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
872                   list<dag> pattern = []>
873     : I<oops, iops, asm, operands, "", pattern> {
874   let Inst{31-22} = 0b1101010100;
875   let Inst{21}    = L;
876 }
877
878 // System instructions which do not have an Rt register.
879 class SimpleSystemI<bit L, dag iops, string asm, string operands,
880                     list<dag> pattern = []>
881     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
882   let Inst{4-0} = 0b11111;
883 }
884
885 // System instructions which have an Rt register.
886 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
887     : BaseSystemI<L, oops, iops, asm, operands>,
888       Sched<[WriteSys]> {
889   bits<5> Rt;
890   let Inst{4-0} = Rt;
891 }
892
893 // Hint instructions that take both a CRm and a 3-bit immediate.
894 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
895 // model patterns with sufficiently fine granularity
896 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
897   class HintI<string mnemonic>
898       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
899                       [(int_aarch64_hint imm0_127:$imm)]>,
900         Sched<[WriteHint]> {
901     bits <7> imm;
902     let Inst{20-12} = 0b000110010;
903     let Inst{11-5} = imm;
904   }
905
906 // System instructions taking a single literal operand which encodes into
907 // CRm. op2 differentiates the opcodes.
908 def BarrierAsmOperand : AsmOperandClass {
909   let Name = "Barrier";
910   let ParserMethod = "tryParseBarrierOperand";
911 }
912 def barrier_op : Operand<i32> {
913   let PrintMethod = "printBarrierOption";
914   let ParserMatchClass = BarrierAsmOperand;
915 }
916 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
917                  list<dag> pattern = []>
918     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
919       Sched<[WriteBarrier]> {
920   bits<4> CRm;
921   let Inst{20-12} = 0b000110011;
922   let Inst{11-8} = CRm;
923   let Inst{7-5} = opc;
924 }
925
926 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
927     : SimpleSystemI<0, (ins), asm, "", pattern>,
928       Sched<[]> {
929   bits<4> CRm;
930   let CRm = 0b0011;
931   let Inst{31-12} = 0b11010101000000110010;
932   let Inst{11-8} = CRm;
933   let Inst{7-5} = op2;
934   let Inst{4-0} = 0b11111;
935 }
936
937 // MRS/MSR system instructions. These have different operand classes because
938 // a different subset of registers can be accessed through each instruction.
939 def MRSSystemRegisterOperand : AsmOperandClass {
940   let Name = "MRSSystemRegister";
941   let ParserMethod = "tryParseSysReg";
942   let DiagnosticType = "MRS";
943 }
944 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
945 def mrs_sysreg_op : Operand<i32> {
946   let ParserMatchClass = MRSSystemRegisterOperand;
947   let DecoderMethod = "DecodeMRSSystemRegister";
948   let PrintMethod = "printMRSSystemRegister";
949 }
950
951 def MSRSystemRegisterOperand : AsmOperandClass {
952   let Name = "MSRSystemRegister";
953   let ParserMethod = "tryParseSysReg";
954   let DiagnosticType = "MSR";
955 }
956 def msr_sysreg_op : Operand<i32> {
957   let ParserMatchClass = MSRSystemRegisterOperand;
958   let DecoderMethod = "DecodeMSRSystemRegister";
959   let PrintMethod = "printMSRSystemRegister";
960 }
961
962 def PSBHintOperand : AsmOperandClass {
963   let Name = "PSBHint";
964   let ParserMethod = "tryParsePSBHint";
965 }
966 def psbhint_op : Operand<i32> {
967   let ParserMatchClass = PSBHintOperand;
968   let PrintMethod = "printPSBHintOp";
969   let MCOperandPredicate = [{
970     // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
971     // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
972     if (!MCOp.isImm())
973       return false;
974     return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
975   }];
976 }
977
978 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
979                        "mrs", "\t$Rt, $systemreg"> {
980   bits<16> systemreg;
981   let Inst{20-5} = systemreg;
982 }
983
984 // FIXME: Some of these def NZCV, others don't. Best way to model that?
985 // Explicitly modeling each of the system register as a register class
986 // would do it, but feels like overkill at this point.
987 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
988                        "msr", "\t$systemreg, $Rt"> {
989   bits<16> systemreg;
990   let Inst{20-5} = systemreg;
991 }
992
993 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
994   let Name = "SystemPStateFieldWithImm0_15";
995   let ParserMethod = "tryParseSysReg";
996 }
997 def pstatefield4_op : Operand<i32> {
998   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
999   let PrintMethod = "printSystemPStateField";
1000 }
1001
1002 let Defs = [NZCV] in
1003 class MSRpstateImm0_15
1004   : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
1005                   "msr", "\t$pstatefield, $imm">,
1006     Sched<[WriteSys]> {
1007   bits<6> pstatefield;
1008   bits<4> imm;
1009   let Inst{20-19} = 0b00;
1010   let Inst{18-16} = pstatefield{5-3};
1011   let Inst{15-12} = 0b0100;
1012   let Inst{11-8} = imm;
1013   let Inst{7-5} = pstatefield{2-0};
1014
1015   let DecoderMethod = "DecodeSystemPStateInstruction";
1016   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1017   // Fail the decoder should attempt to decode the instruction as MSRI.
1018   let hasCompleteDecoder = 0;
1019 }
1020
1021 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1022   let Name = "SystemPStateFieldWithImm0_1";
1023   let ParserMethod = "tryParseSysReg";
1024 }
1025 def pstatefield1_op : Operand<i32> {
1026   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1027   let PrintMethod = "printSystemPStateField";
1028 }
1029
1030 let Defs = [NZCV] in
1031 class MSRpstateImm0_1
1032   : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
1033                   "msr", "\t$pstatefield, $imm">,
1034     Sched<[WriteSys]> {
1035   bits<6> pstatefield;
1036   bit imm;
1037   let Inst{20-19} = 0b00;
1038   let Inst{18-16} = pstatefield{5-3};
1039   let Inst{15-9} = 0b0100000;
1040   let Inst{8} = imm;
1041   let Inst{7-5} = pstatefield{2-0};
1042
1043   let DecoderMethod = "DecodeSystemPStateInstruction";
1044   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1045   // Fail the decoder should attempt to decode the instruction as MSRI.
1046   let hasCompleteDecoder = 0;
1047 }
1048
1049 // SYS and SYSL generic system instructions.
1050 def SysCRAsmOperand : AsmOperandClass {
1051   let Name = "SysCR";
1052   let ParserMethod = "tryParseSysCROperand";
1053 }
1054
1055 def sys_cr_op : Operand<i32> {
1056   let PrintMethod = "printSysCROperand";
1057   let ParserMatchClass = SysCRAsmOperand;
1058 }
1059
1060 class SystemXtI<bit L, string asm>
1061   : RtSystemI<L, (outs),
1062        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1063        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1064   bits<3> op1;
1065   bits<4> Cn;
1066   bits<4> Cm;
1067   bits<3> op2;
1068   let Inst{20-19} = 0b01;
1069   let Inst{18-16} = op1;
1070   let Inst{15-12} = Cn;
1071   let Inst{11-8}  = Cm;
1072   let Inst{7-5}   = op2;
1073 }
1074
1075 class SystemLXtI<bit L, string asm>
1076   : RtSystemI<L, (outs),
1077        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1078        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1079   bits<3> op1;
1080   bits<4> Cn;
1081   bits<4> Cm;
1082   bits<3> op2;
1083   let Inst{20-19} = 0b01;
1084   let Inst{18-16} = op1;
1085   let Inst{15-12} = Cn;
1086   let Inst{11-8}  = Cm;
1087   let Inst{7-5}   = op2;
1088 }
1089
1090
1091 // Branch (register) instructions:
1092 //
1093 //  case opc of
1094 //    0001 blr
1095 //    0000 br
1096 //    0101 dret
1097 //    0100 eret
1098 //    0010 ret
1099 //    otherwise UNDEFINED
1100 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1101                     string operands, list<dag> pattern>
1102     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1103   let Inst{31-25} = 0b1101011;
1104   let Inst{24-21} = opc;
1105   let Inst{20-16} = 0b11111;
1106   let Inst{15-10} = 0b000000;
1107   let Inst{4-0}   = 0b00000;
1108 }
1109
1110 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1111     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1112   bits<5> Rn;
1113   let Inst{9-5} = Rn;
1114 }
1115
1116 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1117 class SpecialReturn<bits<4> opc, string asm>
1118     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1119   let Inst{9-5} = 0b11111;
1120 }
1121
1122 let mayLoad = 1 in
1123 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
1124   : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
1125   Sched<[]> {
1126   bits<5> Rn;
1127   bits<5> Rt;
1128   let Inst{31-30} = sz;
1129   let Inst{29-10} = 0b11100010111111110000;
1130   let Inst{9-5} = Rn;
1131   let Inst{4-0} = Rt;
1132 }
1133
1134 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
1135                list<dag> pattern>
1136   : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
1137   let Inst{31-25} = 0b1101011;
1138   let Inst{20-11} = 0b1111100001;
1139   let Inst{10} = M;
1140   let Inst{4-0} = 0b11111;
1141 }
1142
1143 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
1144   : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
1145   bits<5> Rn;
1146   bits<5> Rm;
1147   let Inst{24-22} = 0b100;
1148   let Inst{21} = op;
1149   let Inst{9-5} = Rn;
1150   let Inst{4-0} = Rm;
1151 }
1152
1153 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
1154   : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
1155   bits<5> Rn;
1156   let Inst{24} = 0;
1157   let Inst{23-21} = opc;
1158   let Inst{9-5} = Rn;
1159 }
1160
1161 class AuthReturn<bits<3> op, bits<1> M, string asm>
1162   : AuthBase<M, (outs), (ins), asm, "", []> {
1163   let Inst{24} = 0;
1164   let Inst{23-21} = op;
1165   let Inst{9-0} = 0b1111111111;
1166 }
1167
1168 let mayLoad = 1 in
1169 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
1170                    string operands, string cstr, Operand opr>
1171   : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
1172   bits<10> offset;
1173   bits<5> Rn;
1174   bits<5> Rt;
1175   let Inst{31-24} = 0b11111000;
1176   let Inst{23} = M;
1177   let Inst{22} = offset{9};
1178   let Inst{21} = 1;
1179   let Inst{20-12} = offset{8-0};
1180   let Inst{11} = W;
1181   let Inst{10} = 1;
1182   let Inst{9-5} = Rn;
1183   let Inst{4-0} = Rt;
1184 }
1185
1186 multiclass AuthLoad<bit M, string asm, Operand opr> {
1187   def indexed   : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
1188                                (ins GPR64sp:$Rn, opr:$offset),
1189                                asm, "\t$Rt, [$Rn, $offset]", "", opr>;
1190   def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
1191                                (ins GPR64sp:$Rn, opr:$offset),
1192                                asm, "\t$Rt, [$Rn, $offset]!",
1193                                "$Rn = $wback,@earlyclobber $wback", opr>;
1194
1195   def : InstAlias<asm # "\t$Rt, [$Rn]",
1196                   (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
1197 }
1198
1199 //---
1200 // Conditional branch instruction.
1201 //---
1202
1203 // Condition code.
1204 // 4-bit immediate. Pretty-printed as <cc>
1205 def ccode : Operand<i32> {
1206   let PrintMethod = "printCondCode";
1207   let ParserMatchClass = CondCode;
1208 }
1209 def inv_ccode : Operand<i32> {
1210   // AL and NV are invalid in the aliases which use inv_ccode
1211   let PrintMethod = "printInverseCondCode";
1212   let ParserMatchClass = CondCode;
1213   let MCOperandPredicate = [{
1214     return MCOp.isImm() &&
1215            MCOp.getImm() != AArch64CC::AL &&
1216            MCOp.getImm() != AArch64CC::NV;
1217   }];
1218 }
1219
1220 // Conditional branch target. 19-bit immediate. The low two bits of the target
1221 // offset are implied zero and so are not part of the immediate.
1222 def am_brcond : Operand<OtherVT> {
1223   let EncoderMethod = "getCondBranchTargetOpValue";
1224   let DecoderMethod = "DecodePCRelLabel19";
1225   let PrintMethod = "printAlignedLabel";
1226   let ParserMatchClass = PCRelLabel19Operand;
1227 }
1228
1229 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1230                      "b", ".$cond\t$target", "",
1231                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1232                    Sched<[WriteBr]> {
1233   let isBranch = 1;
1234   let isTerminator = 1;
1235   let Uses = [NZCV];
1236
1237   bits<4> cond;
1238   bits<19> target;
1239   let Inst{31-24} = 0b01010100;
1240   let Inst{23-5} = target;
1241   let Inst{4} = 0;
1242   let Inst{3-0} = cond;
1243 }
1244
1245 //---
1246 // Compare-and-branch instructions.
1247 //---
1248 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1249     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1250          asm, "\t$Rt, $target", "",
1251          [(node regtype:$Rt, bb:$target)]>,
1252       Sched<[WriteBr]> {
1253   let isBranch = 1;
1254   let isTerminator = 1;
1255
1256   bits<5> Rt;
1257   bits<19> target;
1258   let Inst{30-25} = 0b011010;
1259   let Inst{24}    = op;
1260   let Inst{23-5}  = target;
1261   let Inst{4-0}   = Rt;
1262 }
1263
1264 multiclass CmpBranch<bit op, string asm, SDNode node> {
1265   def W : BaseCmpBranch<GPR32, op, asm, node> {
1266     let Inst{31} = 0;
1267   }
1268   def X : BaseCmpBranch<GPR64, op, asm, node> {
1269     let Inst{31} = 1;
1270   }
1271 }
1272
1273 //---
1274 // Test-bit-and-branch instructions.
1275 //---
1276 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1277 // the target offset are implied zero and so are not part of the immediate.
1278 def am_tbrcond : Operand<OtherVT> {
1279   let EncoderMethod = "getTestBranchTargetOpValue";
1280   let PrintMethod = "printAlignedLabel";
1281   let ParserMatchClass = BranchTarget14Operand;
1282 }
1283
1284 // AsmOperand classes to emit (or not) special diagnostics
1285 def TBZImm0_31Operand : AsmOperandClass {
1286   let Name = "TBZImm0_31";
1287   let PredicateMethod = "isImmInRange<0,31>";
1288   let RenderMethod = "addImm0_31Operands";
1289 }
1290 def TBZImm32_63Operand : AsmOperandClass {
1291   let Name = "Imm32_63";
1292   let PredicateMethod = "isImmInRange<32,63>";
1293   let DiagnosticType = "InvalidImm0_63";
1294 }
1295
1296 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1297   return (((uint32_t)Imm) < 32);
1298 }]> {
1299   let ParserMatchClass = matcher;
1300 }
1301
1302 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1303 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1304
1305 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1306   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1307 }]> {
1308   let ParserMatchClass = TBZImm32_63Operand;
1309 }
1310
1311 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1312                      bit op, string asm, SDNode node>
1313     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1314        asm, "\t$Rt, $bit_off, $target", "",
1315        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1316       Sched<[WriteBr]> {
1317   let isBranch = 1;
1318   let isTerminator = 1;
1319
1320   bits<5> Rt;
1321   bits<6> bit_off;
1322   bits<14> target;
1323
1324   let Inst{30-25} = 0b011011;
1325   let Inst{24}    = op;
1326   let Inst{23-19} = bit_off{4-0};
1327   let Inst{18-5}  = target;
1328   let Inst{4-0}   = Rt;
1329
1330   let DecoderMethod = "DecodeTestAndBranch";
1331 }
1332
1333 multiclass TestBranch<bit op, string asm, SDNode node> {
1334   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1335     let Inst{31} = 0;
1336   }
1337
1338   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1339     let Inst{31} = 1;
1340   }
1341
1342   // Alias X-reg with 0-31 imm to W-Reg.
1343   def : InstAlias<asm # "\t$Rd, $imm, $target",
1344                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1345                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1346   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1347             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1348             tbz_imm0_31_diag:$imm, bb:$target)>;
1349 }
1350
1351 //---
1352 // Unconditional branch (immediate) instructions.
1353 //---
1354 def am_b_target : Operand<OtherVT> {
1355   let EncoderMethod = "getBranchTargetOpValue";
1356   let PrintMethod = "printAlignedLabel";
1357   let ParserMatchClass = BranchTarget26Operand;
1358 }
1359 def am_bl_target : Operand<i64> {
1360   let EncoderMethod = "getBranchTargetOpValue";
1361   let PrintMethod = "printAlignedLabel";
1362   let ParserMatchClass = BranchTarget26Operand;
1363 }
1364
1365 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1366     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1367   bits<26> addr;
1368   let Inst{31}    = op;
1369   let Inst{30-26} = 0b00101;
1370   let Inst{25-0}  = addr;
1371
1372   let DecoderMethod = "DecodeUnconditionalBranch";
1373 }
1374
1375 class BranchImm<bit op, string asm, list<dag> pattern>
1376     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1377 class CallImm<bit op, string asm, list<dag> pattern>
1378     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1379
1380 //---
1381 // Basic one-operand data processing instructions.
1382 //---
1383
1384 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1385 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1386                          SDPatternOperator node>
1387   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1388       [(set regtype:$Rd, (node regtype:$Rn))]>,
1389     Sched<[WriteI, ReadI]> {
1390   bits<5> Rd;
1391   bits<5> Rn;
1392
1393   let Inst{30-13} = 0b101101011000000000;
1394   let Inst{12-10} = opc;
1395   let Inst{9-5}   = Rn;
1396   let Inst{4-0}   = Rd;
1397 }
1398
1399 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1400 multiclass OneOperandData<bits<3> opc, string asm,
1401                           SDPatternOperator node = null_frag> {
1402   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1403     let Inst{31} = 0;
1404   }
1405
1406   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1407     let Inst{31} = 1;
1408   }
1409 }
1410
1411 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1412     : BaseOneOperandData<opc, GPR32, asm, node> {
1413   let Inst{31} = 0;
1414 }
1415
1416 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1417     : BaseOneOperandData<opc, GPR64, asm, node> {
1418   let Inst{31} = 1;
1419 }
1420
1421 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
1422   : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "",
1423       []>,
1424     Sched<[WriteI, ReadI]> {
1425   bits<5> Rd;
1426   bits<5> Rn;
1427   let Inst{31-15} = 0b11011010110000010;
1428   let Inst{14-12} = opcode_prefix;
1429   let Inst{11-10} = opcode;
1430   let Inst{9-5} = Rn;
1431   let Inst{4-0} = Rd;
1432 }
1433
1434 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
1435   : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> {
1436   bits<5> Rd;
1437   let Inst{31-15} = 0b11011010110000010;
1438   let Inst{14-12} = opcode_prefix;
1439   let Inst{11-10} = opcode;
1440   let Inst{9-5} = 0b11111;
1441   let Inst{4-0} = Rd;
1442 }
1443
1444 class SignAuthTwoOperand<bits<4> opc, string asm,
1445                          SDPatternOperator OpNode>
1446   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
1447       asm, "\t$Rd, $Rn, $Rm", "",
1448       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
1449     Sched<[WriteI, ReadI, ReadI]> {
1450   bits<5> Rd;
1451   bits<5> Rn;
1452   bits<5> Rm;
1453   let Inst{31-21} = 0b10011010110;
1454   let Inst{20-16} = Rm;
1455   let Inst{15-14} = 0b00;
1456   let Inst{13-10} = opc;
1457   let Inst{9-5}   = Rn;
1458   let Inst{4-0}   = Rd;
1459 }
1460
1461 //---
1462 // Basic two-operand data processing instructions.
1463 //---
1464 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1465                           list<dag> pattern>
1466     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1467         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1468       Sched<[WriteI, ReadI, ReadI]> {
1469   let Uses = [NZCV];
1470   bits<5> Rd;
1471   bits<5> Rn;
1472   bits<5> Rm;
1473   let Inst{30}    = isSub;
1474   let Inst{28-21} = 0b11010000;
1475   let Inst{20-16} = Rm;
1476   let Inst{15-10} = 0;
1477   let Inst{9-5}   = Rn;
1478   let Inst{4-0}   = Rd;
1479 }
1480
1481 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1482                       SDNode OpNode>
1483     : BaseBaseAddSubCarry<isSub, regtype, asm,
1484         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1485
1486 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1487                               SDNode OpNode>
1488     : BaseBaseAddSubCarry<isSub, regtype, asm,
1489         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1490          (implicit NZCV)]> {
1491   let Defs = [NZCV];
1492 }
1493
1494 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1495                        SDNode OpNode, SDNode OpNode_setflags> {
1496   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1497     let Inst{31} = 0;
1498     let Inst{29} = 0;
1499   }
1500   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1501     let Inst{31} = 1;
1502     let Inst{29} = 0;
1503   }
1504
1505   // Sets flags.
1506   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1507                                     OpNode_setflags> {
1508     let Inst{31} = 0;
1509     let Inst{29} = 1;
1510   }
1511   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1512                                     OpNode_setflags> {
1513     let Inst{31} = 1;
1514     let Inst{29} = 1;
1515   }
1516 }
1517
1518 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1519                      SDPatternOperator OpNode>
1520   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1521       asm, "\t$Rd, $Rn, $Rm", "",
1522       [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1523   bits<5> Rd;
1524   bits<5> Rn;
1525   bits<5> Rm;
1526   let Inst{30-21} = 0b0011010110;
1527   let Inst{20-16} = Rm;
1528   let Inst{15-14} = 0b00;
1529   let Inst{13-10} = opc;
1530   let Inst{9-5}   = Rn;
1531   let Inst{4-0}   = Rd;
1532 }
1533
1534 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1535               SDPatternOperator OpNode>
1536     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1537   let Inst{10}    = isSigned;
1538 }
1539
1540 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1541   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1542            Sched<[WriteID32, ReadID, ReadID]> {
1543     let Inst{31} = 0;
1544   }
1545   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1546            Sched<[WriteID64, ReadID, ReadID]> {
1547     let Inst{31} = 1;
1548   }
1549 }
1550
1551 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1552                 SDPatternOperator OpNode = null_frag>
1553   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1554     Sched<[WriteIS, ReadI]> {
1555   let Inst{11-10} = shift_type;
1556 }
1557
1558 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1559   def Wr : BaseShift<shift_type, GPR32, asm> {
1560     let Inst{31} = 0;
1561   }
1562
1563   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1564     let Inst{31} = 1;
1565   }
1566
1567   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1568             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1569                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1570
1571   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1572             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1573
1574   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1575             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1576
1577   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1578             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1579 }
1580
1581 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1582     : InstAlias<asm#"\t$dst, $src1, $src2",
1583                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1584
1585 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1586                        RegisterClass addtype, string asm,
1587                        list<dag> pattern>
1588   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1589       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1590   bits<5> Rd;
1591   bits<5> Rn;
1592   bits<5> Rm;
1593   bits<5> Ra;
1594   let Inst{30-24} = 0b0011011;
1595   let Inst{23-21} = opc;
1596   let Inst{20-16} = Rm;
1597   let Inst{15}    = isSub;
1598   let Inst{14-10} = Ra;
1599   let Inst{9-5}   = Rn;
1600   let Inst{4-0}   = Rd;
1601 }
1602
1603 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1604   // MADD/MSUB generation is decided by MachineCombiner.cpp
1605   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1606       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1607       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1608     let Inst{31} = 0;
1609   }
1610
1611   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1612       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1613       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1614     let Inst{31} = 1;
1615   }
1616 }
1617
1618 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1619                    SDNode AccNode, SDNode ExtNode>
1620   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1621     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1622                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1623     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1624   let Inst{31} = 1;
1625 }
1626
1627 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1628   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1629       asm, "\t$Rd, $Rn, $Rm", "",
1630       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1631     Sched<[WriteIM64, ReadIM, ReadIM]> {
1632   bits<5> Rd;
1633   bits<5> Rn;
1634   bits<5> Rm;
1635   let Inst{31-24} = 0b10011011;
1636   let Inst{23-21} = opc;
1637   let Inst{20-16} = Rm;
1638   let Inst{15}    = 0;
1639   let Inst{9-5}   = Rn;
1640   let Inst{4-0}   = Rd;
1641
1642   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1643   // (i.e. all bits 1) but is ignored by the processor.
1644   let PostEncoderMethod = "fixMulHigh";
1645 }
1646
1647 class MulAccumWAlias<string asm, Instruction inst>
1648     : InstAlias<asm#"\t$dst, $src1, $src2",
1649                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1650 class MulAccumXAlias<string asm, Instruction inst>
1651     : InstAlias<asm#"\t$dst, $src1, $src2",
1652                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1653 class WideMulAccumAlias<string asm, Instruction inst>
1654     : InstAlias<asm#"\t$dst, $src1, $src2",
1655                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1656
1657 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1658               SDPatternOperator OpNode, string asm>
1659   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1660       asm, "\t$Rd, $Rn, $Rm", "",
1661       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1662     Sched<[WriteISReg, ReadI, ReadISReg]> {
1663   bits<5> Rd;
1664   bits<5> Rn;
1665   bits<5> Rm;
1666
1667   let Inst{31} = sf;
1668   let Inst{30-21} = 0b0011010110;
1669   let Inst{20-16} = Rm;
1670   let Inst{15-13} = 0b010;
1671   let Inst{12} = C;
1672   let Inst{11-10} = sz;
1673   let Inst{9-5} = Rn;
1674   let Inst{4-0} = Rd;
1675   let Predicates = [HasCRC];
1676 }
1677
1678 //---
1679 // Address generation.
1680 //---
1681
1682 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1683     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1684         pattern>,
1685       Sched<[WriteI]> {
1686   bits<5>  Xd;
1687   bits<21> label;
1688   let Inst{31}    = page;
1689   let Inst{30-29} = label{1-0};
1690   let Inst{28-24} = 0b10000;
1691   let Inst{23-5}  = label{20-2};
1692   let Inst{4-0}   = Xd;
1693
1694   let DecoderMethod = "DecodeAdrInstruction";
1695 }
1696
1697 //---
1698 // Move immediate.
1699 //---
1700
1701 def movimm32_imm : Operand<i32> {
1702   let ParserMatchClass = Imm0_65535Operand;
1703   let EncoderMethod = "getMoveWideImmOpValue";
1704   let PrintMethod = "printImm";
1705 }
1706 def movimm32_shift : Operand<i32> {
1707   let PrintMethod = "printShifter";
1708   let ParserMatchClass = MovImm32ShifterOperand;
1709 }
1710 def movimm64_shift : Operand<i32> {
1711   let PrintMethod = "printShifter";
1712   let ParserMatchClass = MovImm64ShifterOperand;
1713 }
1714
1715 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1716 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1717                         string asm>
1718   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1719        asm, "\t$Rd, $imm$shift", "", []>,
1720     Sched<[WriteImm]> {
1721   bits<5> Rd;
1722   bits<16> imm;
1723   bits<6> shift;
1724   let Inst{30-29} = opc;
1725   let Inst{28-23} = 0b100101;
1726   let Inst{22-21} = shift{5-4};
1727   let Inst{20-5}  = imm;
1728   let Inst{4-0}   = Rd;
1729
1730   let DecoderMethod = "DecodeMoveImmInstruction";
1731 }
1732
1733 multiclass MoveImmediate<bits<2> opc, string asm> {
1734   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1735     let Inst{31} = 0;
1736   }
1737
1738   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1739     let Inst{31} = 1;
1740   }
1741 }
1742
1743 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1744 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1745                           string asm>
1746   : I<(outs regtype:$Rd),
1747       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1748        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1749     Sched<[WriteI, ReadI]> {
1750   bits<5> Rd;
1751   bits<16> imm;
1752   bits<6> shift;
1753   let Inst{30-29} = opc;
1754   let Inst{28-23} = 0b100101;
1755   let Inst{22-21} = shift{5-4};
1756   let Inst{20-5}  = imm;
1757   let Inst{4-0}   = Rd;
1758
1759   let DecoderMethod = "DecodeMoveImmInstruction";
1760 }
1761
1762 multiclass InsertImmediate<bits<2> opc, string asm> {
1763   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1764     let Inst{31} = 0;
1765   }
1766
1767   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1768     let Inst{31} = 1;
1769   }
1770 }
1771
1772 //---
1773 // Add/Subtract
1774 //---
1775
1776 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1777                     RegisterClass srcRegtype, addsub_shifted_imm immtype,
1778                     string asm, SDPatternOperator OpNode>
1779     : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1780         asm, "\t$Rd, $Rn, $imm", "",
1781         [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1782       Sched<[WriteI, ReadI]>  {
1783   bits<5>  Rd;
1784   bits<5>  Rn;
1785   bits<14> imm;
1786   let Inst{30}    = isSub;
1787   let Inst{29}    = setFlags;
1788   let Inst{28-24} = 0b10001;
1789   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1790   let Inst{21-10} = imm{11-0};
1791   let Inst{9-5}   = Rn;
1792   let Inst{4-0}   = Rd;
1793   let DecoderMethod = "DecodeBaseAddSubImm";
1794 }
1795
1796 class BaseAddSubRegPseudo<RegisterClass regtype,
1797                           SDPatternOperator OpNode>
1798     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1799              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1800       Sched<[WriteI, ReadI, ReadI]>;
1801
1802 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1803                      arith_shifted_reg shifted_regtype, string asm,
1804                      SDPatternOperator OpNode>
1805     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1806         asm, "\t$Rd, $Rn, $Rm", "",
1807         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1808       Sched<[WriteISReg, ReadI, ReadISReg]> {
1809   // The operands are in order to match the 'addr' MI operands, so we
1810   // don't need an encoder method and by-name matching. Just use the default
1811   // in-order handling. Since we're using by-order, make sure the names
1812   // do not match.
1813   bits<5> dst;
1814   bits<5> src1;
1815   bits<5> src2;
1816   bits<8> shift;
1817   let Inst{30}    = isSub;
1818   let Inst{29}    = setFlags;
1819   let Inst{28-24} = 0b01011;
1820   let Inst{23-22} = shift{7-6};
1821   let Inst{21}    = 0;
1822   let Inst{20-16} = src2;
1823   let Inst{15-10} = shift{5-0};
1824   let Inst{9-5}   = src1;
1825   let Inst{4-0}   = dst;
1826
1827   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1828 }
1829
1830 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1831                      RegisterClass src1Regtype, Operand src2Regtype,
1832                      string asm, SDPatternOperator OpNode>
1833     : I<(outs dstRegtype:$R1),
1834         (ins src1Regtype:$R2, src2Regtype:$R3),
1835         asm, "\t$R1, $R2, $R3", "",
1836         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1837       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1838   bits<5> Rd;
1839   bits<5> Rn;
1840   bits<5> Rm;
1841   bits<6> ext;
1842   let Inst{30}    = isSub;
1843   let Inst{29}    = setFlags;
1844   let Inst{28-24} = 0b01011;
1845   let Inst{23-21} = 0b001;
1846   let Inst{20-16} = Rm;
1847   let Inst{15-13} = ext{5-3};
1848   let Inst{12-10} = ext{2-0};
1849   let Inst{9-5}   = Rn;
1850   let Inst{4-0}   = Rd;
1851
1852   let DecoderMethod = "DecodeAddSubERegInstruction";
1853 }
1854
1855 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1856 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1857                        RegisterClass src1Regtype, RegisterClass src2Regtype,
1858                        Operand ext_op, string asm>
1859     : I<(outs dstRegtype:$Rd),
1860         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1861         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1862       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1863   bits<5> Rd;
1864   bits<5> Rn;
1865   bits<5> Rm;
1866   bits<6> ext;
1867   let Inst{30}    = isSub;
1868   let Inst{29}    = setFlags;
1869   let Inst{28-24} = 0b01011;
1870   let Inst{23-21} = 0b001;
1871   let Inst{20-16} = Rm;
1872   let Inst{15}    = ext{5};
1873   let Inst{12-10} = ext{2-0};
1874   let Inst{9-5}   = Rn;
1875   let Inst{4-0}   = Rd;
1876
1877   let DecoderMethod = "DecodeAddSubERegInstruction";
1878 }
1879
1880 // Aliases for register+register add/subtract.
1881 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1882                      RegisterClass src1Regtype, RegisterClass src2Regtype,
1883                      int shiftExt>
1884     : InstAlias<asm#"\t$dst, $src1, $src2",
1885                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1886                       shiftExt)>;
1887
1888 multiclass AddSub<bit isSub, string mnemonic, string alias,
1889                   SDPatternOperator OpNode = null_frag> {
1890   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1891   // Add/Subtract immediate
1892   // Increase the weight of the immediate variant to try to match it before
1893   // the extended register variant.
1894   // We used to match the register variant before the immediate when the
1895   // register argument could be implicitly zero-extended.
1896   let AddedComplexity = 6 in
1897   def Wri  : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1898                            mnemonic, OpNode> {
1899     let Inst{31} = 0;
1900   }
1901   let AddedComplexity = 6 in
1902   def Xri  : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1903                            mnemonic, OpNode> {
1904     let Inst{31} = 1;
1905   }
1906
1907   // Add/Subtract register - Only used for CodeGen
1908   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1909   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1910
1911   // Add/Subtract shifted register
1912   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1913                            OpNode> {
1914     let Inst{31} = 0;
1915   }
1916   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1917                            OpNode> {
1918     let Inst{31} = 1;
1919   }
1920   }
1921
1922   // Add/Subtract extended register
1923   let AddedComplexity = 1, hasSideEffects = 0 in {
1924   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1925                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1926     let Inst{31} = 0;
1927   }
1928   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1929                            arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1930     let Inst{31} = 1;
1931   }
1932   }
1933
1934   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1935                                arith_extendlsl64, mnemonic> {
1936     // UXTX and SXTX only.
1937     let Inst{14-13} = 0b11;
1938     let Inst{31} = 1;
1939   }
1940
1941   // add Rd, Rb, -imm -> sub Rd, Rn, imm
1942   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1943                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1944                       addsub_shifted_imm32_neg:$imm), 0>;
1945   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1946                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1947                        addsub_shifted_imm64_neg:$imm), 0>;
1948
1949   // Register/register aliases with no shift when SP is not used.
1950   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1951                        GPR32, GPR32, GPR32, 0>;
1952   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1953                        GPR64, GPR64, GPR64, 0>;
1954
1955   // Register/register aliases with no shift when either the destination or
1956   // first source register is SP.
1957   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1958                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1959   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1960                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1961   def : AddSubRegAlias<mnemonic,
1962                        !cast<Instruction>(NAME#"Xrx64"),
1963                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1964   def : AddSubRegAlias<mnemonic,
1965                        !cast<Instruction>(NAME#"Xrx64"),
1966                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1967 }
1968
1969 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1970                    string alias, string cmpAlias> {
1971   let isCompare = 1, Defs = [NZCV] in {
1972   // Add/Subtract immediate
1973   def Wri  : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1974                            mnemonic, OpNode> {
1975     let Inst{31} = 0;
1976   }
1977   def Xri  : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1978                            mnemonic, OpNode> {
1979     let Inst{31} = 1;
1980   }
1981
1982   // Add/Subtract register
1983   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1984   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1985
1986   // Add/Subtract shifted register
1987   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1988                            OpNode> {
1989     let Inst{31} = 0;
1990   }
1991   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1992                            OpNode> {
1993     let Inst{31} = 1;
1994   }
1995
1996   // Add/Subtract extended register
1997   let AddedComplexity = 1 in {
1998   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1999                            arith_extended_reg32<i32>, mnemonic, OpNode> {
2000     let Inst{31} = 0;
2001   }
2002   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
2003                            arith_extended_reg32<i64>, mnemonic, OpNode> {
2004     let Inst{31} = 1;
2005   }
2006   }
2007
2008   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
2009                                arith_extendlsl64, mnemonic> {
2010     // UXTX and SXTX only.
2011     let Inst{14-13} = 0b11;
2012     let Inst{31} = 1;
2013   }
2014   } // Defs = [NZCV]
2015
2016   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
2017   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2018                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
2019                       addsub_shifted_imm32_neg:$imm), 0>;
2020   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2021                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
2022                        addsub_shifted_imm64_neg:$imm), 0>;
2023
2024   // Compare aliases
2025   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2026                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
2027   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2028                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
2029   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
2030                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2031   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
2032                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2033   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
2034                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
2035   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
2036                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
2037   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
2038                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
2039
2040   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
2041   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2042                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
2043   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2044                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
2045
2046   // Compare shorthands
2047   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
2048                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
2049   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
2050                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
2051   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
2052                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
2053   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
2054                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
2055
2056   // Register/register aliases with no shift when SP is not used.
2057   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2058                        GPR32, GPR32, GPR32, 0>;
2059   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2060                        GPR64, GPR64, GPR64, 0>;
2061
2062   // Register/register aliases with no shift when the first source register
2063   // is SP.
2064   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2065                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
2066   def : AddSubRegAlias<mnemonic,
2067                        !cast<Instruction>(NAME#"Xrx64"),
2068                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
2069 }
2070
2071 //---
2072 // Extract
2073 //---
2074 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2075                                       SDTCisPtrTy<3>]>;
2076 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
2077
2078 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
2079                      list<dag> patterns>
2080     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
2081          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
2082       Sched<[WriteExtr, ReadExtrHi]> {
2083   bits<5> Rd;
2084   bits<5> Rn;
2085   bits<5> Rm;
2086   bits<6> imm;
2087
2088   let Inst{30-23} = 0b00100111;
2089   let Inst{21}    = 0;
2090   let Inst{20-16} = Rm;
2091   let Inst{15-10} = imm;
2092   let Inst{9-5}   = Rn;
2093   let Inst{4-0}   = Rd;
2094 }
2095
2096 multiclass ExtractImm<string asm> {
2097   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
2098                       [(set GPR32:$Rd,
2099                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
2100     let Inst{31} = 0;
2101     let Inst{22} = 0;
2102     // imm<5> must be zero.
2103     let imm{5}   = 0;
2104   }
2105   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
2106                       [(set GPR64:$Rd,
2107                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
2108
2109     let Inst{31} = 1;
2110     let Inst{22} = 1;
2111   }
2112 }
2113
2114 //---
2115 // Bitfield
2116 //---
2117
2118 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2119 class BaseBitfieldImm<bits<2> opc,
2120                       RegisterClass regtype, Operand imm_type, string asm>
2121     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
2122          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
2123       Sched<[WriteIS, ReadI]> {
2124   bits<5> Rd;
2125   bits<5> Rn;
2126   bits<6> immr;
2127   bits<6> imms;
2128
2129   let Inst{30-29} = opc;
2130   let Inst{28-23} = 0b100110;
2131   let Inst{21-16} = immr;
2132   let Inst{15-10} = imms;
2133   let Inst{9-5}   = Rn;
2134   let Inst{4-0}   = Rd;
2135 }
2136
2137 multiclass BitfieldImm<bits<2> opc, string asm> {
2138   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2139     let Inst{31} = 0;
2140     let Inst{22} = 0;
2141     // imms<5> and immr<5> must be zero, else ReservedValue().
2142     let Inst{21} = 0;
2143     let Inst{15} = 0;
2144   }
2145   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2146     let Inst{31} = 1;
2147     let Inst{22} = 1;
2148   }
2149 }
2150
2151 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2152 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2153                       RegisterClass regtype, Operand imm_type, string asm>
2154     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2155                              imm_type:$imms),
2156          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2157       Sched<[WriteIS, ReadI]> {
2158   bits<5> Rd;
2159   bits<5> Rn;
2160   bits<6> immr;
2161   bits<6> imms;
2162
2163   let Inst{30-29} = opc;
2164   let Inst{28-23} = 0b100110;
2165   let Inst{21-16} = immr;
2166   let Inst{15-10} = imms;
2167   let Inst{9-5}   = Rn;
2168   let Inst{4-0}   = Rd;
2169 }
2170
2171 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2172   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2173     let Inst{31} = 0;
2174     let Inst{22} = 0;
2175     // imms<5> and immr<5> must be zero, else ReservedValue().
2176     let Inst{21} = 0;
2177     let Inst{15} = 0;
2178   }
2179   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2180     let Inst{31} = 1;
2181     let Inst{22} = 1;
2182   }
2183 }
2184
2185 //---
2186 // Logical
2187 //---
2188
2189 // Logical (immediate)
2190 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2191                      RegisterClass sregtype, Operand imm_type, string asm,
2192                      list<dag> pattern>
2193     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2194          asm, "\t$Rd, $Rn, $imm", "", pattern>,
2195       Sched<[WriteI, ReadI]> {
2196   bits<5>  Rd;
2197   bits<5>  Rn;
2198   bits<13> imm;
2199   let Inst{30-29} = opc;
2200   let Inst{28-23} = 0b100100;
2201   let Inst{22}    = imm{12};
2202   let Inst{21-16} = imm{11-6};
2203   let Inst{15-10} = imm{5-0};
2204   let Inst{9-5}   = Rn;
2205   let Inst{4-0}   = Rd;
2206
2207   let DecoderMethod = "DecodeLogicalImmInstruction";
2208 }
2209
2210 // Logical (shifted register)
2211 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2212                       logical_shifted_reg shifted_regtype, string asm,
2213                       list<dag> pattern>
2214     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2215         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2216       Sched<[WriteISReg, ReadI, ReadISReg]> {
2217   // The operands are in order to match the 'addr' MI operands, so we
2218   // don't need an encoder method and by-name matching. Just use the default
2219   // in-order handling. Since we're using by-order, make sure the names
2220   // do not match.
2221   bits<5> dst;
2222   bits<5> src1;
2223   bits<5> src2;
2224   bits<8> shift;
2225   let Inst{30-29} = opc;
2226   let Inst{28-24} = 0b01010;
2227   let Inst{23-22} = shift{7-6};
2228   let Inst{21}    = N;
2229   let Inst{20-16} = src2;
2230   let Inst{15-10} = shift{5-0};
2231   let Inst{9-5}   = src1;
2232   let Inst{4-0}   = dst;
2233
2234   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2235 }
2236
2237 // Aliases for register+register logical instructions.
2238 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2239     : InstAlias<asm#"\t$dst, $src1, $src2",
2240                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2241
2242 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2243                       string Alias> {
2244   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2245   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2246                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2247                                                logical_imm32:$imm))]> {
2248     let Inst{31} = 0;
2249     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2250   }
2251   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2252   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2253                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2254                                                logical_imm64:$imm))]> {
2255     let Inst{31} = 1;
2256   }
2257
2258   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2259                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2260                       logical_imm32_not:$imm), 0>;
2261   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2262                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2263                        logical_imm64_not:$imm), 0>;
2264 }
2265
2266 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2267                        string Alias> {
2268   let isCompare = 1, Defs = [NZCV] in {
2269   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2270       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2271     let Inst{31} = 0;
2272     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2273   }
2274   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2275       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2276     let Inst{31} = 1;
2277   }
2278   } // end Defs = [NZCV]
2279
2280   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2281                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2282                       logical_imm32_not:$imm), 0>;
2283   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2284                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2285                        logical_imm64_not:$imm), 0>;
2286 }
2287
2288 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2289     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2290              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2291       Sched<[WriteI, ReadI, ReadI]>;
2292
2293 // Split from LogicalImm as not all instructions have both.
2294 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2295                       SDPatternOperator OpNode> {
2296   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2297   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2298   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2299   }
2300
2301   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2302                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2303                                                  logical_shifted_reg32:$Rm))]> {
2304     let Inst{31} = 0;
2305   }
2306   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2307                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2308                                                  logical_shifted_reg64:$Rm))]> {
2309     let Inst{31} = 1;
2310   }
2311
2312   def : LogicalRegAlias<mnemonic,
2313                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2314   def : LogicalRegAlias<mnemonic,
2315                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2316 }
2317
2318 // Split from LogicalReg to allow setting NZCV Defs
2319 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2320                        SDPatternOperator OpNode = null_frag> {
2321   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2322   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2323   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2324
2325   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2326             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2327     let Inst{31} = 0;
2328   }
2329   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2330             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2331     let Inst{31} = 1;
2332   }
2333   } // Defs = [NZCV]
2334
2335   def : LogicalRegAlias<mnemonic,
2336                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2337   def : LogicalRegAlias<mnemonic,
2338                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2339 }
2340
2341 //---
2342 // Conditionally set flags
2343 //---
2344
2345 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2346 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2347                             string mnemonic, SDNode OpNode>
2348     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2349          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2350          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2351                              (i32 imm:$cond), NZCV))]>,
2352       Sched<[WriteI, ReadI]> {
2353   let Uses = [NZCV];
2354   let Defs = [NZCV];
2355
2356   bits<5> Rn;
2357   bits<5> imm;
2358   bits<4> nzcv;
2359   bits<4> cond;
2360
2361   let Inst{30}    = op;
2362   let Inst{29-21} = 0b111010010;
2363   let Inst{20-16} = imm;
2364   let Inst{15-12} = cond;
2365   let Inst{11-10} = 0b10;
2366   let Inst{9-5}   = Rn;
2367   let Inst{4}     = 0b0;
2368   let Inst{3-0}   = nzcv;
2369 }
2370
2371 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2372 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2373                             SDNode OpNode>
2374     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2375          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2376          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2377                              (i32 imm:$cond), NZCV))]>,
2378       Sched<[WriteI, ReadI, ReadI]> {
2379   let Uses = [NZCV];
2380   let Defs = [NZCV];
2381
2382   bits<5> Rn;
2383   bits<5> Rm;
2384   bits<4> nzcv;
2385   bits<4> cond;
2386
2387   let Inst{30}    = op;
2388   let Inst{29-21} = 0b111010010;
2389   let Inst{20-16} = Rm;
2390   let Inst{15-12} = cond;
2391   let Inst{11-10} = 0b00;
2392   let Inst{9-5}   = Rn;
2393   let Inst{4}     = 0b0;
2394   let Inst{3-0}   = nzcv;
2395 }
2396
2397 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2398   // immediate operand variants
2399   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2400     let Inst{31} = 0;
2401   }
2402   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2403     let Inst{31} = 1;
2404   }
2405   // register operand variants
2406   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2407     let Inst{31} = 0;
2408   }
2409   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2410     let Inst{31} = 1;
2411   }
2412 }
2413
2414 //---
2415 // Conditional select
2416 //---
2417
2418 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2419     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2420          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2421          [(set regtype:$Rd,
2422                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2423       Sched<[WriteI, ReadI, ReadI]> {
2424   let Uses = [NZCV];
2425
2426   bits<5> Rd;
2427   bits<5> Rn;
2428   bits<5> Rm;
2429   bits<4> cond;
2430
2431   let Inst{30}    = op;
2432   let Inst{29-21} = 0b011010100;
2433   let Inst{20-16} = Rm;
2434   let Inst{15-12} = cond;
2435   let Inst{11-10} = op2;
2436   let Inst{9-5}   = Rn;
2437   let Inst{4-0}   = Rd;
2438 }
2439
2440 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2441   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2442     let Inst{31} = 0;
2443   }
2444   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2445     let Inst{31} = 1;
2446   }
2447 }
2448
2449 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2450                        PatFrag frag>
2451     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2452          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2453          [(set regtype:$Rd,
2454                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2455                (i32 imm:$cond), NZCV))]>,
2456       Sched<[WriteI, ReadI, ReadI]> {
2457   let Uses = [NZCV];
2458
2459   bits<5> Rd;
2460   bits<5> Rn;
2461   bits<5> Rm;
2462   bits<4> cond;
2463
2464   let Inst{30}    = op;
2465   let Inst{29-21} = 0b011010100;
2466   let Inst{20-16} = Rm;
2467   let Inst{15-12} = cond;
2468   let Inst{11-10} = op2;
2469   let Inst{9-5}   = Rn;
2470   let Inst{4-0}   = Rd;
2471 }
2472
2473 def inv_cond_XFORM : SDNodeXForm<imm, [{
2474   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2475   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2476                                    MVT::i32);
2477 }]>;
2478
2479 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2480   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2481     let Inst{31} = 0;
2482   }
2483   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2484     let Inst{31} = 1;
2485   }
2486
2487   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2488             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2489                                            (inv_cond_XFORM imm:$cond))>;
2490
2491   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2492             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2493                                            (inv_cond_XFORM imm:$cond))>;
2494 }
2495
2496 //---
2497 // Special Mask Value
2498 //---
2499 def maski8_or_more : Operand<i32>,
2500   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2501 }
2502 def maski16_or_more : Operand<i32>,
2503   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2504 }
2505
2506
2507 //---
2508 // Load/store
2509 //---
2510
2511 // (unsigned immediate)
2512 // Indexed for 8-bit registers. offset is in range [0,4095].
2513 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2514 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2515 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2516 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2517 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2518
2519 def gi_am_indexed8 :
2520     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
2521     GIComplexPatternEquiv<am_indexed8>;
2522 def gi_am_indexed16 :
2523     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
2524     GIComplexPatternEquiv<am_indexed16>;
2525 def gi_am_indexed32 :
2526     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
2527     GIComplexPatternEquiv<am_indexed32>;
2528 def gi_am_indexed64 :
2529     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
2530     GIComplexPatternEquiv<am_indexed64>;
2531 def gi_am_indexed128 :
2532     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
2533     GIComplexPatternEquiv<am_indexed128>;
2534
2535 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2536   let Name = "UImm12Offset" # Scale;
2537   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2538   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2539   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2540 }
2541
2542 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2543 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2544 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2545 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2546 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2547
2548 class uimm12_scaled<int Scale> : Operand<i64> {
2549   let ParserMatchClass
2550    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2551   let EncoderMethod
2552    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2553   let PrintMethod = "printUImm12Offset<" # Scale # ">";
2554 }
2555
2556 def uimm12s1 : uimm12_scaled<1>;
2557 def uimm12s2 : uimm12_scaled<2>;
2558 def uimm12s4 : uimm12_scaled<4>;
2559 def uimm12s8 : uimm12_scaled<8>;
2560 def uimm12s16 : uimm12_scaled<16>;
2561
2562 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2563                       string asm, list<dag> pattern>
2564     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2565   bits<5> Rt;
2566
2567   bits<5> Rn;
2568   bits<12> offset;
2569
2570   let Inst{31-30} = sz;
2571   let Inst{29-27} = 0b111;
2572   let Inst{26}    = V;
2573   let Inst{25-24} = 0b01;
2574   let Inst{23-22} = opc;
2575   let Inst{21-10} = offset;
2576   let Inst{9-5}   = Rn;
2577   let Inst{4-0}   = Rt;
2578
2579   let DecoderMethod = "DecodeUnsignedLdStInstruction";
2580 }
2581
2582 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2583                   Operand indextype, string asm, list<dag> pattern> {
2584   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2585   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2586                            (ins GPR64sp:$Rn, indextype:$offset),
2587                            asm, pattern>,
2588            Sched<[WriteLD]>;
2589
2590   def : InstAlias<asm # "\t$Rt, [$Rn]",
2591                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2592 }
2593
2594 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2595              Operand indextype, string asm, list<dag> pattern> {
2596   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2597   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2598                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2599                            asm, pattern>,
2600            Sched<[WriteST]>;
2601
2602   def : InstAlias<asm # "\t$Rt, [$Rn]",
2603                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2604 }
2605
2606 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
2607 // substitute zero-registers automatically.
2608 //
2609 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
2610 //       into StoreUI.
2611 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
2612              Operand indextype, string asm, list<dag> pattern> {
2613   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2614   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2615                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2616                            asm, pattern>,
2617            Sched<[WriteST]>;
2618
2619   def : InstAlias<asm # "\t$Rt, [$Rn]",
2620                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2621 }
2622
2623 def PrefetchOperand : AsmOperandClass {
2624   let Name = "Prefetch";
2625   let ParserMethod = "tryParsePrefetch";
2626 }
2627 def prfop : Operand<i32> {
2628   let PrintMethod = "printPrefetchOp";
2629   let ParserMatchClass = PrefetchOperand;
2630 }
2631
2632 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2633 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2634     : BaseLoadStoreUI<sz, V, opc,
2635                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2636                       asm, pat>,
2637       Sched<[WriteLD]>;
2638
2639 //---
2640 // Load literal
2641 //---
2642
2643 // Load literal address: 19-bit immediate. The low two bits of the target
2644 // offset are implied zero and so are not part of the immediate.
2645 def am_ldrlit : Operand<iPTR> {
2646   let EncoderMethod = "getLoadLiteralOpValue";
2647   let DecoderMethod = "DecodePCRelLabel19";
2648   let PrintMethod = "printAlignedLabel";
2649   let ParserMatchClass = PCRelLabel19Operand;
2650 }
2651
2652 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2653 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2654     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2655         asm, "\t$Rt, $label", "", []>,
2656       Sched<[WriteLD]> {
2657   bits<5> Rt;
2658   bits<19> label;
2659   let Inst{31-30} = opc;
2660   let Inst{29-27} = 0b011;
2661   let Inst{26}    = V;
2662   let Inst{25-24} = 0b00;
2663   let Inst{23-5}  = label;
2664   let Inst{4-0}   = Rt;
2665 }
2666
2667 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2668 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2669     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2670         asm, "\t$Rt, $label", "", pat>,
2671       Sched<[WriteLD]> {
2672   bits<5> Rt;
2673   bits<19> label;
2674   let Inst{31-30} = opc;
2675   let Inst{29-27} = 0b011;
2676   let Inst{26}    = V;
2677   let Inst{25-24} = 0b00;
2678   let Inst{23-5}  = label;
2679   let Inst{4-0}   = Rt;
2680 }
2681
2682 //---
2683 // Load/store register offset
2684 //---
2685
2686 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2687 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2688 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2689 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2690 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2691
2692 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2693 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2694 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2695 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2696 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2697
2698 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2699   let Name = "Mem" # Reg # "Extend" # Width;
2700   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2701   let RenderMethod = "addMemExtendOperands";
2702   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2703 }
2704
2705 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2706   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2707   // the trivial shift.
2708   let RenderMethod = "addMemExtend8Operands";
2709 }
2710 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2711 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2712 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2713 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2714
2715 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2716   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2717   // the trivial shift.
2718   let RenderMethod = "addMemExtend8Operands";
2719 }
2720 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2721 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2722 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2723 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2724
2725 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2726         : Operand<i32> {
2727   let ParserMatchClass = ParserClass;
2728   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2729   let DecoderMethod = "DecodeMemExtend";
2730   let EncoderMethod = "getMemExtendOpValue";
2731   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2732 }
2733
2734 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
2735 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
2736 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
2737 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
2738 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2739
2740 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
2741 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
2742 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
2743 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
2744 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2745
2746 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2747                   Operand wextend, Operand xextend>  {
2748   // CodeGen-level pattern covering the entire addressing mode.
2749   ComplexPattern Wpat = windex;
2750   ComplexPattern Xpat = xindex;
2751
2752   // Asm-level Operand covering the valid "uxtw #3" style syntax.
2753   Operand Wext = wextend;
2754   Operand Xext = xextend;
2755 }
2756
2757 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2758 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2759 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2760 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2761 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2762                        ro_Xextend128>;
2763
2764 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2765                       string asm, dag ins, dag outs, list<dag> pat>
2766     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2767   bits<5> Rt;
2768   bits<5> Rn;
2769   bits<5> Rm;
2770   bits<2> extend;
2771   let Inst{31-30} = sz;
2772   let Inst{29-27} = 0b111;
2773   let Inst{26}    = V;
2774   let Inst{25-24} = 0b00;
2775   let Inst{23-22} = opc;
2776   let Inst{21}    = 1;
2777   let Inst{20-16} = Rm;
2778   let Inst{15}    = extend{1}; // sign extend Rm?
2779   let Inst{14}    = 1;
2780   let Inst{12}    = extend{0}; // do shift?
2781   let Inst{11-10} = 0b10;
2782   let Inst{9-5}   = Rn;
2783   let Inst{4-0}   = Rt;
2784 }
2785
2786 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2787   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
2788               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2789
2790 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2791                    string asm, ValueType Ty, SDPatternOperator loadop> {
2792   let AddedComplexity = 10 in
2793   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2794                  (outs regtype:$Rt),
2795                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2796                  [(set (Ty regtype:$Rt),
2797                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2798                                              ro_Wextend8:$extend)))]>,
2799            Sched<[WriteLDIdx, ReadAdrBase]> {
2800     let Inst{13} = 0b0;
2801   }
2802
2803   let AddedComplexity = 10 in
2804   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2805                  (outs regtype:$Rt),
2806                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2807                  [(set (Ty regtype:$Rt),
2808                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2809                                              ro_Xextend8:$extend)))]>,
2810            Sched<[WriteLDIdx, ReadAdrBase]> {
2811     let Inst{13} = 0b1;
2812   }
2813
2814   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2815 }
2816
2817 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2818                     string asm, ValueType Ty, SDPatternOperator storeop> {
2819   let AddedComplexity = 10 in
2820   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2821                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2822                  [(storeop (Ty regtype:$Rt),
2823                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2824                                          ro_Wextend8:$extend))]>,
2825             Sched<[WriteSTIdx, ReadAdrBase]> {
2826     let Inst{13} = 0b0;
2827   }
2828
2829   let AddedComplexity = 10 in
2830   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2831                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2832                  [(storeop (Ty regtype:$Rt),
2833                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2834                                          ro_Xextend8:$extend))]>,
2835             Sched<[WriteSTIdx, ReadAdrBase]> {
2836     let Inst{13} = 0b1;
2837   }
2838
2839   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2840 }
2841
2842 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2843                       string asm, dag ins, dag outs, list<dag> pat>
2844     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2845   bits<5> Rt;
2846   bits<5> Rn;
2847   bits<5> Rm;
2848   bits<2> extend;
2849   let Inst{31-30} = sz;
2850   let Inst{29-27} = 0b111;
2851   let Inst{26}    = V;
2852   let Inst{25-24} = 0b00;
2853   let Inst{23-22} = opc;
2854   let Inst{21}    = 1;
2855   let Inst{20-16} = Rm;
2856   let Inst{15}    = extend{1}; // sign extend Rm?
2857   let Inst{14}    = 1;
2858   let Inst{12}    = extend{0}; // do shift?
2859   let Inst{11-10} = 0b10;
2860   let Inst{9-5}   = Rn;
2861   let Inst{4-0}   = Rt;
2862 }
2863
2864 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2865                     string asm, ValueType Ty, SDPatternOperator loadop> {
2866   let AddedComplexity = 10 in
2867   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2868                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2869                  [(set (Ty regtype:$Rt),
2870                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2871                                               ro_Wextend16:$extend)))]>,
2872             Sched<[WriteLDIdx, ReadAdrBase]> {
2873     let Inst{13} = 0b0;
2874   }
2875
2876   let AddedComplexity = 10 in
2877   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2878                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2879                  [(set (Ty regtype:$Rt),
2880                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2881                                              ro_Xextend16:$extend)))]>,
2882             Sched<[WriteLDIdx, ReadAdrBase]> {
2883     let Inst{13} = 0b1;
2884   }
2885
2886   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2887 }
2888
2889 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2890                      string asm, ValueType Ty, SDPatternOperator storeop> {
2891   let AddedComplexity = 10 in
2892   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2893                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2894                 [(storeop (Ty regtype:$Rt),
2895                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2896                                          ro_Wextend16:$extend))]>,
2897            Sched<[WriteSTIdx, ReadAdrBase]> {
2898     let Inst{13} = 0b0;
2899   }
2900
2901   let AddedComplexity = 10 in
2902   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2903                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2904                 [(storeop (Ty regtype:$Rt),
2905                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2906                                          ro_Xextend16:$extend))]>,
2907            Sched<[WriteSTIdx, ReadAdrBase]> {
2908     let Inst{13} = 0b1;
2909   }
2910
2911   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2912 }
2913
2914 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2915                       string asm, dag ins, dag outs, list<dag> pat>
2916     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2917   bits<5> Rt;
2918   bits<5> Rn;
2919   bits<5> Rm;
2920   bits<2> extend;
2921   let Inst{31-30} = sz;
2922   let Inst{29-27} = 0b111;
2923   let Inst{26}    = V;
2924   let Inst{25-24} = 0b00;
2925   let Inst{23-22} = opc;
2926   let Inst{21}    = 1;
2927   let Inst{20-16} = Rm;
2928   let Inst{15}    = extend{1}; // sign extend Rm?
2929   let Inst{14}    = 1;
2930   let Inst{12}    = extend{0}; // do shift?
2931   let Inst{11-10} = 0b10;
2932   let Inst{9-5}   = Rn;
2933   let Inst{4-0}   = Rt;
2934 }
2935
2936 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2937                     string asm, ValueType Ty, SDPatternOperator loadop> {
2938   let AddedComplexity = 10 in
2939   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2940                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2941                  [(set (Ty regtype:$Rt),
2942                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2943                                               ro_Wextend32:$extend)))]>,
2944            Sched<[WriteLDIdx, ReadAdrBase]> {
2945     let Inst{13} = 0b0;
2946   }
2947
2948   let AddedComplexity = 10 in
2949   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2950                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2951                  [(set (Ty regtype:$Rt),
2952                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2953                                               ro_Xextend32:$extend)))]>,
2954            Sched<[WriteLDIdx, ReadAdrBase]> {
2955     let Inst{13} = 0b1;
2956   }
2957
2958   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2959 }
2960
2961 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2962                      string asm, ValueType Ty, SDPatternOperator storeop> {
2963   let AddedComplexity = 10 in
2964   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2965                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2966                 [(storeop (Ty regtype:$Rt),
2967                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2968                                          ro_Wextend32:$extend))]>,
2969             Sched<[WriteSTIdx, ReadAdrBase]> {
2970     let Inst{13} = 0b0;
2971   }
2972
2973   let AddedComplexity = 10 in
2974   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2975                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2976                 [(storeop (Ty regtype:$Rt),
2977                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2978                                         ro_Xextend32:$extend))]>,
2979             Sched<[WriteSTIdx, ReadAdrBase]> {
2980     let Inst{13} = 0b1;
2981   }
2982
2983   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2984 }
2985
2986 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2987                       string asm, dag ins, dag outs, list<dag> pat>
2988     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2989   bits<5> Rt;
2990   bits<5> Rn;
2991   bits<5> Rm;
2992   bits<2> extend;
2993   let Inst{31-30} = sz;
2994   let Inst{29-27} = 0b111;
2995   let Inst{26}    = V;
2996   let Inst{25-24} = 0b00;
2997   let Inst{23-22} = opc;
2998   let Inst{21}    = 1;
2999   let Inst{20-16} = Rm;
3000   let Inst{15}    = extend{1}; // sign extend Rm?
3001   let Inst{14}    = 1;
3002   let Inst{12}    = extend{0}; // do shift?
3003   let Inst{11-10} = 0b10;
3004   let Inst{9-5}   = Rn;
3005   let Inst{4-0}   = Rt;
3006 }
3007
3008 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3009                     string asm, ValueType Ty, SDPatternOperator loadop> {
3010   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3011   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3012                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3013                 [(set (Ty regtype:$Rt),
3014                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3015                                              ro_Wextend64:$extend)))]>,
3016            Sched<[WriteLDIdx, ReadAdrBase]> {
3017     let Inst{13} = 0b0;
3018   }
3019
3020   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3021   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3022                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3023                  [(set (Ty regtype:$Rt),
3024                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3025                                               ro_Xextend64:$extend)))]>,
3026            Sched<[WriteLDIdx, ReadAdrBase]> {
3027     let Inst{13} = 0b1;
3028   }
3029
3030   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3031 }
3032
3033 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3034                      string asm, ValueType Ty, SDPatternOperator storeop> {
3035   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3036   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3037                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3038                 [(storeop (Ty regtype:$Rt),
3039                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3040                                          ro_Wextend64:$extend))]>,
3041             Sched<[WriteSTIdx, ReadAdrBase]> {
3042     let Inst{13} = 0b0;
3043   }
3044
3045   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3046   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3047                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3048                 [(storeop (Ty regtype:$Rt),
3049                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3050                                          ro_Xextend64:$extend))]>,
3051             Sched<[WriteSTIdx, ReadAdrBase]> {
3052     let Inst{13} = 0b1;
3053   }
3054
3055   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3056 }
3057
3058 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3059                       string asm, dag ins, dag outs, list<dag> pat>
3060     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3061   bits<5> Rt;
3062   bits<5> Rn;
3063   bits<5> Rm;
3064   bits<2> extend;
3065   let Inst{31-30} = sz;
3066   let Inst{29-27} = 0b111;
3067   let Inst{26}    = V;
3068   let Inst{25-24} = 0b00;
3069   let Inst{23-22} = opc;
3070   let Inst{21}    = 1;
3071   let Inst{20-16} = Rm;
3072   let Inst{15}    = extend{1}; // sign extend Rm?
3073   let Inst{14}    = 1;
3074   let Inst{12}    = extend{0}; // do shift?
3075   let Inst{11-10} = 0b10;
3076   let Inst{9-5}   = Rn;
3077   let Inst{4-0}   = Rt;
3078 }
3079
3080 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3081                      string asm, ValueType Ty, SDPatternOperator loadop> {
3082   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3083   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3084                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3085                  [(set (Ty regtype:$Rt),
3086                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
3087                                                ro_Wextend128:$extend)))]>,
3088             Sched<[WriteLDIdx, ReadAdrBase]> {
3089     let Inst{13} = 0b0;
3090   }
3091
3092   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3093   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3094                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3095                  [(set (Ty regtype:$Rt),
3096                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
3097                                                ro_Xextend128:$extend)))]>,
3098             Sched<[WriteLDIdx, ReadAdrBase]> {
3099     let Inst{13} = 0b1;
3100   }
3101
3102   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3103 }
3104
3105 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3106                       string asm, ValueType Ty, SDPatternOperator storeop> {
3107   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3108   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3109                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3110                 []>,
3111             Sched<[WriteSTIdx, ReadAdrBase]> {
3112     let Inst{13} = 0b0;
3113   }
3114
3115   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3116   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3117                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3118                 []>,
3119             Sched<[WriteSTIdx, ReadAdrBase]> {
3120     let Inst{13} = 0b1;
3121   }
3122
3123   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3124 }
3125
3126 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3127 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
3128                      string asm, list<dag> pat>
3129     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
3130       Sched<[WriteLD]> {
3131   bits<5> Rt;
3132   bits<5> Rn;
3133   bits<5> Rm;
3134   bits<2> extend;
3135   let Inst{31-30} = sz;
3136   let Inst{29-27} = 0b111;
3137   let Inst{26}    = V;
3138   let Inst{25-24} = 0b00;
3139   let Inst{23-22} = opc;
3140   let Inst{21}    = 1;
3141   let Inst{20-16} = Rm;
3142   let Inst{15}    = extend{1}; // sign extend Rm?
3143   let Inst{14}    = 1;
3144   let Inst{12}    = extend{0}; // do shift?
3145   let Inst{11-10} = 0b10;
3146   let Inst{9-5}   = Rn;
3147   let Inst{4-0}   = Rt;
3148 }
3149
3150 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
3151   def roW : BasePrefetchRO<sz, V, opc, (outs),
3152                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3153                 asm, [(AArch64Prefetch imm:$Rt,
3154                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3155                                                     ro_Wextend64:$extend))]> {
3156     let Inst{13} = 0b0;
3157   }
3158
3159   def roX : BasePrefetchRO<sz, V, opc, (outs),
3160                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3161                 asm,  [(AArch64Prefetch imm:$Rt,
3162                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3163                                                      ro_Xextend64:$extend))]> {
3164     let Inst{13} = 0b1;
3165   }
3166
3167   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3168                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3169                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3170 }
3171
3172 //---
3173 // Load/store unscaled immediate
3174 //---
3175
3176 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3177 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3178 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3179 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3180 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3181
3182 def gi_am_unscaled8 :
3183     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
3184     GIComplexPatternEquiv<am_unscaled8>;
3185 def gi_am_unscaled16 :
3186     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
3187     GIComplexPatternEquiv<am_unscaled16>;
3188 def gi_am_unscaled32 :
3189     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
3190     GIComplexPatternEquiv<am_unscaled32>;
3191 def gi_am_unscaled64 :
3192     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
3193     GIComplexPatternEquiv<am_unscaled64>;
3194 def gi_am_unscaled128 :
3195     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
3196     GIComplexPatternEquiv<am_unscaled128>;
3197
3198
3199 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3200                            string asm, list<dag> pattern>
3201     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3202   bits<5> Rt;
3203   bits<5> Rn;
3204   bits<9> offset;
3205   let Inst{31-30} = sz;
3206   let Inst{29-27} = 0b111;
3207   let Inst{26}    = V;
3208   let Inst{25-24} = 0b00;
3209   let Inst{23-22} = opc;
3210   let Inst{21}    = 0;
3211   let Inst{20-12} = offset;
3212   let Inst{11-10} = 0b00;
3213   let Inst{9-5}   = Rn;
3214   let Inst{4-0}   = Rt;
3215
3216   let DecoderMethod = "DecodeSignedLdStInstruction";
3217 }
3218
3219 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3220                    string asm, list<dag> pattern> {
3221   let AddedComplexity = 1 in // try this before LoadUI
3222   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3223                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3224           Sched<[WriteLD]>;
3225
3226   def : InstAlias<asm # "\t$Rt, [$Rn]",
3227                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3228 }
3229
3230 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3231                          string asm, list<dag> pattern> {
3232   let AddedComplexity = 1 in // try this before StoreUI
3233   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3234                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3235                                asm, pattern>,
3236           Sched<[WriteST]>;
3237
3238   def : InstAlias<asm # "\t$Rt, [$Rn]",
3239                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3240 }
3241
3242 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3243                             list<dag> pat> {
3244   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3245   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3246                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3247                                asm, pat>,
3248           Sched<[WriteLD]>;
3249
3250   def : InstAlias<asm # "\t$Rt, [$Rn]",
3251                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3252 }
3253
3254 //---
3255 // Load/store unscaled immediate, unprivileged
3256 //---
3257
3258 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3259                                 dag oops, dag iops, string asm>
3260     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3261   bits<5> Rt;
3262   bits<5> Rn;
3263   bits<9> offset;
3264   let Inst{31-30} = sz;
3265   let Inst{29-27} = 0b111;
3266   let Inst{26}    = V;
3267   let Inst{25-24} = 0b00;
3268   let Inst{23-22} = opc;
3269   let Inst{21}    = 0;
3270   let Inst{20-12} = offset;
3271   let Inst{11-10} = 0b10;
3272   let Inst{9-5}   = Rn;
3273   let Inst{4-0}   = Rt;
3274
3275   let DecoderMethod = "DecodeSignedLdStInstruction";
3276 }
3277
3278 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3279                             RegisterClass regtype, string asm> {
3280   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3281   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3282                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
3283           Sched<[WriteLD]>;
3284
3285   def : InstAlias<asm # "\t$Rt, [$Rn]",
3286                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3287 }
3288
3289 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3290                              RegisterClass regtype, string asm> {
3291   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3292   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3293                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3294                                  asm>,
3295           Sched<[WriteST]>;
3296
3297   def : InstAlias<asm # "\t$Rt, [$Rn]",
3298                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3299 }
3300
3301 //---
3302 // Load/store pre-indexed
3303 //---
3304
3305 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3306                           string asm, string cstr, list<dag> pat>
3307     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3308   bits<5> Rt;
3309   bits<5> Rn;
3310   bits<9> offset;
3311   let Inst{31-30} = sz;
3312   let Inst{29-27} = 0b111;
3313   let Inst{26}    = V;
3314   let Inst{25-24} = 0;
3315   let Inst{23-22} = opc;
3316   let Inst{21}    = 0;
3317   let Inst{20-12} = offset;
3318   let Inst{11-10} = 0b11;
3319   let Inst{9-5}   = Rn;
3320   let Inst{4-0}   = Rt;
3321
3322   let DecoderMethod = "DecodeSignedLdStInstruction";
3323 }
3324
3325 let hasSideEffects = 0 in {
3326 let mayStore = 0, mayLoad = 1 in
3327 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3328              string asm>
3329     : BaseLoadStorePreIdx<sz, V, opc,
3330                      (outs GPR64sp:$wback, regtype:$Rt),
3331                      (ins GPR64sp:$Rn, simm9:$offset), asm,
3332                      "$Rn = $wback,@earlyclobber $wback", []>,
3333       Sched<[WriteLD, WriteAdr]>;
3334
3335 let mayStore = 1, mayLoad = 0 in
3336 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3337                   string asm, SDPatternOperator storeop, ValueType Ty>
3338     : BaseLoadStorePreIdx<sz, V, opc,
3339                       (outs GPR64sp:$wback),
3340                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3341                       asm, "$Rn = $wback,@earlyclobber $wback",
3342       [(set GPR64sp:$wback,
3343             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3344       Sched<[WriteAdr, WriteST]>;
3345 } // hasSideEffects = 0
3346
3347 //---
3348 // Load/store post-indexed
3349 //---
3350
3351 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3352                           string asm, string cstr, list<dag> pat>
3353     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3354   bits<5> Rt;
3355   bits<5> Rn;
3356   bits<9> offset;
3357   let Inst{31-30} = sz;
3358   let Inst{29-27} = 0b111;
3359   let Inst{26}    = V;
3360   let Inst{25-24} = 0b00;
3361   let Inst{23-22} = opc;
3362   let Inst{21}    = 0b0;
3363   let Inst{20-12} = offset;
3364   let Inst{11-10} = 0b01;
3365   let Inst{9-5}   = Rn;
3366   let Inst{4-0}   = Rt;
3367
3368   let DecoderMethod = "DecodeSignedLdStInstruction";
3369 }
3370
3371 let hasSideEffects = 0 in {
3372 let mayStore = 0, mayLoad = 1 in
3373 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3374              string asm>
3375     : BaseLoadStorePostIdx<sz, V, opc,
3376                       (outs GPR64sp:$wback, regtype:$Rt),
3377                       (ins GPR64sp:$Rn, simm9:$offset),
3378                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
3379       Sched<[WriteLD, WriteI]>;
3380
3381 let mayStore = 1, mayLoad = 0 in
3382 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3383                    string asm, SDPatternOperator storeop, ValueType Ty>
3384     : BaseLoadStorePostIdx<sz, V, opc,
3385                       (outs GPR64sp:$wback),
3386                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3387                        asm, "$Rn = $wback,@earlyclobber $wback",
3388       [(set GPR64sp:$wback,
3389             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3390     Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3391 } // hasSideEffects = 0
3392
3393
3394 //---
3395 // Load/store pair
3396 //---
3397
3398 // (indexed, offset)
3399
3400 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3401                               string asm>
3402     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3403   bits<5> Rt;
3404   bits<5> Rt2;
3405   bits<5> Rn;
3406   bits<7> offset;
3407   let Inst{31-30} = opc;
3408   let Inst{29-27} = 0b101;
3409   let Inst{26}    = V;
3410   let Inst{25-23} = 0b010;
3411   let Inst{22}    = L;
3412   let Inst{21-15} = offset;
3413   let Inst{14-10} = Rt2;
3414   let Inst{9-5}   = Rn;
3415   let Inst{4-0}   = Rt;
3416
3417   let DecoderMethod = "DecodePairLdStInstruction";
3418 }
3419
3420 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3421                           Operand indextype, string asm> {
3422   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3423   def i : BaseLoadStorePairOffset<opc, V, 1,
3424                                   (outs regtype:$Rt, regtype:$Rt2),
3425                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
3426           Sched<[WriteLD, WriteLDHi]>;
3427
3428   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3429                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3430                                                   GPR64sp:$Rn, 0)>;
3431 }
3432
3433
3434 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3435                            Operand indextype, string asm> {
3436   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3437   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3438                                   (ins regtype:$Rt, regtype:$Rt2,
3439                                        GPR64sp:$Rn, indextype:$offset),
3440                                   asm>,
3441           Sched<[WriteSTP]>;
3442
3443   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3444                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3445                                                   GPR64sp:$Rn, 0)>;
3446 }
3447
3448 // (pre-indexed)
3449 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3450                               string asm>
3451     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3452   bits<5> Rt;
3453   bits<5> Rt2;
3454   bits<5> Rn;
3455   bits<7> offset;
3456   let Inst{31-30} = opc;
3457   let Inst{29-27} = 0b101;
3458   let Inst{26}    = V;
3459   let Inst{25-23} = 0b011;
3460   let Inst{22}    = L;
3461   let Inst{21-15} = offset;
3462   let Inst{14-10} = Rt2;
3463   let Inst{9-5}   = Rn;
3464   let Inst{4-0}   = Rt;
3465
3466   let DecoderMethod = "DecodePairLdStInstruction";
3467 }
3468
3469 let hasSideEffects = 0 in {
3470 let mayStore = 0, mayLoad = 1 in
3471 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3472                      Operand indextype, string asm>
3473     : BaseLoadStorePairPreIdx<opc, V, 1,
3474                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3475                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
3476       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3477
3478 let mayStore = 1, mayLoad = 0 in
3479 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3480                       Operand indextype, string asm>
3481     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3482                              (ins regtype:$Rt, regtype:$Rt2,
3483                                   GPR64sp:$Rn, indextype:$offset),
3484                              asm>,
3485       Sched<[WriteAdr, WriteSTP]>;
3486 } // hasSideEffects = 0
3487
3488 // (post-indexed)
3489
3490 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3491                               string asm>
3492     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3493   bits<5> Rt;
3494   bits<5> Rt2;
3495   bits<5> Rn;
3496   bits<7> offset;
3497   let Inst{31-30} = opc;
3498   let Inst{29-27} = 0b101;
3499   let Inst{26}    = V;
3500   let Inst{25-23} = 0b001;
3501   let Inst{22}    = L;
3502   let Inst{21-15} = offset;
3503   let Inst{14-10} = Rt2;
3504   let Inst{9-5}   = Rn;
3505   let Inst{4-0}   = Rt;
3506
3507   let DecoderMethod = "DecodePairLdStInstruction";
3508 }
3509
3510 let hasSideEffects = 0 in {
3511 let mayStore = 0, mayLoad = 1 in
3512 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3513                       Operand idxtype, string asm>
3514     : BaseLoadStorePairPostIdx<opc, V, 1,
3515                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3516                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3517       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3518
3519 let mayStore = 1, mayLoad = 0 in
3520 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3521                        Operand idxtype, string asm>
3522     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3523                              (ins regtype:$Rt, regtype:$Rt2,
3524                                   GPR64sp:$Rn, idxtype:$offset),
3525                              asm>,
3526       Sched<[WriteAdr, WriteSTP]>;
3527 } // hasSideEffects = 0
3528
3529 //  (no-allocate)
3530
3531 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3532                               string asm>
3533     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3534   bits<5> Rt;
3535   bits<5> Rt2;
3536   bits<5> Rn;
3537   bits<7> offset;
3538   let Inst{31-30} = opc;
3539   let Inst{29-27} = 0b101;
3540   let Inst{26}    = V;
3541   let Inst{25-23} = 0b000;
3542   let Inst{22}    = L;
3543   let Inst{21-15} = offset;
3544   let Inst{14-10} = Rt2;
3545   let Inst{9-5}   = Rn;
3546   let Inst{4-0}   = Rt;
3547
3548   let DecoderMethod = "DecodePairLdStInstruction";
3549 }
3550
3551 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3552                            Operand indextype, string asm> {
3553   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3554   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3555                                    (outs regtype:$Rt, regtype:$Rt2),
3556                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
3557           Sched<[WriteLD, WriteLDHi]>;
3558
3559
3560   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3561                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3562                                                   GPR64sp:$Rn, 0)>;
3563 }
3564
3565 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3566                       Operand indextype, string asm> {
3567   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3568   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3569                                    (ins regtype:$Rt, regtype:$Rt2,
3570                                         GPR64sp:$Rn, indextype:$offset),
3571                                    asm>,
3572           Sched<[WriteSTP]>;
3573
3574   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3575                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3576                                                   GPR64sp:$Rn, 0)>;
3577 }
3578
3579 //---
3580 // Load/store exclusive
3581 //---
3582
3583 // True exclusive operations write to and/or read from the system's exclusive
3584 // monitors, which as far as a compiler is concerned can be modelled as a
3585 // random shared memory address. Hence LoadExclusive mayStore.
3586 //
3587 // Since these instructions have the undefined register bits set to 1 in
3588 // their canonical form, we need a post encoder method to set those bits
3589 // to 1 when encoding these instructions. We do this using the
3590 // fixLoadStoreExclusive function. This function has template parameters:
3591 //
3592 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3593 //
3594 // hasRs indicates that the instruction uses the Rs field, so we won't set
3595 // it to 1 (and the same for Rt2). We don't need template parameters for
3596 // the other register fields since Rt and Rn are always used.
3597 //
3598 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3599 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3600                              dag oops, dag iops, string asm, string operands>
3601     : I<oops, iops, asm, operands, "", []> {
3602   let Inst{31-30} = sz;
3603   let Inst{29-24} = 0b001000;
3604   let Inst{23}    = o2;
3605   let Inst{22}    = L;
3606   let Inst{21}    = o1;
3607   let Inst{15}    = o0;
3608
3609   let DecoderMethod = "DecodeExclusiveLdStInstruction";
3610 }
3611
3612 // Neither Rs nor Rt2 operands.
3613 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3614                                dag oops, dag iops, string asm, string operands>
3615     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3616   bits<5> Rt;
3617   bits<5> Rn;
3618   let Inst{20-16} = 0b11111;
3619   let Unpredictable{20-16} = 0b11111;
3620   let Inst{14-10} = 0b11111;
3621   let Unpredictable{14-10} = 0b11111;
3622   let Inst{9-5} = Rn;
3623   let Inst{4-0} = Rt;
3624
3625   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3626 }
3627
3628 // Simple load acquires don't set the exclusive monitor
3629 let mayLoad = 1, mayStore = 0 in
3630 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3631                   RegisterClass regtype, string asm>
3632     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3633                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3634       Sched<[WriteLD]>;
3635
3636 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3637                     RegisterClass regtype, string asm>
3638     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3639                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3640       Sched<[WriteLD]>;
3641
3642 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3643                        RegisterClass regtype, string asm>
3644     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3645                              (outs regtype:$Rt, regtype:$Rt2),
3646                              (ins GPR64sp0:$Rn), asm,
3647                              "\t$Rt, $Rt2, [$Rn]">,
3648       Sched<[WriteLD, WriteLDHi]> {
3649   bits<5> Rt;
3650   bits<5> Rt2;
3651   bits<5> Rn;
3652   let Inst{14-10} = Rt2;
3653   let Inst{9-5} = Rn;
3654   let Inst{4-0} = Rt;
3655
3656   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3657 }
3658
3659 // Simple store release operations do not check the exclusive monitor.
3660 let mayLoad = 0, mayStore = 1 in
3661 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3662                    RegisterClass regtype, string asm>
3663     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3664                                (ins regtype:$Rt, GPR64sp0:$Rn),
3665                                asm, "\t$Rt, [$Rn]">,
3666       Sched<[WriteST]>;
3667
3668 let mayLoad = 1, mayStore = 1 in
3669 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3670                      RegisterClass regtype, string asm>
3671     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3672                              (ins regtype:$Rt, GPR64sp0:$Rn),
3673                              asm, "\t$Ws, $Rt, [$Rn]">,
3674       Sched<[WriteSTX]> {
3675   bits<5> Ws;
3676   bits<5> Rt;
3677   bits<5> Rn;
3678   let Inst{20-16} = Ws;
3679   let Inst{9-5} = Rn;
3680   let Inst{4-0} = Rt;
3681
3682   let Constraints = "@earlyclobber $Ws";
3683   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3684 }
3685
3686 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3687                          RegisterClass regtype, string asm>
3688     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3689                              (outs GPR32:$Ws),
3690                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3691                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3692       Sched<[WriteSTX]> {
3693   bits<5> Ws;
3694   bits<5> Rt;
3695   bits<5> Rt2;
3696   bits<5> Rn;
3697   let Inst{20-16} = Ws;
3698   let Inst{14-10} = Rt2;
3699   let Inst{9-5} = Rn;
3700   let Inst{4-0} = Rt;
3701
3702   let Constraints = "@earlyclobber $Ws";
3703 }
3704
3705 //---
3706 // Exception generation
3707 //---
3708
3709 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3710 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3711     : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3712       Sched<[WriteSys]> {
3713   bits<16> imm;
3714   let Inst{31-24} = 0b11010100;
3715   let Inst{23-21} = op1;
3716   let Inst{20-5}  = imm;
3717   let Inst{4-2}   = 0b000;
3718   let Inst{1-0}   = ll;
3719 }
3720
3721 let Predicates = [HasFPARMv8] in {
3722
3723 //---
3724 // Floating point to integer conversion
3725 //---
3726
3727 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3728                       RegisterClass srcType, RegisterClass dstType,
3729                       string asm, list<dag> pattern>
3730     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3731          asm, "\t$Rd, $Rn", "", pattern>,
3732       Sched<[WriteFCvt]> {
3733   bits<5> Rd;
3734   bits<5> Rn;
3735   let Inst{30-29} = 0b00;
3736   let Inst{28-24} = 0b11110;
3737   let Inst{23-22} = type;
3738   let Inst{21}    = 1;
3739   let Inst{20-19} = rmode;
3740   let Inst{18-16} = opcode;
3741   let Inst{15-10} = 0;
3742   let Inst{9-5}   = Rn;
3743   let Inst{4-0}   = Rd;
3744 }
3745
3746 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3747 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3748                       RegisterClass srcType, RegisterClass dstType,
3749                       Operand immType, string asm, list<dag> pattern>
3750     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3751          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3752       Sched<[WriteFCvt]> {
3753   bits<5> Rd;
3754   bits<5> Rn;
3755   bits<6> scale;
3756   let Inst{30-29} = 0b00;
3757   let Inst{28-24} = 0b11110;
3758   let Inst{23-22} = type;
3759   let Inst{21}    = 0;
3760   let Inst{20-19} = rmode;
3761   let Inst{18-16} = opcode;
3762   let Inst{15-10} = scale;
3763   let Inst{9-5}   = Rn;
3764   let Inst{4-0}   = Rd;
3765 }
3766
3767 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3768            SDPatternOperator OpN> {
3769   // Unscaled half-precision to 32-bit
3770   def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
3771                                      [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
3772     let Inst{31} = 0; // 32-bit GPR flag
3773     let Predicates = [HasFullFP16];
3774   }
3775
3776   // Unscaled half-precision to 64-bit
3777   def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
3778                                      [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
3779     let Inst{31} = 1; // 64-bit GPR flag
3780     let Predicates = [HasFullFP16];
3781   }
3782
3783   // Unscaled single-precision to 32-bit
3784   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3785                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3786     let Inst{31} = 0; // 32-bit GPR flag
3787   }
3788
3789   // Unscaled single-precision to 64-bit
3790   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3791                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3792     let Inst{31} = 1; // 64-bit GPR flag
3793   }
3794
3795   // Unscaled double-precision to 32-bit
3796   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3797                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3798     let Inst{31} = 0; // 32-bit GPR flag
3799   }
3800
3801   // Unscaled double-precision to 64-bit
3802   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3803                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3804     let Inst{31} = 1; // 64-bit GPR flag
3805   }
3806 }
3807
3808 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3809                              SDPatternOperator OpN> {
3810   // Scaled half-precision to 32-bit
3811   def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
3812                               fixedpoint_f16_i32, asm,
3813               [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
3814                                           fixedpoint_f16_i32:$scale)))]> {
3815     let Inst{31} = 0; // 32-bit GPR flag
3816     let scale{5} = 1;
3817     let Predicates = [HasFullFP16];
3818   }
3819
3820   // Scaled half-precision to 64-bit
3821   def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
3822                               fixedpoint_f16_i64, asm,
3823               [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
3824                                           fixedpoint_f16_i64:$scale)))]> {
3825     let Inst{31} = 1; // 64-bit GPR flag
3826     let Predicates = [HasFullFP16];
3827   }
3828
3829   // Scaled single-precision to 32-bit
3830   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3831                               fixedpoint_f32_i32, asm,
3832               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3833                                           fixedpoint_f32_i32:$scale)))]> {
3834     let Inst{31} = 0; // 32-bit GPR flag
3835     let scale{5} = 1;
3836   }
3837
3838   // Scaled single-precision to 64-bit
3839   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3840                               fixedpoint_f32_i64, asm,
3841               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3842                                           fixedpoint_f32_i64:$scale)))]> {
3843     let Inst{31} = 1; // 64-bit GPR flag
3844   }
3845
3846   // Scaled double-precision to 32-bit
3847   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3848                               fixedpoint_f64_i32, asm,
3849               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3850                                           fixedpoint_f64_i32:$scale)))]> {
3851     let Inst{31} = 0; // 32-bit GPR flag
3852     let scale{5} = 1;
3853   }
3854
3855   // Scaled double-precision to 64-bit
3856   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3857                               fixedpoint_f64_i64, asm,
3858               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3859                                           fixedpoint_f64_i64:$scale)))]> {
3860     let Inst{31} = 1; // 64-bit GPR flag
3861   }
3862 }
3863
3864 //---
3865 // Integer to floating point conversion
3866 //---
3867
3868 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3869 class BaseIntegerToFP<bit isUnsigned,
3870                       RegisterClass srcType, RegisterClass dstType,
3871                       Operand immType, string asm, list<dag> pattern>
3872     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3873          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3874       Sched<[WriteFCvt]> {
3875   bits<5> Rd;
3876   bits<5> Rn;
3877   bits<6> scale;
3878   let Inst{30-24} = 0b0011110;
3879   let Inst{21-17} = 0b00001;
3880   let Inst{16}    = isUnsigned;
3881   let Inst{15-10} = scale;
3882   let Inst{9-5}   = Rn;
3883   let Inst{4-0}   = Rd;
3884 }
3885
3886 class BaseIntegerToFPUnscaled<bit isUnsigned,
3887                       RegisterClass srcType, RegisterClass dstType,
3888                       ValueType dvt, string asm, SDNode node>
3889     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3890          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3891       Sched<[WriteFCvt]> {
3892   bits<5> Rd;
3893   bits<5> Rn;
3894   bits<6> scale;
3895   let Inst{30-24} = 0b0011110;
3896   let Inst{21-17} = 0b10001;
3897   let Inst{16}    = isUnsigned;
3898   let Inst{15-10} = 0b000000;
3899   let Inst{9-5}   = Rn;
3900   let Inst{4-0}   = Rd;
3901 }
3902
3903 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3904   // Unscaled
3905   def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
3906     let Inst{31} = 0; // 32-bit GPR flag
3907     let Inst{23-22} = 0b11; // 16-bit FPR flag
3908     let Predicates = [HasFullFP16];
3909   }
3910
3911   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3912     let Inst{31} = 0; // 32-bit GPR flag
3913     let Inst{23-22} = 0b00; // 32-bit FPR flag
3914   }
3915
3916   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3917     let Inst{31} = 0; // 32-bit GPR flag
3918     let Inst{23-22} = 0b01; // 64-bit FPR flag
3919   }
3920
3921   def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
3922     let Inst{31} = 1; // 64-bit GPR flag
3923     let Inst{23-22} = 0b11; // 16-bit FPR flag
3924     let Predicates = [HasFullFP16];
3925   }
3926
3927   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3928     let Inst{31} = 1; // 64-bit GPR flag
3929     let Inst{23-22} = 0b00; // 32-bit FPR flag
3930   }
3931
3932   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3933     let Inst{31} = 1; // 64-bit GPR flag
3934     let Inst{23-22} = 0b01; // 64-bit FPR flag
3935   }
3936
3937   // Scaled
3938   def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
3939                              [(set FPR16:$Rd,
3940                                    (fdiv (node GPR32:$Rn),
3941                                          fixedpoint_f16_i32:$scale))]> {
3942     let Inst{31} = 0; // 32-bit GPR flag
3943     let Inst{23-22} = 0b11; // 16-bit FPR flag
3944     let scale{5} = 1;
3945     let Predicates = [HasFullFP16];
3946   }
3947
3948   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3949                              [(set FPR32:$Rd,
3950                                    (fdiv (node GPR32:$Rn),
3951                                          fixedpoint_f32_i32:$scale))]> {
3952     let Inst{31} = 0; // 32-bit GPR flag
3953     let Inst{23-22} = 0b00; // 32-bit FPR flag
3954     let scale{5} = 1;
3955   }
3956
3957   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3958                              [(set FPR64:$Rd,
3959                                    (fdiv (node GPR32:$Rn),
3960                                          fixedpoint_f64_i32:$scale))]> {
3961     let Inst{31} = 0; // 32-bit GPR flag
3962     let Inst{23-22} = 0b01; // 64-bit FPR flag
3963     let scale{5} = 1;
3964   }
3965
3966   def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
3967                              [(set FPR16:$Rd,
3968                                    (fdiv (node GPR64:$Rn),
3969                                          fixedpoint_f16_i64:$scale))]> {
3970     let Inst{31} = 1; // 64-bit GPR flag
3971     let Inst{23-22} = 0b11; // 16-bit FPR flag
3972     let Predicates = [HasFullFP16];
3973   }
3974
3975   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3976                              [(set FPR32:$Rd,
3977                                    (fdiv (node GPR64:$Rn),
3978                                          fixedpoint_f32_i64:$scale))]> {
3979     let Inst{31} = 1; // 64-bit GPR flag
3980     let Inst{23-22} = 0b00; // 32-bit FPR flag
3981   }
3982
3983   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3984                              [(set FPR64:$Rd,
3985                                    (fdiv (node GPR64:$Rn),
3986                                          fixedpoint_f64_i64:$scale))]> {
3987     let Inst{31} = 1; // 64-bit GPR flag
3988     let Inst{23-22} = 0b01; // 64-bit FPR flag
3989   }
3990 }
3991
3992 //---
3993 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3994 //---
3995
3996 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3997 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3998                       RegisterClass srcType, RegisterClass dstType,
3999                       string asm>
4000     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
4001         // We use COPY_TO_REGCLASS for these bitconvert operations.
4002         // copyPhysReg() expands the resultant COPY instructions after
4003         // regalloc is done. This gives greater freedom for the allocator
4004         // and related passes (coalescing, copy propagation, et. al.) to
4005         // be more effective.
4006         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
4007       Sched<[WriteFCopy]> {
4008   bits<5> Rd;
4009   bits<5> Rn;
4010   let Inst{30-24} = 0b0011110;
4011   let Inst{21}    = 1;
4012   let Inst{20-19} = rmode;
4013   let Inst{18-16} = opcode;
4014   let Inst{15-10} = 0b000000;
4015   let Inst{9-5}   = Rn;
4016   let Inst{4-0}   = Rd;
4017 }
4018
4019 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4020 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
4021                      RegisterClass srcType, RegisterOperand dstType, string asm,
4022                      string kind>
4023     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4024         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
4025       Sched<[WriteFCopy]> {
4026   bits<5> Rd;
4027   bits<5> Rn;
4028   let Inst{30-23} = 0b00111101;
4029   let Inst{21}    = 1;
4030   let Inst{20-19} = rmode;
4031   let Inst{18-16} = opcode;
4032   let Inst{15-10} = 0b000000;
4033   let Inst{9-5}   = Rn;
4034   let Inst{4-0}   = Rd;
4035
4036   let DecoderMethod =  "DecodeFMOVLaneInstruction";
4037 }
4038
4039 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4040 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
4041                      RegisterOperand srcType, RegisterClass dstType, string asm,
4042                      string kind>
4043     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4044         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
4045       Sched<[WriteFCopy]> {
4046   bits<5> Rd;
4047   bits<5> Rn;
4048   let Inst{30-23} = 0b00111101;
4049   let Inst{21}    = 1;
4050   let Inst{20-19} = rmode;
4051   let Inst{18-16} = opcode;
4052   let Inst{15-10} = 0b000000;
4053   let Inst{9-5}   = Rn;
4054   let Inst{4-0}   = Rd;
4055
4056   let DecoderMethod =  "DecodeFMOVLaneInstruction";
4057 }
4058
4059
4060 multiclass UnscaledConversion<string asm> {
4061   def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
4062     let Inst{31} = 0; // 32-bit GPR flag
4063     let Inst{23-22} = 0b11; // 16-bit FPR flag
4064     let Predicates = [HasFullFP16];
4065   }
4066
4067   def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
4068     let Inst{31} = 1; // 64-bit GPR flag
4069     let Inst{23-22} = 0b11; // 16-bit FPR flag
4070     let Predicates = [HasFullFP16];
4071   }
4072
4073   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
4074     let Inst{31} = 0; // 32-bit GPR flag
4075     let Inst{23-22} = 0b00; // 32-bit FPR flag
4076   }
4077
4078   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
4079     let Inst{31} = 1; // 64-bit GPR flag
4080     let Inst{23-22} = 0b01; // 64-bit FPR flag
4081   }
4082
4083   def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
4084     let Inst{31} = 0; // 32-bit GPR flag
4085     let Inst{23-22} = 0b11; // 16-bit FPR flag
4086     let Predicates = [HasFullFP16];
4087   }
4088
4089   def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
4090     let Inst{31} = 1; // 64-bit GPR flag
4091     let Inst{23-22} = 0b11; // 16-bit FPR flag
4092     let Predicates = [HasFullFP16];
4093   }
4094
4095   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
4096     let Inst{31} = 0; // 32-bit GPR flag
4097     let Inst{23-22} = 0b00; // 32-bit FPR flag
4098   }
4099
4100   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
4101     let Inst{31} = 1; // 64-bit GPR flag
4102     let Inst{23-22} = 0b01; // 64-bit FPR flag
4103   }
4104
4105   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
4106                                              asm, ".d"> {
4107     let Inst{31} = 1;
4108     let Inst{22} = 0;
4109   }
4110
4111   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
4112                                                asm, ".d"> {
4113     let Inst{31} = 1;
4114     let Inst{22} = 0;
4115   }
4116 }
4117
4118 //---
4119 // Floating point conversion
4120 //---
4121
4122 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
4123                        RegisterClass srcType, string asm, list<dag> pattern>
4124     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
4125       Sched<[WriteFCvt]> {
4126   bits<5> Rd;
4127   bits<5> Rn;
4128   let Inst{31-24} = 0b00011110;
4129   let Inst{23-22} = type;
4130   let Inst{21-17} = 0b10001;
4131   let Inst{16-15} = opcode;
4132   let Inst{14-10} = 0b10000;
4133   let Inst{9-5}   = Rn;
4134   let Inst{4-0}   = Rd;
4135 }
4136
4137 multiclass FPConversion<string asm> {
4138   // Double-precision to Half-precision
4139   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4140                              [(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
4141
4142   // Double-precision to Single-precision
4143   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4144                              [(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
4145
4146   // Half-precision to Double-precision
4147   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
4148                              [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>;
4149
4150   // Half-precision to Single-precision
4151   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
4152                              [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>;
4153
4154   // Single-precision to Double-precision
4155   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
4156                              [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
4157
4158   // Single-precision to Half-precision
4159   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4160                              [(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
4161 }
4162
4163 //---
4164 // Single operand floating point data processing
4165 //---
4166
4167 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4168 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
4169                               ValueType vt, string asm, SDPatternOperator node>
4170     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
4171          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
4172       Sched<[WriteF]> {
4173   bits<5> Rd;
4174   bits<5> Rn;
4175   let Inst{31-24} = 0b00011110;
4176   let Inst{21-19} = 0b100;
4177   let Inst{18-15} = opcode;
4178   let Inst{14-10} = 0b10000;
4179   let Inst{9-5}   = Rn;
4180   let Inst{4-0}   = Rd;
4181 }
4182
4183 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4184                                SDPatternOperator node = null_frag> {
4185   def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
4186     let Inst{23-22} = 0b11; // 16-bit size flag
4187     let Predicates = [HasFullFP16];
4188   }
4189
4190   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4191     let Inst{23-22} = 0b00; // 32-bit size flag
4192   }
4193
4194   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4195     let Inst{23-22} = 0b01; // 64-bit size flag
4196   }
4197 }
4198
4199 //---
4200 // Two operand floating point data processing
4201 //---
4202
4203 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4204 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4205                            string asm, list<dag> pat>
4206     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4207          asm, "\t$Rd, $Rn, $Rm", "", pat>,
4208       Sched<[WriteF]> {
4209   bits<5> Rd;
4210   bits<5> Rn;
4211   bits<5> Rm;
4212   let Inst{31-24} = 0b00011110;
4213   let Inst{21}    = 1;
4214   let Inst{20-16} = Rm;
4215   let Inst{15-12} = opcode;
4216   let Inst{11-10} = 0b10;
4217   let Inst{9-5}   = Rn;
4218   let Inst{4-0}   = Rd;
4219 }
4220
4221 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4222                             SDPatternOperator node = null_frag> {
4223   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4224                          [(set (f16 FPR16:$Rd),
4225                                (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4226     let Inst{23-22} = 0b11; // 16-bit size flag
4227     let Predicates = [HasFullFP16];
4228   }
4229
4230   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4231                          [(set (f32 FPR32:$Rd),
4232                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4233     let Inst{23-22} = 0b00; // 32-bit size flag
4234   }
4235
4236   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4237                          [(set (f64 FPR64:$Rd),
4238                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4239     let Inst{23-22} = 0b01; // 64-bit size flag
4240   }
4241 }
4242
4243 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4244   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4245                   [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4246     let Inst{23-22} = 0b11; // 16-bit size flag
4247     let Predicates = [HasFullFP16];
4248   }
4249
4250   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4251                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4252     let Inst{23-22} = 0b00; // 32-bit size flag
4253   }
4254
4255   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4256                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4257     let Inst{23-22} = 0b01; // 64-bit size flag
4258   }
4259 }
4260
4261
4262 //---
4263 // Three operand floating point data processing
4264 //---
4265
4266 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4267                              RegisterClass regtype, string asm, list<dag> pat>
4268     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4269          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4270       Sched<[WriteFMul]> {
4271   bits<5> Rd;
4272   bits<5> Rn;
4273   bits<5> Rm;
4274   bits<5> Ra;
4275   let Inst{31-24} = 0b00011111;
4276   let Inst{21}    = isNegated;
4277   let Inst{20-16} = Rm;
4278   let Inst{15}    = isSub;
4279   let Inst{14-10} = Ra;
4280   let Inst{9-5}   = Rn;
4281   let Inst{4-0}   = Rd;
4282 }
4283
4284 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4285                               SDPatternOperator node> {
4286   def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4287             [(set FPR16:$Rd,
4288                   (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4289     let Inst{23-22} = 0b11; // 16-bit size flag
4290     let Predicates = [HasFullFP16];
4291   }
4292
4293   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4294             [(set FPR32:$Rd,
4295                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4296     let Inst{23-22} = 0b00; // 32-bit size flag
4297   }
4298
4299   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4300             [(set FPR64:$Rd,
4301                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
4302     let Inst{23-22} = 0b01; // 64-bit size flag
4303   }
4304 }
4305
4306 //---
4307 // Floating point data comparisons
4308 //---
4309
4310 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4311 class BaseOneOperandFPComparison<bit signalAllNans,
4312                                  RegisterClass regtype, string asm,
4313                                  list<dag> pat>
4314     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4315       Sched<[WriteFCmp]> {
4316   bits<5> Rn;
4317   let Inst{31-24} = 0b00011110;
4318   let Inst{21}    = 1;
4319
4320   let Inst{15-10} = 0b001000;
4321   let Inst{9-5}   = Rn;
4322   let Inst{4}     = signalAllNans;
4323   let Inst{3-0}   = 0b1000;
4324
4325   // Rm should be 0b00000 canonically, but we need to accept any value.
4326   let PostEncoderMethod = "fixOneOperandFPComparison";
4327 }
4328
4329 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4330 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4331                                 string asm, list<dag> pat>
4332     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4333       Sched<[WriteFCmp]> {
4334   bits<5> Rm;
4335   bits<5> Rn;
4336   let Inst{31-24} = 0b00011110;
4337   let Inst{21}    = 1;
4338   let Inst{20-16} = Rm;
4339   let Inst{15-10} = 0b001000;
4340   let Inst{9-5}   = Rn;
4341   let Inst{4}     = signalAllNans;
4342   let Inst{3-0}   = 0b0000;
4343 }
4344
4345 multiclass FPComparison<bit signalAllNans, string asm,
4346                         SDPatternOperator OpNode = null_frag> {
4347   let Defs = [NZCV] in {
4348   def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4349       [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4350     let Inst{23-22} = 0b11;
4351     let Predicates = [HasFullFP16];
4352   }
4353
4354   def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4355       [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4356     let Inst{23-22} = 0b11;
4357     let Predicates = [HasFullFP16];
4358   }
4359
4360   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4361       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4362     let Inst{23-22} = 0b00;
4363   }
4364
4365   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4366       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4367     let Inst{23-22} = 0b00;
4368   }
4369
4370   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4371       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4372     let Inst{23-22} = 0b01;
4373   }
4374
4375   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4376       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4377     let Inst{23-22} = 0b01;
4378   }
4379   } // Defs = [NZCV]
4380 }
4381
4382 //---
4383 // Floating point conditional comparisons
4384 //---
4385
4386 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4387 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4388                            string mnemonic, list<dag> pat>
4389     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4390          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4391       Sched<[WriteFCmp]> {
4392   let Uses = [NZCV];
4393   let Defs = [NZCV];
4394
4395   bits<5> Rn;
4396   bits<5> Rm;
4397   bits<4> nzcv;
4398   bits<4> cond;
4399
4400   let Inst{31-24} = 0b00011110;
4401   let Inst{21}    = 1;
4402   let Inst{20-16} = Rm;
4403   let Inst{15-12} = cond;
4404   let Inst{11-10} = 0b01;
4405   let Inst{9-5}   = Rn;
4406   let Inst{4}     = signalAllNans;
4407   let Inst{3-0}   = nzcv;
4408 }
4409
4410 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4411                             SDPatternOperator OpNode = null_frag> {
4412   def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
4413     let Inst{23-22} = 0b11;
4414     let Predicates = [HasFullFP16];
4415   }
4416
4417   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4418       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4419                           (i32 imm:$cond), NZCV))]> {
4420     let Inst{23-22} = 0b00;
4421   }
4422
4423   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4424       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4425                           (i32 imm:$cond), NZCV))]> {
4426     let Inst{23-22} = 0b01;
4427   }
4428 }
4429
4430 //---
4431 // Floating point conditional select
4432 //---
4433
4434 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4435     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4436          asm, "\t$Rd, $Rn, $Rm, $cond", "",
4437          [(set regtype:$Rd,
4438                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4439                           (i32 imm:$cond), NZCV))]>,
4440       Sched<[WriteF]> {
4441   bits<5> Rd;
4442   bits<5> Rn;
4443   bits<5> Rm;
4444   bits<4> cond;
4445
4446   let Inst{31-24} = 0b00011110;
4447   let Inst{21}    = 1;
4448   let Inst{20-16} = Rm;
4449   let Inst{15-12} = cond;
4450   let Inst{11-10} = 0b11;
4451   let Inst{9-5}   = Rn;
4452   let Inst{4-0}   = Rd;
4453 }
4454
4455 multiclass FPCondSelect<string asm> {
4456   let Uses = [NZCV] in {
4457   def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4458     let Inst{23-22} = 0b11;
4459     let Predicates = [HasFullFP16];
4460   }
4461
4462   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4463     let Inst{23-22} = 0b00;
4464   }
4465
4466   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4467     let Inst{23-22} = 0b01;
4468   }
4469   } // Uses = [NZCV]
4470 }
4471
4472 //---
4473 // Floating move immediate
4474 //---
4475
4476 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4477   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4478       [(set regtype:$Rd, fpimmtype:$imm)]>,
4479     Sched<[WriteFImm]> {
4480   bits<5> Rd;
4481   bits<8> imm;
4482   let Inst{31-24} = 0b00011110;
4483   let Inst{21}    = 1;
4484   let Inst{20-13} = imm;
4485   let Inst{12-5}  = 0b10000000;
4486   let Inst{4-0}   = Rd;
4487 }
4488
4489 multiclass FPMoveImmediate<string asm> {
4490   def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4491     let Inst{23-22} = 0b11;
4492     let Predicates = [HasFullFP16];
4493   }
4494
4495   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4496     let Inst{23-22} = 0b00;
4497   }
4498
4499   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4500     let Inst{23-22} = 0b01;
4501   }
4502 }
4503 } // end of 'let Predicates = [HasFPARMv8]'
4504
4505 //----------------------------------------------------------------------------
4506 // AdvSIMD
4507 //----------------------------------------------------------------------------
4508
4509 let Predicates = [HasNEON] in {
4510
4511 //----------------------------------------------------------------------------
4512 // AdvSIMD three register vector instructions
4513 //----------------------------------------------------------------------------
4514
4515 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4516 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
4517                         RegisterOperand regtype, string asm, string kind,
4518                         list<dag> pattern>
4519   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4520       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4521       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4522     Sched<[WriteV]> {
4523   bits<5> Rd;
4524   bits<5> Rn;
4525   bits<5> Rm;
4526   let Inst{31}    = 0;
4527   let Inst{30}    = Q;
4528   let Inst{29}    = U;
4529   let Inst{28-24} = 0b01110;
4530   let Inst{23-21} = size;
4531   let Inst{20-16} = Rm;
4532   let Inst{15-11} = opcode;
4533   let Inst{10}    = 1;
4534   let Inst{9-5}   = Rn;
4535   let Inst{4-0}   = Rd;
4536 }
4537
4538 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4539 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
4540                         RegisterOperand regtype, string asm, string kind,
4541                         list<dag> pattern>
4542   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4543       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4544       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4545     Sched<[WriteV]> {
4546   bits<5> Rd;
4547   bits<5> Rn;
4548   bits<5> Rm;
4549   let Inst{31}    = 0;
4550   let Inst{30}    = Q;
4551   let Inst{29}    = U;
4552   let Inst{28-24} = 0b01110;
4553   let Inst{23-21} = size;
4554   let Inst{20-16} = Rm;
4555   let Inst{15-11} = opcode;
4556   let Inst{10}    = 1;
4557   let Inst{9-5}   = Rn;
4558   let Inst{4-0}   = Rd;
4559 }
4560
4561 class BaseSIMDThreeSameVectorDot<bit Q, bit U, string asm, string kind1,
4562                                  string kind2> :
4563         BaseSIMDThreeSameVector<Q, U, 0b100, 0b10010, V128, asm, kind1, [] > {
4564   let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
4565 }
4566
4567 // All operand sizes distinguished in the encoding.
4568 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4569                                SDPatternOperator OpNode> {
4570   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4571                                       asm, ".8b",
4572          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4573   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4574                                       asm, ".16b",
4575          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4576   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4577                                       asm, ".4h",
4578          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4579   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4580                                       asm, ".8h",
4581          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4582   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4583                                       asm, ".2s",
4584          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4585   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4586                                       asm, ".4s",
4587          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4588   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
4589                                       asm, ".2d",
4590          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4591 }
4592
4593 // As above, but D sized elements unsupported.
4594 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4595                                   SDPatternOperator OpNode> {
4596   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4597                                       asm, ".8b",
4598         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4599   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4600                                       asm, ".16b",
4601         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4602   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4603                                       asm, ".4h",
4604         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4605   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4606                                       asm, ".8h",
4607         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4608   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4609                                       asm, ".2s",
4610         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4611   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4612                                       asm, ".4s",
4613         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4614 }
4615
4616 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4617                                   SDPatternOperator OpNode> {
4618   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
4619                                       asm, ".8b",
4620       [(set (v8i8 V64:$dst),
4621             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4622   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
4623                                       asm, ".16b",
4624       [(set (v16i8 V128:$dst),
4625             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4626   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
4627                                       asm, ".4h",
4628       [(set (v4i16 V64:$dst),
4629             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4630   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
4631                                       asm, ".8h",
4632       [(set (v8i16 V128:$dst),
4633             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4634   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
4635                                       asm, ".2s",
4636       [(set (v2i32 V64:$dst),
4637             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4638   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
4639                                       asm, ".4s",
4640       [(set (v4i32 V128:$dst),
4641             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4642 }
4643
4644 // As above, but only B sized elements supported.
4645 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4646                                 SDPatternOperator OpNode> {
4647   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4648                                       asm, ".8b",
4649     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4650   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4651                                       asm, ".16b",
4652     [(set (v16i8 V128:$Rd),
4653           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4654 }
4655
4656 // As above, but only floating point elements supported.
4657 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
4658                                  string asm, SDPatternOperator OpNode> {
4659   let Predicates = [HasNEON, HasFullFP16] in {
4660   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4661                                       asm, ".4h",
4662         [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4663   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4664                                       asm, ".8h",
4665         [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4666   } // Predicates = [HasNEON, HasFullFP16]
4667   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4668                                       asm, ".2s",
4669         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4670   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4671                                       asm, ".4s",
4672         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4673   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4674                                       asm, ".2d",
4675         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4676 }
4677
4678 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
4679                                     string asm,
4680                                     SDPatternOperator OpNode> {
4681   let Predicates = [HasNEON, HasFullFP16] in {
4682   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4683                                       asm, ".4h",
4684         [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4685   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4686                                       asm, ".8h",
4687         [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4688   } // Predicates = [HasNEON, HasFullFP16]
4689   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4690                                       asm, ".2s",
4691         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4692   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4693                                       asm, ".4s",
4694         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4695   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4696                                       asm, ".2d",
4697         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4698 }
4699
4700 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
4701                                  string asm, SDPatternOperator OpNode> {
4702   let Predicates = [HasNEON, HasFullFP16] in {
4703   def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
4704                                       asm, ".4h",
4705      [(set (v4f16 V64:$dst),
4706            (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4707   def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
4708                                       asm, ".8h",
4709      [(set (v8f16 V128:$dst),
4710            (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4711   } // Predicates = [HasNEON, HasFullFP16]
4712   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
4713                                       asm, ".2s",
4714      [(set (v2f32 V64:$dst),
4715            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4716   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
4717                                       asm, ".4s",
4718      [(set (v4f32 V128:$dst),
4719            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4720   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
4721                                       asm, ".2d",
4722      [(set (v2f64 V128:$dst),
4723            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4724 }
4725
4726 // As above, but D and B sized elements unsupported.
4727 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4728                                 SDPatternOperator OpNode> {
4729   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4730                                       asm, ".4h",
4731         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4732   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4733                                       asm, ".8h",
4734         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4735   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4736                                       asm, ".2s",
4737         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4738   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4739                                       asm, ".4s",
4740         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4741 }
4742
4743 // Logical three vector ops share opcode bits, and only use B sized elements.
4744 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4745                                   SDPatternOperator OpNode = null_frag> {
4746   def v8i8  : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
4747                                      asm, ".8b",
4748                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4749   def v16i8  : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
4750                                      asm, ".16b",
4751                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4752
4753   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4754           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4755   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4756           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4757   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4758           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4759
4760   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4761       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4762   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4763       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4764   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4765       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4766 }
4767
4768 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4769                                   string asm, SDPatternOperator OpNode> {
4770   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
4771                                      asm, ".8b",
4772              [(set (v8i8 V64:$dst),
4773                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4774   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
4775                                      asm, ".16b",
4776              [(set (v16i8 V128:$dst),
4777                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4778                            (v16i8 V128:$Rm)))]>;
4779
4780   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4781                            (v4i16 V64:$RHS))),
4782           (!cast<Instruction>(NAME#"v8i8")
4783             V64:$LHS, V64:$MHS, V64:$RHS)>;
4784   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4785                            (v2i32 V64:$RHS))),
4786           (!cast<Instruction>(NAME#"v8i8")
4787             V64:$LHS, V64:$MHS, V64:$RHS)>;
4788   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4789                            (v1i64 V64:$RHS))),
4790           (!cast<Instruction>(NAME#"v8i8")
4791             V64:$LHS, V64:$MHS, V64:$RHS)>;
4792
4793   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4794                            (v8i16 V128:$RHS))),
4795       (!cast<Instruction>(NAME#"v16i8")
4796         V128:$LHS, V128:$MHS, V128:$RHS)>;
4797   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4798                            (v4i32 V128:$RHS))),
4799       (!cast<Instruction>(NAME#"v16i8")
4800         V128:$LHS, V128:$MHS, V128:$RHS)>;
4801   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4802                            (v2i64 V128:$RHS))),
4803       (!cast<Instruction>(NAME#"v16i8")
4804         V128:$LHS, V128:$MHS, V128:$RHS)>;
4805 }
4806
4807
4808 //----------------------------------------------------------------------------
4809 // AdvSIMD two register vector instructions.
4810 //----------------------------------------------------------------------------
4811
4812 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4813 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4814                             bits<2> size2, RegisterOperand regtype, string asm,
4815                             string dstkind, string srckind, list<dag> pattern>
4816   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4817       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4818       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4819     Sched<[WriteV]> {
4820   bits<5> Rd;
4821   bits<5> Rn;
4822   let Inst{31}    = 0;
4823   let Inst{30}    = Q;
4824   let Inst{29}    = U;
4825   let Inst{28-24} = 0b01110;
4826   let Inst{23-22} = size;
4827   let Inst{21} = 0b1;
4828   let Inst{20-19} = size2;
4829   let Inst{18-17} = 0b00;
4830   let Inst{16-12} = opcode;
4831   let Inst{11-10} = 0b10;
4832   let Inst{9-5}   = Rn;
4833   let Inst{4-0}   = Rd;
4834 }
4835
4836 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4837 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4838                                 bits<2> size2, RegisterOperand regtype,
4839                                 string asm, string dstkind, string srckind,
4840                                 list<dag> pattern>
4841   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4842       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4843       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4844     Sched<[WriteV]> {
4845   bits<5> Rd;
4846   bits<5> Rn;
4847   let Inst{31}    = 0;
4848   let Inst{30}    = Q;
4849   let Inst{29}    = U;
4850   let Inst{28-24} = 0b01110;
4851   let Inst{23-22} = size;
4852   let Inst{21} = 0b1;
4853   let Inst{20-19} = size2;
4854   let Inst{18-17} = 0b00;
4855   let Inst{16-12} = opcode;
4856   let Inst{11-10} = 0b10;
4857   let Inst{9-5}   = Rn;
4858   let Inst{4-0}   = Rd;
4859 }
4860
4861 // Supports B, H, and S element sizes.
4862 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4863                             SDPatternOperator OpNode> {
4864   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4865                                       asm, ".8b", ".8b",
4866                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4867   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4868                                       asm, ".16b", ".16b",
4869                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4870   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4871                                       asm, ".4h", ".4h",
4872                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4873   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4874                                       asm, ".8h", ".8h",
4875                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4876   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4877                                       asm, ".2s", ".2s",
4878                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4879   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4880                                       asm, ".4s", ".4s",
4881                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4882 }
4883
4884 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4885                             RegisterOperand regtype, string asm, string dstkind,
4886                             string srckind, string amount>
4887   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4888       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4889       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
4890     Sched<[WriteV]> {
4891   bits<5> Rd;
4892   bits<5> Rn;
4893   let Inst{31}    = 0;
4894   let Inst{30}    = Q;
4895   let Inst{29-24} = 0b101110;
4896   let Inst{23-22} = size;
4897   let Inst{21-10} = 0b100001001110;
4898   let Inst{9-5}   = Rn;
4899   let Inst{4-0}   = Rd;
4900 }
4901
4902 multiclass SIMDVectorLShiftLongBySizeBHS {
4903   let hasSideEffects = 0 in {
4904   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4905                                              "shll", ".8h",  ".8b", "8">;
4906   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4907                                              "shll2", ".8h", ".16b", "8">;
4908   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4909                                              "shll", ".4s",  ".4h", "16">;
4910   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4911                                              "shll2", ".4s", ".8h", "16">;
4912   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4913                                              "shll", ".2d",  ".2s", "32">;
4914   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4915                                              "shll2", ".2d", ".4s", "32">;
4916   }
4917 }
4918
4919 // Supports all element sizes.
4920 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4921                              SDPatternOperator OpNode> {
4922   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4923                                       asm, ".4h", ".8b",
4924                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4925   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4926                                       asm, ".8h", ".16b",
4927                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4928   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4929                                       asm, ".2s", ".4h",
4930                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4931   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4932                                       asm, ".4s", ".8h",
4933                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4934   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4935                                       asm, ".1d", ".2s",
4936                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4937   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4938                                       asm, ".2d", ".4s",
4939                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4940 }
4941
4942 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4943                                  SDPatternOperator OpNode> {
4944   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4945                                           asm, ".4h", ".8b",
4946       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4947                                       (v8i8 V64:$Rn)))]>;
4948   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4949                                           asm, ".8h", ".16b",
4950       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4951                                       (v16i8 V128:$Rn)))]>;
4952   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4953                                           asm, ".2s", ".4h",
4954       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4955                                       (v4i16 V64:$Rn)))]>;
4956   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4957                                           asm, ".4s", ".8h",
4958       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4959                                       (v8i16 V128:$Rn)))]>;
4960   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4961                                           asm, ".1d", ".2s",
4962       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4963                                       (v2i32 V64:$Rn)))]>;
4964   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4965                                           asm, ".2d", ".4s",
4966       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4967                                       (v4i32 V128:$Rn)))]>;
4968 }
4969
4970 // Supports all element sizes, except 1xD.
4971 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4972                                   SDPatternOperator OpNode> {
4973   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4974                                     asm, ".8b", ".8b",
4975     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4976   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4977                                     asm, ".16b", ".16b",
4978     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4979   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4980                                     asm, ".4h", ".4h",
4981     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4982   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4983                                     asm, ".8h", ".8h",
4984     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4985   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4986                                     asm, ".2s", ".2s",
4987     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4988   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4989                                     asm, ".4s", ".4s",
4990     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4991   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
4992                                     asm, ".2d", ".2d",
4993     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4994 }
4995
4996 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4997                              SDPatternOperator OpNode = null_frag> {
4998   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4999                                 asm, ".8b", ".8b",
5000     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5001   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5002                                 asm, ".16b", ".16b",
5003     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5004   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5005                                 asm, ".4h", ".4h",
5006     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5007   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5008                                 asm, ".8h", ".8h",
5009     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5010   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5011                                 asm, ".2s", ".2s",
5012     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5013   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5014                                 asm, ".4s", ".4s",
5015     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5016   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5017                                 asm, ".2d", ".2d",
5018     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5019 }
5020
5021
5022 // Supports only B element sizes.
5023 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5024                           SDPatternOperator OpNode> {
5025   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5026                                 asm, ".8b", ".8b",
5027                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5028   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5029                                 asm, ".16b", ".16b",
5030                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5031
5032 }
5033
5034 // Supports only B and H element sizes.
5035 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5036                                 SDPatternOperator OpNode> {
5037   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5038                                 asm, ".8b", ".8b",
5039                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5040   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5041                                 asm, ".16b", ".16b",
5042                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5043   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5044                                 asm, ".4h", ".4h",
5045                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5046   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5047                                 asm, ".8h", ".8h",
5048                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5049 }
5050
5051 // Supports only S and D element sizes, uses high bit of the size field
5052 // as an extra opcode bit.
5053 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5054                            SDPatternOperator OpNode> {
5055   let Predicates = [HasNEON, HasFullFP16] in {
5056   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5057                                 asm, ".4h", ".4h",
5058                           [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5059   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5060                                 asm, ".8h", ".8h",
5061                           [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5062   } // Predicates = [HasNEON, HasFullFP16]
5063   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5064                                 asm, ".2s", ".2s",
5065                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5066   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5067                                 asm, ".4s", ".4s",
5068                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5069   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5070                                 asm, ".2d", ".2d",
5071                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5072 }
5073
5074 // Supports only S element size.
5075 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5076                            SDPatternOperator OpNode> {
5077   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5078                                 asm, ".2s", ".2s",
5079                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5080   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5081                                 asm, ".4s", ".4s",
5082                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5083 }
5084
5085
5086 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5087                            SDPatternOperator OpNode> {
5088   let Predicates = [HasNEON, HasFullFP16] in {
5089   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5090                                 asm, ".4h", ".4h",
5091                           [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5092   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5093                                 asm, ".8h", ".8h",
5094                           [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5095   } // Predicates = [HasNEON, HasFullFP16]
5096   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5097                                 asm, ".2s", ".2s",
5098                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5099   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5100                                 asm, ".4s", ".4s",
5101                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5102   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5103                                 asm, ".2d", ".2d",
5104                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5105 }
5106
5107 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
5108                            SDPatternOperator OpNode> {
5109   let Predicates = [HasNEON, HasFullFP16] in {
5110   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5111                                 asm, ".4h", ".4h",
5112                           [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5113   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5114                                 asm, ".8h", ".8h",
5115                           [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5116   } // Predicates = [HasNEON, HasFullFP16]
5117   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5118                                 asm, ".2s", ".2s",
5119                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5120   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5121                                 asm, ".4s", ".4s",
5122                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5123   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5124                                 asm, ".2d", ".2d",
5125                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5126 }
5127
5128
5129 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5130                            RegisterOperand inreg, RegisterOperand outreg,
5131                            string asm, string outkind, string inkind,
5132                            list<dag> pattern>
5133   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
5134       "{\t$Rd" # outkind # ", $Rn" # inkind #
5135       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
5136     Sched<[WriteV]> {
5137   bits<5> Rd;
5138   bits<5> Rn;
5139   let Inst{31}    = 0;
5140   let Inst{30}    = Q;
5141   let Inst{29}    = U;
5142   let Inst{28-24} = 0b01110;
5143   let Inst{23-22} = size;
5144   let Inst{21-17} = 0b10000;
5145   let Inst{16-12} = opcode;
5146   let Inst{11-10} = 0b10;
5147   let Inst{9-5}   = Rn;
5148   let Inst{4-0}   = Rd;
5149 }
5150
5151 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5152                            RegisterOperand inreg, RegisterOperand outreg,
5153                            string asm, string outkind, string inkind,
5154                            list<dag> pattern>
5155   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
5156       "{\t$Rd" # outkind # ", $Rn" # inkind #
5157       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5158     Sched<[WriteV]> {
5159   bits<5> Rd;
5160   bits<5> Rn;
5161   let Inst{31}    = 0;
5162   let Inst{30}    = Q;
5163   let Inst{29}    = U;
5164   let Inst{28-24} = 0b01110;
5165   let Inst{23-22} = size;
5166   let Inst{21-17} = 0b10000;
5167   let Inst{16-12} = opcode;
5168   let Inst{11-10} = 0b10;
5169   let Inst{9-5}   = Rn;
5170   let Inst{4-0}   = Rd;
5171 }
5172
5173 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
5174                               SDPatternOperator OpNode> {
5175   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
5176                                       asm, ".8b", ".8h",
5177         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5178   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
5179                                       asm#"2", ".16b", ".8h", []>;
5180   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
5181                                       asm, ".4h", ".4s",
5182         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5183   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
5184                                       asm#"2", ".8h", ".4s", []>;
5185   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
5186                                       asm, ".2s", ".2d",
5187         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5188   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
5189                                       asm#"2", ".4s", ".2d", []>;
5190
5191   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
5192             (!cast<Instruction>(NAME # "v16i8")
5193                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5194   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
5195             (!cast<Instruction>(NAME # "v8i16")
5196                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5197   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
5198             (!cast<Instruction>(NAME # "v4i32")
5199                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5200 }
5201
5202 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
5203                            bits<5> opcode, RegisterOperand regtype, string asm,
5204                            string kind, string zero, ValueType dty,
5205                            ValueType sty, SDNode OpNode>
5206   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5207       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5208       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5209       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5210     Sched<[WriteV]> {
5211   bits<5> Rd;
5212   bits<5> Rn;
5213   let Inst{31}    = 0;
5214   let Inst{30}    = Q;
5215   let Inst{29}    = U;
5216   let Inst{28-24} = 0b01110;
5217   let Inst{23-22} = size;
5218   let Inst{21} = 0b1;
5219   let Inst{20-19} = size2;
5220   let Inst{18-17} = 0b00;
5221   let Inst{16-12} = opcode;
5222   let Inst{11-10} = 0b10;
5223   let Inst{9-5}   = Rn;
5224   let Inst{4-0}   = Rd;
5225 }
5226
5227 // Comparisons support all element sizes, except 1xD.
5228 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5229                             SDNode OpNode> {
5230   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
5231                                      asm, ".8b", "0",
5232                                      v8i8, v8i8, OpNode>;
5233   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
5234                                      asm, ".16b", "0",
5235                                      v16i8, v16i8, OpNode>;
5236   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
5237                                      asm, ".4h", "0",
5238                                      v4i16, v4i16, OpNode>;
5239   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
5240                                      asm, ".8h", "0",
5241                                      v8i16, v8i16, OpNode>;
5242   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
5243                                      asm, ".2s", "0",
5244                                      v2i32, v2i32, OpNode>;
5245   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
5246                                      asm, ".4s", "0",
5247                                      v4i32, v4i32, OpNode>;
5248   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
5249                                      asm, ".2d", "0",
5250                                      v2i64, v2i64, OpNode>;
5251 }
5252
5253 // FP Comparisons support only S and D element sizes (and H for v8.2a).
5254 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5255                               string asm, SDNode OpNode> {
5256
5257   let Predicates = [HasNEON, HasFullFP16] in {
5258   def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5259                                      asm, ".4h", "0.0",
5260                                      v4i16, v4f16, OpNode>;
5261   def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5262                                      asm, ".8h", "0.0",
5263                                      v8i16, v8f16, OpNode>;
5264   } // Predicates = [HasNEON, HasFullFP16]
5265   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
5266                                      asm, ".2s", "0.0",
5267                                      v2i32, v2f32, OpNode>;
5268   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
5269                                      asm, ".4s", "0.0",
5270                                      v4i32, v4f32, OpNode>;
5271   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
5272                                      asm, ".2d", "0.0",
5273                                      v2i64, v2f64, OpNode>;
5274
5275   let Predicates = [HasNEON, HasFullFP16] in {
5276   def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5277                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5278   def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5279                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5280   }
5281   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
5282                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5283   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
5284                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5285   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
5286                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5287   let Predicates = [HasNEON, HasFullFP16] in {
5288   def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5289                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5290   def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5291                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5292   }
5293   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
5294                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5295   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
5296                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5297   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
5298                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5299 }
5300
5301 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5302 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5303                              RegisterOperand outtype, RegisterOperand intype,
5304                              string asm, string VdTy, string VnTy,
5305                              list<dag> pattern>
5306   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5307       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5308     Sched<[WriteV]> {
5309   bits<5> Rd;
5310   bits<5> Rn;
5311   let Inst{31}    = 0;
5312   let Inst{30}    = Q;
5313   let Inst{29}    = U;
5314   let Inst{28-24} = 0b01110;
5315   let Inst{23-22} = size;
5316   let Inst{21-17} = 0b10000;
5317   let Inst{16-12} = opcode;
5318   let Inst{11-10} = 0b10;
5319   let Inst{9-5}   = Rn;
5320   let Inst{4-0}   = Rd;
5321 }
5322
5323 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5324                              RegisterOperand outtype, RegisterOperand intype,
5325                              string asm, string VdTy, string VnTy,
5326                              list<dag> pattern>
5327   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5328       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5329     Sched<[WriteV]> {
5330   bits<5> Rd;
5331   bits<5> Rn;
5332   let Inst{31}    = 0;
5333   let Inst{30}    = Q;
5334   let Inst{29}    = U;
5335   let Inst{28-24} = 0b01110;
5336   let Inst{23-22} = size;
5337   let Inst{21-17} = 0b10000;
5338   let Inst{16-12} = opcode;
5339   let Inst{11-10} = 0b10;
5340   let Inst{9-5}   = Rn;
5341   let Inst{4-0}   = Rd;
5342 }
5343
5344 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5345   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5346                                     asm, ".4s", ".4h", []>;
5347   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5348                                     asm#"2", ".4s", ".8h", []>;
5349   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5350                                     asm, ".2d", ".2s", []>;
5351   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5352                                     asm#"2", ".2d", ".4s", []>;
5353 }
5354
5355 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5356   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5357                                     asm, ".4h", ".4s", []>;
5358   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5359                                     asm#"2", ".8h", ".4s", []>;
5360   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5361                                     asm, ".2s", ".2d", []>;
5362   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5363                                     asm#"2", ".4s", ".2d", []>;
5364 }
5365
5366 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5367                                      Intrinsic OpNode> {
5368   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5369                                      asm, ".2s", ".2d",
5370                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5371   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5372                                     asm#"2", ".4s", ".2d", []>;
5373
5374   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5375             (!cast<Instruction>(NAME # "v4f32")
5376                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5377 }
5378
5379 //----------------------------------------------------------------------------
5380 // AdvSIMD three register different-size vector instructions.
5381 //----------------------------------------------------------------------------
5382
5383 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5384 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5385                       RegisterOperand outtype, RegisterOperand intype1,
5386                       RegisterOperand intype2, string asm,
5387                       string outkind, string inkind1, string inkind2,
5388                       list<dag> pattern>
5389   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5390       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5391       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5392     Sched<[WriteV]> {
5393   bits<5> Rd;
5394   bits<5> Rn;
5395   bits<5> Rm;
5396   let Inst{31}    = 0;
5397   let Inst{30}    = size{0};
5398   let Inst{29}    = U;
5399   let Inst{28-24} = 0b01110;
5400   let Inst{23-22} = size{2-1};
5401   let Inst{21}    = 1;
5402   let Inst{20-16} = Rm;
5403   let Inst{15-12} = opcode;
5404   let Inst{11-10} = 0b00;
5405   let Inst{9-5}   = Rn;
5406   let Inst{4-0}   = Rd;
5407 }
5408
5409 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5410 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5411                       RegisterOperand outtype, RegisterOperand intype1,
5412                       RegisterOperand intype2, string asm,
5413                       string outkind, string inkind1, string inkind2,
5414                       list<dag> pattern>
5415   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5416       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5417       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5418     Sched<[WriteV]> {
5419   bits<5> Rd;
5420   bits<5> Rn;
5421   bits<5> Rm;
5422   let Inst{31}    = 0;
5423   let Inst{30}    = size{0};
5424   let Inst{29}    = U;
5425   let Inst{28-24} = 0b01110;
5426   let Inst{23-22} = size{2-1};
5427   let Inst{21}    = 1;
5428   let Inst{20-16} = Rm;
5429   let Inst{15-12} = opcode;
5430   let Inst{11-10} = 0b00;
5431   let Inst{9-5}   = Rn;
5432   let Inst{4-0}   = Rd;
5433 }
5434
5435 // FIXME: TableGen doesn't know how to deal with expanded types that also
5436 //        change the element count (in this case, placing the results in
5437 //        the high elements of the result register rather than the low
5438 //        elements). Until that's fixed, we can't code-gen those.
5439 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5440                                     Intrinsic IntOp> {
5441   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5442                                                   V64, V128, V128,
5443                                                   asm, ".8b", ".8h", ".8h",
5444      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5445   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5446                                                   V128, V128, V128,
5447                                                   asm#"2", ".16b", ".8h", ".8h",
5448      []>;
5449   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5450                                                   V64, V128, V128,
5451                                                   asm, ".4h", ".4s", ".4s",
5452      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5453   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5454                                                   V128, V128, V128,
5455                                                   asm#"2", ".8h", ".4s", ".4s",
5456      []>;
5457   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5458                                                   V64, V128, V128,
5459                                                   asm, ".2s", ".2d", ".2d",
5460      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5461   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5462                                                   V128, V128, V128,
5463                                                   asm#"2", ".4s", ".2d", ".2d",
5464      []>;
5465
5466
5467   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5468   // a version attached to an instruction.
5469   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5470                                                    (v8i16 V128:$Rm))),
5471             (!cast<Instruction>(NAME # "v8i16_v16i8")
5472                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5473                 V128:$Rn, V128:$Rm)>;
5474   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5475                                                     (v4i32 V128:$Rm))),
5476             (!cast<Instruction>(NAME # "v4i32_v8i16")
5477                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5478                 V128:$Rn, V128:$Rm)>;
5479   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5480                                                     (v2i64 V128:$Rm))),
5481             (!cast<Instruction>(NAME # "v2i64_v4i32")
5482                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5483                 V128:$Rn, V128:$Rm)>;
5484 }
5485
5486 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5487                                       Intrinsic IntOp> {
5488   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5489                                             V128, V64, V64,
5490                                             asm, ".8h", ".8b", ".8b",
5491       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5492   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5493                                             V128, V128, V128,
5494                                             asm#"2", ".8h", ".16b", ".16b", []>;
5495   let Predicates = [HasCrypto] in {
5496     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5497                                               V128, V64, V64,
5498                                               asm, ".1q", ".1d", ".1d", []>;
5499     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5500                                               V128, V128, V128,
5501                                               asm#"2", ".1q", ".2d", ".2d", []>;
5502   }
5503
5504   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5505                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
5506       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5507 }
5508
5509 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5510                                  SDPatternOperator OpNode> {
5511   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5512                                                   V128, V64, V64,
5513                                                   asm, ".4s", ".4h", ".4h",
5514       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5515   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5516                                                   V128, V128, V128,
5517                                                   asm#"2", ".4s", ".8h", ".8h",
5518       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5519                                       (extract_high_v8i16 V128:$Rm)))]>;
5520   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5521                                                   V128, V64, V64,
5522                                                   asm, ".2d", ".2s", ".2s",
5523       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5524   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5525                                                   V128, V128, V128,
5526                                                   asm#"2", ".2d", ".4s", ".4s",
5527       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5528                                       (extract_high_v4i32 V128:$Rm)))]>;
5529 }
5530
5531 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5532                                   SDPatternOperator OpNode = null_frag> {
5533   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5534                                                   V128, V64, V64,
5535                                                   asm, ".8h", ".8b", ".8b",
5536       [(set (v8i16 V128:$Rd),
5537             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5538   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5539                                                  V128, V128, V128,
5540                                                  asm#"2", ".8h", ".16b", ".16b",
5541       [(set (v8i16 V128:$Rd),
5542             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5543                                 (extract_high_v16i8 V128:$Rm)))))]>;
5544   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5545                                                   V128, V64, V64,
5546                                                   asm, ".4s", ".4h", ".4h",
5547       [(set (v4i32 V128:$Rd),
5548             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5549   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5550                                                   V128, V128, V128,
5551                                                   asm#"2", ".4s", ".8h", ".8h",
5552       [(set (v4i32 V128:$Rd),
5553             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5554                                   (extract_high_v8i16 V128:$Rm)))))]>;
5555   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5556                                                   V128, V64, V64,
5557                                                   asm, ".2d", ".2s", ".2s",
5558       [(set (v2i64 V128:$Rd),
5559             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5560   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5561                                                   V128, V128, V128,
5562                                                   asm#"2", ".2d", ".4s", ".4s",
5563       [(set (v2i64 V128:$Rd),
5564             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5565                                  (extract_high_v4i32 V128:$Rm)))))]>;
5566 }
5567
5568 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5569                                           string asm,
5570                                           SDPatternOperator OpNode> {
5571   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5572                                                   V128, V64, V64,
5573                                                   asm, ".8h", ".8b", ".8b",
5574     [(set (v8i16 V128:$dst),
5575           (add (v8i16 V128:$Rd),
5576                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5577   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5578                                                  V128, V128, V128,
5579                                                  asm#"2", ".8h", ".16b", ".16b",
5580     [(set (v8i16 V128:$dst),
5581           (add (v8i16 V128:$Rd),
5582                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5583                                    (extract_high_v16i8 V128:$Rm))))))]>;
5584   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5585                                                   V128, V64, V64,
5586                                                   asm, ".4s", ".4h", ".4h",
5587     [(set (v4i32 V128:$dst),
5588           (add (v4i32 V128:$Rd),
5589                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5590   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5591                                                   V128, V128, V128,
5592                                                   asm#"2", ".4s", ".8h", ".8h",
5593     [(set (v4i32 V128:$dst),
5594           (add (v4i32 V128:$Rd),
5595                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5596                                     (extract_high_v8i16 V128:$Rm))))))]>;
5597   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5598                                                   V128, V64, V64,
5599                                                   asm, ".2d", ".2s", ".2s",
5600     [(set (v2i64 V128:$dst),
5601           (add (v2i64 V128:$Rd),
5602                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5603   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5604                                                   V128, V128, V128,
5605                                                   asm#"2", ".2d", ".4s", ".4s",
5606     [(set (v2i64 V128:$dst),
5607           (add (v2i64 V128:$Rd),
5608                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5609                                     (extract_high_v4i32 V128:$Rm))))))]>;
5610 }
5611
5612 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5613                                   SDPatternOperator OpNode = null_frag> {
5614   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5615                                                   V128, V64, V64,
5616                                                   asm, ".8h", ".8b", ".8b",
5617       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5618   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5619                                                  V128, V128, V128,
5620                                                  asm#"2", ".8h", ".16b", ".16b",
5621       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5622                                       (extract_high_v16i8 V128:$Rm)))]>;
5623   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5624                                                   V128, V64, V64,
5625                                                   asm, ".4s", ".4h", ".4h",
5626       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5627   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5628                                                   V128, V128, V128,
5629                                                   asm#"2", ".4s", ".8h", ".8h",
5630       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5631                                       (extract_high_v8i16 V128:$Rm)))]>;
5632   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5633                                                   V128, V64, V64,
5634                                                   asm, ".2d", ".2s", ".2s",
5635       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5636   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5637                                                   V128, V128, V128,
5638                                                   asm#"2", ".2d", ".4s", ".4s",
5639       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5640                                       (extract_high_v4i32 V128:$Rm)))]>;
5641 }
5642
5643 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5644                                       string asm,
5645                                       SDPatternOperator OpNode> {
5646   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5647                                                   V128, V64, V64,
5648                                                   asm, ".8h", ".8b", ".8b",
5649     [(set (v8i16 V128:$dst),
5650           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5651   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5652                                                  V128, V128, V128,
5653                                                  asm#"2", ".8h", ".16b", ".16b",
5654     [(set (v8i16 V128:$dst),
5655           (OpNode (v8i16 V128:$Rd),
5656                   (extract_high_v16i8 V128:$Rn),
5657                   (extract_high_v16i8 V128:$Rm)))]>;
5658   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5659                                                   V128, V64, V64,
5660                                                   asm, ".4s", ".4h", ".4h",
5661     [(set (v4i32 V128:$dst),
5662           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5663   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5664                                                   V128, V128, V128,
5665                                                   asm#"2", ".4s", ".8h", ".8h",
5666     [(set (v4i32 V128:$dst),
5667           (OpNode (v4i32 V128:$Rd),
5668                   (extract_high_v8i16 V128:$Rn),
5669                   (extract_high_v8i16 V128:$Rm)))]>;
5670   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5671                                                   V128, V64, V64,
5672                                                   asm, ".2d", ".2s", ".2s",
5673     [(set (v2i64 V128:$dst),
5674           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5675   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5676                                                   V128, V128, V128,
5677                                                   asm#"2", ".2d", ".4s", ".4s",
5678     [(set (v2i64 V128:$dst),
5679           (OpNode (v2i64 V128:$Rd),
5680                   (extract_high_v4i32 V128:$Rn),
5681                   (extract_high_v4i32 V128:$Rm)))]>;
5682 }
5683
5684 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5685                                            SDPatternOperator Accum> {
5686   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5687                                                   V128, V64, V64,
5688                                                   asm, ".4s", ".4h", ".4h",
5689     [(set (v4i32 V128:$dst),
5690           (Accum (v4i32 V128:$Rd),
5691                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5692                                                 (v4i16 V64:$Rm)))))]>;
5693   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5694                                                   V128, V128, V128,
5695                                                   asm#"2", ".4s", ".8h", ".8h",
5696     [(set (v4i32 V128:$dst),
5697           (Accum (v4i32 V128:$Rd),
5698                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5699                                             (extract_high_v8i16 V128:$Rm)))))]>;
5700   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5701                                                   V128, V64, V64,
5702                                                   asm, ".2d", ".2s", ".2s",
5703     [(set (v2i64 V128:$dst),
5704           (Accum (v2i64 V128:$Rd),
5705                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5706                                                 (v2i32 V64:$Rm)))))]>;
5707   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5708                                                   V128, V128, V128,
5709                                                   asm#"2", ".2d", ".4s", ".4s",
5710     [(set (v2i64 V128:$dst),
5711           (Accum (v2i64 V128:$Rd),
5712                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5713                                             (extract_high_v4i32 V128:$Rm)))))]>;
5714 }
5715
5716 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5717                                   SDPatternOperator OpNode> {
5718   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5719                                                   V128, V128, V64,
5720                                                   asm, ".8h", ".8h", ".8b",
5721        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5722   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5723                                                   V128, V128, V128,
5724                                                   asm#"2", ".8h", ".8h", ".16b",
5725        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5726                                        (extract_high_v16i8 V128:$Rm)))]>;
5727   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5728                                                   V128, V128, V64,
5729                                                   asm, ".4s", ".4s", ".4h",
5730        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5731   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5732                                                   V128, V128, V128,
5733                                                   asm#"2", ".4s", ".4s", ".8h",
5734        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5735                                        (extract_high_v8i16 V128:$Rm)))]>;
5736   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5737                                                   V128, V128, V64,
5738                                                   asm, ".2d", ".2d", ".2s",
5739        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5740   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5741                                                   V128, V128, V128,
5742                                                   asm#"2", ".2d", ".2d", ".4s",
5743        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5744                                        (extract_high_v4i32 V128:$Rm)))]>;
5745 }
5746
5747 //----------------------------------------------------------------------------
5748 // AdvSIMD bitwise extract from vector
5749 //----------------------------------------------------------------------------
5750
5751 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5752                              string asm, string kind>
5753   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5754       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5755       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5756       [(set (vty regtype:$Rd),
5757             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5758     Sched<[WriteV]> {
5759   bits<5> Rd;
5760   bits<5> Rn;
5761   bits<5> Rm;
5762   bits<4> imm;
5763   let Inst{31}    = 0;
5764   let Inst{30}    = size;
5765   let Inst{29-21} = 0b101110000;
5766   let Inst{20-16} = Rm;
5767   let Inst{15}    = 0;
5768   let Inst{14-11} = imm;
5769   let Inst{10}    = 0;
5770   let Inst{9-5}   = Rn;
5771   let Inst{4-0}   = Rd;
5772 }
5773
5774
5775 multiclass SIMDBitwiseExtract<string asm> {
5776   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5777     let imm{3} = 0;
5778   }
5779   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5780 }
5781
5782 //----------------------------------------------------------------------------
5783 // AdvSIMD zip vector
5784 //----------------------------------------------------------------------------
5785
5786 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5787                         string asm, string kind, SDNode OpNode, ValueType valty>
5788   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5789       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5790       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5791       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5792     Sched<[WriteV]> {
5793   bits<5> Rd;
5794   bits<5> Rn;
5795   bits<5> Rm;
5796   let Inst{31}    = 0;
5797   let Inst{30}    = size{0};
5798   let Inst{29-24} = 0b001110;
5799   let Inst{23-22} = size{2-1};
5800   let Inst{21}    = 0;
5801   let Inst{20-16} = Rm;
5802   let Inst{15}    = 0;
5803   let Inst{14-12} = opc;
5804   let Inst{11-10} = 0b10;
5805   let Inst{9-5}   = Rn;
5806   let Inst{4-0}   = Rd;
5807 }
5808
5809 multiclass SIMDZipVector<bits<3>opc, string asm,
5810                          SDNode OpNode> {
5811   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
5812       asm, ".8b", OpNode, v8i8>;
5813   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
5814       asm, ".16b", OpNode, v16i8>;
5815   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
5816       asm, ".4h", OpNode, v4i16>;
5817   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
5818       asm, ".8h", OpNode, v8i16>;
5819   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
5820       asm, ".2s", OpNode, v2i32>;
5821   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
5822       asm, ".4s", OpNode, v4i32>;
5823   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
5824       asm, ".2d", OpNode, v2i64>;
5825
5826   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5827         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5828   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5829         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
5830   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5831         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5832   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5833         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5834   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5835         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5836 }
5837
5838 //----------------------------------------------------------------------------
5839 // AdvSIMD three register scalar instructions
5840 //----------------------------------------------------------------------------
5841
5842 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5843 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
5844                         RegisterClass regtype, string asm,
5845                         list<dag> pattern>
5846   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5847       "\t$Rd, $Rn, $Rm", "", pattern>,
5848     Sched<[WriteV]> {
5849   bits<5> Rd;
5850   bits<5> Rn;
5851   bits<5> Rm;
5852   let Inst{31-30} = 0b01;
5853   let Inst{29}    = U;
5854   let Inst{28-24} = 0b11110;
5855   let Inst{23-21} = size;
5856   let Inst{20-16} = Rm;
5857   let Inst{15-11} = opcode;
5858   let Inst{10}    = 1;
5859   let Inst{9-5}   = Rn;
5860   let Inst{4-0}   = Rd;
5861 }
5862
5863 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5864 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5865                         dag oops, dag iops, string asm,
5866             list<dag> pattern>
5867   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5868     Sched<[WriteV]> {
5869   bits<5> Rd;
5870   bits<5> Rn;
5871   bits<5> Rm;
5872   let Inst{31-30} = 0b01;
5873   let Inst{29}    = U;
5874   let Inst{28-24} = 0b11110;
5875   let Inst{23-22} = size;
5876   let Inst{21}    = R;
5877   let Inst{20-16} = Rm;
5878   let Inst{15-11} = opcode;
5879   let Inst{10}    = 1;
5880   let Inst{9-5}   = Rn;
5881   let Inst{4-0}   = Rd;
5882 }
5883
5884 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5885                             SDPatternOperator OpNode> {
5886   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5887     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5888 }
5889
5890 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5891                                SDPatternOperator OpNode> {
5892   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5893     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5894   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
5895   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5896   def v1i8   : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
5897
5898   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5899             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5900   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5901             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5902 }
5903
5904 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5905                              SDPatternOperator OpNode> {
5906   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
5907                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5908   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5909 }
5910
5911 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5912                                  SDPatternOperator OpNode = null_frag> {
5913   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5914                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 
5915                                      asm, []>;
5916   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5917                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 
5918                                      asm, []>;
5919 }
5920
5921 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
5922                              SDPatternOperator OpNode = null_frag> {
5923   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5924     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5925       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5926     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5927       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5928     let Predicates = [HasNEON, HasFullFP16] in {
5929     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5930       [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
5931     } // Predicates = [HasNEON, HasFullFP16]
5932   }
5933
5934   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5935             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5936 }
5937
5938 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
5939                                 SDPatternOperator OpNode = null_frag> {
5940   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5941     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5942       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5943     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5944       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5945     let Predicates = [HasNEON, HasFullFP16] in {
5946     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5947       []>;
5948     } // Predicates = [HasNEON, HasFullFP16]
5949   }
5950
5951   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5952             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5953 }
5954
5955 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5956               dag oops, dag iops, string asm, string cstr, list<dag> pat>
5957   : I<oops, iops, asm,
5958       "\t$Rd, $Rn, $Rm", cstr, pat>,
5959     Sched<[WriteV]> {
5960   bits<5> Rd;
5961   bits<5> Rn;
5962   bits<5> Rm;
5963   let Inst{31-30} = 0b01;
5964   let Inst{29}    = U;
5965   let Inst{28-24} = 0b11110;
5966   let Inst{23-22} = size;
5967   let Inst{21}    = 1;
5968   let Inst{20-16} = Rm;
5969   let Inst{15-11} = opcode;
5970   let Inst{10}    = 0;
5971   let Inst{9-5}   = Rn;
5972   let Inst{4-0}   = Rd;
5973 }
5974
5975 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5976 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5977                                   SDPatternOperator OpNode = null_frag> {
5978   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5979                                       (outs FPR32:$Rd),
5980                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5981   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5982                                       (outs FPR64:$Rd),
5983                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5984             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5985 }
5986
5987 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5988 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5989                                   SDPatternOperator OpNode = null_frag> {
5990   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5991                                       (outs FPR32:$dst),
5992                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5993                                       asm, "$Rd = $dst", []>;
5994   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5995                                       (outs FPR64:$dst),
5996                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5997                                       asm, "$Rd = $dst",
5998             [(set (i64 FPR64:$dst),
5999                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6000 }
6001
6002 //----------------------------------------------------------------------------
6003 // AdvSIMD two register scalar instructions
6004 //----------------------------------------------------------------------------
6005
6006 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6007 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6008                         RegisterClass regtype, RegisterClass regtype2,
6009                         string asm, list<dag> pat>
6010   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6011       "\t$Rd, $Rn", "", pat>,
6012     Sched<[WriteV]> {
6013   bits<5> Rd;
6014   bits<5> Rn;
6015   let Inst{31-30} = 0b01;
6016   let Inst{29}    = U;
6017   let Inst{28-24} = 0b11110;
6018   let Inst{23-22} = size;
6019   let Inst{21} = 0b1;
6020   let Inst{20-19} = size2;
6021   let Inst{18-17} = 0b00;
6022   let Inst{16-12} = opcode;
6023   let Inst{11-10} = 0b10;
6024   let Inst{9-5}   = Rn;
6025   let Inst{4-0}   = Rd;
6026 }
6027
6028 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6029 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6030                         RegisterClass regtype, RegisterClass regtype2,
6031                         string asm, list<dag> pat>
6032   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6033       "\t$Rd, $Rn", "$Rd = $dst", pat>,
6034     Sched<[WriteV]> {
6035   bits<5> Rd;
6036   bits<5> Rn;
6037   let Inst{31-30} = 0b01;
6038   let Inst{29}    = U;
6039   let Inst{28-24} = 0b11110;
6040   let Inst{23-22} = size;
6041   let Inst{21-17} = 0b10000;
6042   let Inst{16-12} = opcode;
6043   let Inst{11-10} = 0b10;
6044   let Inst{9-5}   = Rn;
6045   let Inst{4-0}   = Rd;
6046 }
6047
6048
6049 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6050 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6051                         RegisterClass regtype, string asm, string zero>
6052   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6053       "\t$Rd, $Rn, #" # zero, "", []>,
6054     Sched<[WriteV]> {
6055   bits<5> Rd;
6056   bits<5> Rn;
6057   let Inst{31-30} = 0b01;
6058   let Inst{29}    = U;
6059   let Inst{28-24} = 0b11110;
6060   let Inst{23-22} = size;
6061   let Inst{21} = 0b1;
6062   let Inst{20-19} = size2;
6063   let Inst{18-17} = 0b00;
6064   let Inst{16-12} = opcode;
6065   let Inst{11-10} = 0b10;
6066   let Inst{9-5}   = Rn;
6067   let Inst{4-0}   = Rd;
6068 }
6069
6070 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6071   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6072      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6073     Sched<[WriteV]> {
6074   bits<5> Rd;
6075   bits<5> Rn;
6076   let Inst{31-17} = 0b011111100110000;
6077   let Inst{16-12} = opcode;
6078   let Inst{11-10} = 0b10;
6079   let Inst{9-5}   = Rn;
6080   let Inst{4-0}   = Rd;
6081 }
6082
6083 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6084                              SDPatternOperator OpNode> {
6085   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6086
6087   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6088             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6089 }
6090
6091 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6092                               SDPatternOperator OpNode> {
6093   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
6094   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
6095   let Predicates = [HasNEON, HasFullFP16] in {
6096   def v1i16rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
6097   }
6098
6099   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6100                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
6101   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6102                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
6103   let Predicates = [HasNEON, HasFullFP16] in {
6104   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6105                   (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
6106   }
6107
6108   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
6109             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6110 }
6111
6112 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
6113                           SDPatternOperator OpNode = null_frag> {
6114   def v1i64       : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6115     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
6116
6117   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
6118             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
6119 }
6120
6121 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
6122   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
6123   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
6124   let Predicates = [HasNEON, HasFullFP16] in {
6125   def v1f16       : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
6126   }
6127 }
6128
6129 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
6130                               SDPatternOperator OpNode> {
6131   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
6132                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
6133   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
6134                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
6135   let Predicates = [HasNEON, HasFullFP16] in {
6136   def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
6137                                 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
6138   }
6139 }
6140
6141 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
6142                              SDPatternOperator OpNode = null_frag> {
6143   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6144     def v1i64  : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6145            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6146     def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
6147            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
6148     def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
6149     def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
6150   }
6151
6152   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
6153             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
6154 }
6155
6156 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
6157                                  Intrinsic OpNode> {
6158   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6159     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
6160         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
6161     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
6162         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
6163     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
6164     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
6165   }
6166
6167   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
6168             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
6169 }
6170
6171
6172
6173 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6174 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
6175                                  SDPatternOperator OpNode = null_frag> {
6176   def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
6177         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6178   def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
6179   def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
6180 }
6181
6182 //----------------------------------------------------------------------------
6183 // AdvSIMD scalar pairwise instructions
6184 //----------------------------------------------------------------------------
6185
6186 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6187 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
6188                         RegisterOperand regtype, RegisterOperand vectype,
6189                         string asm, string kind>
6190   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6191       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
6192     Sched<[WriteV]> {
6193   bits<5> Rd;
6194   bits<5> Rn;
6195   let Inst{31-30} = 0b01;
6196   let Inst{29}    = U;
6197   let Inst{28-24} = 0b11110;
6198   let Inst{23-22} = size;
6199   let Inst{21-17} = 0b11000;
6200   let Inst{16-12} = opcode;
6201   let Inst{11-10} = 0b10;
6202   let Inst{9-5}   = Rn;
6203   let Inst{4-0}   = Rd;
6204 }
6205
6206 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6207   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6208                                       asm, ".2d">;
6209 }
6210
6211 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6212   let Predicates = [HasNEON, HasFullFP16] in {
6213   def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6214                                       asm, ".2h">;
6215   }
6216   def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
6217                                       asm, ".2s">;
6218   def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
6219                                       asm, ".2d">;
6220 }
6221
6222 //----------------------------------------------------------------------------
6223 // AdvSIMD across lanes instructions
6224 //----------------------------------------------------------------------------
6225
6226 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6227 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6228                           RegisterClass regtype, RegisterOperand vectype,
6229                           string asm, string kind, list<dag> pattern>
6230   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6231       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6232     Sched<[WriteV]> {
6233   bits<5> Rd;
6234   bits<5> Rn;
6235   let Inst{31}    = 0;
6236   let Inst{30}    = Q;
6237   let Inst{29}    = U;
6238   let Inst{28-24} = 0b01110;
6239   let Inst{23-22} = size;
6240   let Inst{21-17} = 0b11000;
6241   let Inst{16-12} = opcode;
6242   let Inst{11-10} = 0b10;
6243   let Inst{9-5}   = Rn;
6244   let Inst{4-0}   = Rd;
6245 }
6246
6247 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6248                               string asm> {
6249   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
6250                                    asm, ".8b", []>;
6251   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
6252                                    asm, ".16b", []>;
6253   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6254                                    asm, ".4h", []>;
6255   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6256                                    asm, ".8h", []>;
6257   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6258                                    asm, ".4s", []>;
6259 }
6260
6261 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6262   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6263                                    asm, ".8b", []>;
6264   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6265                                    asm, ".16b", []>;
6266   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6267                                    asm, ".4h", []>;
6268   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6269                                    asm, ".8h", []>;
6270   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6271                                    asm, ".4s", []>;
6272 }
6273
6274 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
6275                             Intrinsic intOp> {
6276   let Predicates = [HasNEON, HasFullFP16] in {
6277   def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6278                                    asm, ".4h",
6279         [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6280   def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6281                                    asm, ".8h",
6282         [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6283   } // Predicates = [HasNEON, HasFullFP16]
6284   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6285                                    asm, ".4s",
6286         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6287 }
6288
6289 //----------------------------------------------------------------------------
6290 // AdvSIMD INS/DUP instructions
6291 //----------------------------------------------------------------------------
6292
6293 // FIXME: There has got to be a better way to factor these. ugh.
6294
6295 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6296                      string operands, string constraints, list<dag> pattern>
6297   : I<outs, ins, asm, operands, constraints, pattern>,
6298     Sched<[WriteV]> {
6299   bits<5> Rd;
6300   bits<5> Rn;
6301   let Inst{31} = 0;
6302   let Inst{30} = Q;
6303   let Inst{29} = op;
6304   let Inst{28-21} = 0b01110000;
6305   let Inst{15} = 0;
6306   let Inst{10} = 1;
6307   let Inst{9-5} = Rn;
6308   let Inst{4-0} = Rd;
6309 }
6310
6311 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6312                       RegisterOperand vecreg, RegisterClass regtype>
6313   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6314                    "{\t$Rd" # size # ", $Rn" #
6315                    "|" # size # "\t$Rd, $Rn}", "",
6316                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6317   let Inst{20-16} = imm5;
6318   let Inst{14-11} = 0b0001;
6319 }
6320
6321 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6322                          ValueType vectype, ValueType insreg,
6323                          RegisterOperand vecreg, Operand idxtype,
6324                          ValueType elttype, SDNode OpNode>
6325   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6326                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6327                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6328                  [(set (vectype vecreg:$Rd),
6329                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6330   let Inst{14-11} = 0b0000;
6331 }
6332
6333 class SIMDDup64FromElement
6334   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6335                        VectorIndexD, i64, AArch64duplane64> {
6336   bits<1> idx;
6337   let Inst{20} = idx;
6338   let Inst{19-16} = 0b1000;
6339 }
6340
6341 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6342                            RegisterOperand vecreg>
6343   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6344                        VectorIndexS, i64, AArch64duplane32> {
6345   bits<2> idx;
6346   let Inst{20-19} = idx;
6347   let Inst{18-16} = 0b100;
6348 }
6349
6350 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6351                            RegisterOperand vecreg>
6352   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6353                        VectorIndexH, i64, AArch64duplane16> {
6354   bits<3> idx;
6355   let Inst{20-18} = idx;
6356   let Inst{17-16} = 0b10;
6357 }
6358
6359 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6360                           RegisterOperand vecreg>
6361   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6362                        VectorIndexB, i64, AArch64duplane8> {
6363   bits<4> idx;
6364   let Inst{20-17} = idx;
6365   let Inst{16} = 1;
6366 }
6367
6368 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6369                   Operand idxtype, string asm, list<dag> pattern>
6370   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6371                    "{\t$Rd, $Rn" # size # "$idx" #
6372                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6373   let Inst{14-11} = imm4;
6374 }
6375
6376 class SIMDSMov<bit Q, string size, RegisterClass regtype,
6377                Operand idxtype>
6378   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6379 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6380                Operand idxtype>
6381   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6382       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6383
6384 class SIMDMovAlias<string asm, string size, Instruction inst,
6385                    RegisterClass regtype, Operand idxtype>
6386     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6387                     "|" # size # "\t$dst, $src$idx}",
6388                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6389
6390 multiclass SMov {
6391   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6392     bits<4> idx;
6393     let Inst{20-17} = idx;
6394     let Inst{16} = 1;
6395   }
6396   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6397     bits<4> idx;
6398     let Inst{20-17} = idx;
6399     let Inst{16} = 1;
6400   }
6401   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6402     bits<3> idx;
6403     let Inst{20-18} = idx;
6404     let Inst{17-16} = 0b10;
6405   }
6406   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6407     bits<3> idx;
6408     let Inst{20-18} = idx;
6409     let Inst{17-16} = 0b10;
6410   }
6411   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6412     bits<2> idx;
6413     let Inst{20-19} = idx;
6414     let Inst{18-16} = 0b100;
6415   }
6416 }
6417
6418 multiclass UMov {
6419   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6420     bits<4> idx;
6421     let Inst{20-17} = idx;
6422     let Inst{16} = 1;
6423   }
6424   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6425     bits<3> idx;
6426     let Inst{20-18} = idx;
6427     let Inst{17-16} = 0b10;
6428   }
6429   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6430     bits<2> idx;
6431     let Inst{20-19} = idx;
6432     let Inst{18-16} = 0b100;
6433   }
6434   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6435     bits<1> idx;
6436     let Inst{20} = idx;
6437     let Inst{19-16} = 0b1000;
6438   }
6439   def : SIMDMovAlias<"mov", ".s",
6440                      !cast<Instruction>(NAME#"vi32"),
6441                      GPR32, VectorIndexS>;
6442   def : SIMDMovAlias<"mov", ".d",
6443                      !cast<Instruction>(NAME#"vi64"),
6444                      GPR64, VectorIndexD>;
6445 }
6446
6447 class SIMDInsFromMain<string size, ValueType vectype,
6448                       RegisterClass regtype, Operand idxtype>
6449   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6450                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6451                    "{\t$Rd" # size # "$idx, $Rn" #
6452                    "|" # size # "\t$Rd$idx, $Rn}",
6453                    "$Rd = $dst",
6454             [(set V128:$dst,
6455               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6456   let Inst{14-11} = 0b0011;
6457 }
6458
6459 class SIMDInsFromElement<string size, ValueType vectype,
6460                          ValueType elttype, Operand idxtype>
6461   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6462                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6463                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6464                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
6465                    "$Rd = $dst",
6466          [(set V128:$dst,
6467                (vector_insert
6468                  (vectype V128:$Rd),
6469                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6470                  idxtype:$idx))]>;
6471
6472 class SIMDInsMainMovAlias<string size, Instruction inst,
6473                           RegisterClass regtype, Operand idxtype>
6474     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6475                         "|" # size #"\t$dst$idx, $src}",
6476                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6477 class SIMDInsElementMovAlias<string size, Instruction inst,
6478                              Operand idxtype>
6479     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
6480                       # "|" # size #"\t$dst$idx, $src$idx2}",
6481                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6482
6483
6484 multiclass SIMDIns {
6485   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6486     bits<4> idx;
6487     let Inst{20-17} = idx;
6488     let Inst{16} = 1;
6489   }
6490   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6491     bits<3> idx;
6492     let Inst{20-18} = idx;
6493     let Inst{17-16} = 0b10;
6494   }
6495   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6496     bits<2> idx;
6497     let Inst{20-19} = idx;
6498     let Inst{18-16} = 0b100;
6499   }
6500   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6501     bits<1> idx;
6502     let Inst{20} = idx;
6503     let Inst{19-16} = 0b1000;
6504   }
6505
6506   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6507     bits<4> idx;
6508     bits<4> idx2;
6509     let Inst{20-17} = idx;
6510     let Inst{16} = 1;
6511     let Inst{14-11} = idx2;
6512   }
6513   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6514     bits<3> idx;
6515     bits<3> idx2;
6516     let Inst{20-18} = idx;
6517     let Inst{17-16} = 0b10;
6518     let Inst{14-12} = idx2;
6519     let Inst{11} = {?};
6520   }
6521   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6522     bits<2> idx;
6523     bits<2> idx2;
6524     let Inst{20-19} = idx;
6525     let Inst{18-16} = 0b100;
6526     let Inst{14-13} = idx2;
6527     let Inst{12-11} = {?,?};
6528   }
6529   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6530     bits<1> idx;
6531     bits<1> idx2;
6532     let Inst{20} = idx;
6533     let Inst{19-16} = 0b1000;
6534     let Inst{14} = idx2;
6535     let Inst{13-11} = {?,?,?};
6536   }
6537
6538   // For all forms of the INS instruction, the "mov" mnemonic is the
6539   // preferred alias. Why they didn't just call the instruction "mov" in
6540   // the first place is a very good question indeed...
6541   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6542                          GPR32, VectorIndexB>;
6543   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6544                          GPR32, VectorIndexH>;
6545   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6546                          GPR32, VectorIndexS>;
6547   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6548                          GPR64, VectorIndexD>;
6549
6550   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6551                          VectorIndexB>;
6552   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6553                          VectorIndexH>;
6554   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6555                          VectorIndexS>;
6556   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6557                          VectorIndexD>;
6558 }
6559
6560 //----------------------------------------------------------------------------
6561 // AdvSIMD TBL/TBX
6562 //----------------------------------------------------------------------------
6563
6564 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6565 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6566                           RegisterOperand listtype, string asm, string kind>
6567   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6568        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6569     Sched<[WriteV]> {
6570   bits<5> Vd;
6571   bits<5> Vn;
6572   bits<5> Vm;
6573   let Inst{31}    = 0;
6574   let Inst{30}    = Q;
6575   let Inst{29-21} = 0b001110000;
6576   let Inst{20-16} = Vm;
6577   let Inst{15}    = 0;
6578   let Inst{14-13} = len;
6579   let Inst{12}    = op;
6580   let Inst{11-10} = 0b00;
6581   let Inst{9-5}   = Vn;
6582   let Inst{4-0}   = Vd;
6583 }
6584
6585 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6586 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6587                           RegisterOperand listtype, string asm, string kind>
6588   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6589        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6590     Sched<[WriteV]> {
6591   bits<5> Vd;
6592   bits<5> Vn;
6593   bits<5> Vm;
6594   let Inst{31}    = 0;
6595   let Inst{30}    = Q;
6596   let Inst{29-21} = 0b001110000;
6597   let Inst{20-16} = Vm;
6598   let Inst{15}    = 0;
6599   let Inst{14-13} = len;
6600   let Inst{12}    = op;
6601   let Inst{11-10} = 0b00;
6602   let Inst{9-5}   = Vn;
6603   let Inst{4-0}   = Vd;
6604 }
6605
6606 class SIMDTableLookupAlias<string asm, Instruction inst,
6607                           RegisterOperand vectype, RegisterOperand listtype>
6608     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6609                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6610
6611 multiclass SIMDTableLookup<bit op, string asm> {
6612   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6613                                       asm, ".8b">;
6614   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6615                                       asm, ".8b">;
6616   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6617                                       asm, ".8b">;
6618   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6619                                       asm, ".8b">;
6620   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6621                                       asm, ".16b">;
6622   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6623                                       asm, ".16b">;
6624   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6625                                       asm, ".16b">;
6626   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6627                                       asm, ".16b">;
6628
6629   def : SIMDTableLookupAlias<asm # ".8b",
6630                          !cast<Instruction>(NAME#"v8i8One"),
6631                          V64, VecListOne128>;
6632   def : SIMDTableLookupAlias<asm # ".8b",
6633                          !cast<Instruction>(NAME#"v8i8Two"),
6634                          V64, VecListTwo128>;
6635   def : SIMDTableLookupAlias<asm # ".8b",
6636                          !cast<Instruction>(NAME#"v8i8Three"),
6637                          V64, VecListThree128>;
6638   def : SIMDTableLookupAlias<asm # ".8b",
6639                          !cast<Instruction>(NAME#"v8i8Four"),
6640                          V64, VecListFour128>;
6641   def : SIMDTableLookupAlias<asm # ".16b",
6642                          !cast<Instruction>(NAME#"v16i8One"),
6643                          V128, VecListOne128>;
6644   def : SIMDTableLookupAlias<asm # ".16b",
6645                          !cast<Instruction>(NAME#"v16i8Two"),
6646                          V128, VecListTwo128>;
6647   def : SIMDTableLookupAlias<asm # ".16b",
6648                          !cast<Instruction>(NAME#"v16i8Three"),
6649                          V128, VecListThree128>;
6650   def : SIMDTableLookupAlias<asm # ".16b",
6651                          !cast<Instruction>(NAME#"v16i8Four"),
6652                          V128, VecListFour128>;
6653 }
6654
6655 multiclass SIMDTableLookupTied<bit op, string asm> {
6656   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6657                                       asm, ".8b">;
6658   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6659                                       asm, ".8b">;
6660   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6661                                       asm, ".8b">;
6662   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6663                                       asm, ".8b">;
6664   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6665                                       asm, ".16b">;
6666   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6667                                       asm, ".16b">;
6668   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6669                                       asm, ".16b">;
6670   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6671                                       asm, ".16b">;
6672
6673   def : SIMDTableLookupAlias<asm # ".8b",
6674                          !cast<Instruction>(NAME#"v8i8One"),
6675                          V64, VecListOne128>;
6676   def : SIMDTableLookupAlias<asm # ".8b",
6677                          !cast<Instruction>(NAME#"v8i8Two"),
6678                          V64, VecListTwo128>;
6679   def : SIMDTableLookupAlias<asm # ".8b",
6680                          !cast<Instruction>(NAME#"v8i8Three"),
6681                          V64, VecListThree128>;
6682   def : SIMDTableLookupAlias<asm # ".8b",
6683                          !cast<Instruction>(NAME#"v8i8Four"),
6684                          V64, VecListFour128>;
6685   def : SIMDTableLookupAlias<asm # ".16b",
6686                          !cast<Instruction>(NAME#"v16i8One"),
6687                          V128, VecListOne128>;
6688   def : SIMDTableLookupAlias<asm # ".16b",
6689                          !cast<Instruction>(NAME#"v16i8Two"),
6690                          V128, VecListTwo128>;
6691   def : SIMDTableLookupAlias<asm # ".16b",
6692                          !cast<Instruction>(NAME#"v16i8Three"),
6693                          V128, VecListThree128>;
6694   def : SIMDTableLookupAlias<asm # ".16b",
6695                          !cast<Instruction>(NAME#"v16i8Four"),
6696                          V128, VecListFour128>;
6697 }
6698
6699
6700 //----------------------------------------------------------------------------
6701 // AdvSIMD scalar CPY
6702 //----------------------------------------------------------------------------
6703 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6704 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6705                         string kind, Operand idxtype>
6706   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6707        "{\t$dst, $src" # kind # "$idx" #
6708        "|\t$dst, $src$idx}", "", []>,
6709     Sched<[WriteV]> {
6710   bits<5> dst;
6711   bits<5> src;
6712   let Inst{31-21} = 0b01011110000;
6713   let Inst{15-10} = 0b000001;
6714   let Inst{9-5}   = src;
6715   let Inst{4-0}   = dst;
6716 }
6717
6718 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6719       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6720     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6721                     # "|\t$dst, $src$index}",
6722                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6723
6724
6725 multiclass SIMDScalarCPY<string asm> {
6726   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
6727     bits<4> idx;
6728     let Inst{20-17} = idx;
6729     let Inst{16} = 1;
6730   }
6731   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6732     bits<3> idx;
6733     let Inst{20-18} = idx;
6734     let Inst{17-16} = 0b10;
6735   }
6736   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6737     bits<2> idx;
6738     let Inst{20-19} = idx;
6739     let Inst{18-16} = 0b100;
6740   }
6741   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6742     bits<1> idx;
6743     let Inst{20} = idx;
6744     let Inst{19-16} = 0b1000;
6745   }
6746
6747   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6748                                                           VectorIndexD:$idx)))),
6749             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6750
6751   // 'DUP' mnemonic aliases.
6752   def : SIMDScalarCPYAlias<"dup", ".b",
6753                            !cast<Instruction>(NAME#"i8"),
6754                            FPR8, V128, VectorIndexB>;
6755   def : SIMDScalarCPYAlias<"dup", ".h",
6756                            !cast<Instruction>(NAME#"i16"),
6757                            FPR16, V128, VectorIndexH>;
6758   def : SIMDScalarCPYAlias<"dup", ".s",
6759                            !cast<Instruction>(NAME#"i32"),
6760                            FPR32, V128, VectorIndexS>;
6761   def : SIMDScalarCPYAlias<"dup", ".d",
6762                            !cast<Instruction>(NAME#"i64"),
6763                            FPR64, V128, VectorIndexD>;
6764 }
6765
6766 //----------------------------------------------------------------------------
6767 // AdvSIMD modified immediate instructions
6768 //----------------------------------------------------------------------------
6769
6770 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
6771                           string asm, string op_string,
6772                           string cstr, list<dag> pattern>
6773   : I<oops, iops, asm, op_string, cstr, pattern>,
6774     Sched<[WriteV]> {
6775   bits<5> Rd;
6776   bits<8> imm8;
6777   let Inst{31}    = 0;
6778   let Inst{30}    = Q;
6779   let Inst{29}    = op;
6780   let Inst{28-19} = 0b0111100000;
6781   let Inst{18-16} = imm8{7-5};
6782   let Inst{11} = op2;
6783   let Inst{10} = 1;
6784   let Inst{9-5}   = imm8{4-0};
6785   let Inst{4-0}   = Rd;
6786 }
6787
6788 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
6789                                 Operand immtype, dag opt_shift_iop,
6790                                 string opt_shift, string asm, string kind,
6791                                 list<dag> pattern>
6792   : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
6793                         !con((ins immtype:$imm8), opt_shift_iop), asm,
6794                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
6795                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6796                         "", pattern> {
6797   let DecoderMethod = "DecodeModImmInstruction";
6798 }
6799
6800 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6801                                 Operand immtype, dag opt_shift_iop,
6802                                 string opt_shift, string asm, string kind,
6803                                 list<dag> pattern>
6804   : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
6805                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6806                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6807                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6808                         "$Rd = $dst", pattern> {
6809   let DecoderMethod = "DecodeModImmTiedInstruction";
6810 }
6811
6812 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6813                                      RegisterOperand vectype, string asm,
6814                                      string kind, list<dag> pattern>
6815   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6816                               (ins logical_vec_shift:$shift),
6817                               "$shift", asm, kind, pattern> {
6818   bits<2> shift;
6819   let Inst{15}    = b15_b12{1};
6820   let Inst{14-13} = shift;
6821   let Inst{12}    = b15_b12{0};
6822 }
6823
6824 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6825                                      RegisterOperand vectype, string asm,
6826                                      string kind, list<dag> pattern>
6827   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6828                               (ins logical_vec_shift:$shift),
6829                               "$shift", asm, kind, pattern> {
6830   bits<2> shift;
6831   let Inst{15}    = b15_b12{1};
6832   let Inst{14-13} = shift;
6833   let Inst{12}    = b15_b12{0};
6834 }
6835
6836
6837 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6838                                          RegisterOperand vectype, string asm,
6839                                          string kind, list<dag> pattern>
6840   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6841                               (ins logical_vec_hw_shift:$shift),
6842                               "$shift", asm, kind, pattern> {
6843   bits<2> shift;
6844   let Inst{15} = b15_b12{1};
6845   let Inst{14} = 0;
6846   let Inst{13} = shift{0};
6847   let Inst{12} = b15_b12{0};
6848 }
6849
6850 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6851                                          RegisterOperand vectype, string asm,
6852                                          string kind, list<dag> pattern>
6853   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6854                               (ins logical_vec_hw_shift:$shift),
6855                               "$shift", asm, kind, pattern> {
6856   bits<2> shift;
6857   let Inst{15} = b15_b12{1};
6858   let Inst{14} = 0;
6859   let Inst{13} = shift{0};
6860   let Inst{12} = b15_b12{0};
6861 }
6862
6863 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6864                                       string asm> {
6865   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6866                                                  asm, ".4h", []>;
6867   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6868                                                  asm, ".8h", []>;
6869
6870   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6871                                              asm, ".2s", []>;
6872   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6873                                              asm, ".4s", []>;
6874 }
6875
6876 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6877                                       bits<2> w_cmode, string asm,
6878                                       SDNode OpNode> {
6879   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6880                                                  asm, ".4h",
6881              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6882                                              imm0_255:$imm8,
6883                                              (i32 imm:$shift)))]>;
6884   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6885                                                  asm, ".8h",
6886              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6887                                               imm0_255:$imm8,
6888                                               (i32 imm:$shift)))]>;
6889
6890   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6891                                              asm, ".2s",
6892              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6893                                              imm0_255:$imm8,
6894                                              (i32 imm:$shift)))]>;
6895   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6896                                              asm, ".4s",
6897              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6898                                               imm0_255:$imm8,
6899                                               (i32 imm:$shift)))]>;
6900 }
6901
6902 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6903                              RegisterOperand vectype, string asm,
6904                              string kind, list<dag> pattern>
6905   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6906                               (ins move_vec_shift:$shift),
6907                               "$shift", asm, kind, pattern> {
6908   bits<1> shift;
6909   let Inst{15-13} = cmode{3-1};
6910   let Inst{12}    = shift;
6911 }
6912
6913 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
6914                                    RegisterOperand vectype,
6915                                    Operand imm_type, string asm,
6916                                    string kind, list<dag> pattern>
6917   : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
6918                               asm, kind, pattern> {
6919   let Inst{15-12} = cmode;
6920 }
6921
6922 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6923                                    list<dag> pattern>
6924   : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6925                         "\t$Rd, $imm8", "", pattern> {
6926   let Inst{15-12} = cmode;
6927   let DecoderMethod = "DecodeModImmInstruction";
6928 }
6929
6930 //----------------------------------------------------------------------------
6931 // AdvSIMD indexed element
6932 //----------------------------------------------------------------------------
6933
6934 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6935 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6936                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6937                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6938                       string apple_kind, string dst_kind, string lhs_kind,
6939                       string rhs_kind, list<dag> pattern>
6940   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6941       asm,
6942       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6943       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6944     Sched<[WriteV]> {
6945   bits<5> Rd;
6946   bits<5> Rn;
6947   bits<5> Rm;
6948
6949   let Inst{31}    = 0;
6950   let Inst{30}    = Q;
6951   let Inst{29}    = U;
6952   let Inst{28}    = Scalar;
6953   let Inst{27-24} = 0b1111;
6954   let Inst{23-22} = size;
6955   // Bit 21 must be set by the derived class.
6956   let Inst{20-16} = Rm;
6957   let Inst{15-12} = opc;
6958   // Bit 11 must be set by the derived class.
6959   let Inst{10}    = 0;
6960   let Inst{9-5}   = Rn;
6961   let Inst{4-0}   = Rd;
6962 }
6963
6964 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6965 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6966                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6967                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6968                       string apple_kind, string dst_kind, string lhs_kind,
6969                       string rhs_kind, list<dag> pattern>
6970   : I<(outs dst_reg:$dst),
6971       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6972       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6973       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6974     Sched<[WriteV]> {
6975   bits<5> Rd;
6976   bits<5> Rn;
6977   bits<5> Rm;
6978
6979   let Inst{31}    = 0;
6980   let Inst{30}    = Q;
6981   let Inst{29}    = U;
6982   let Inst{28}    = Scalar;
6983   let Inst{27-24} = 0b1111;
6984   let Inst{23-22} = size;
6985   // Bit 21 must be set by the derived class.
6986   let Inst{20-16} = Rm;
6987   let Inst{15-12} = opc;
6988   // Bit 11 must be set by the derived class.
6989   let Inst{10}    = 0;
6990   let Inst{9-5}   = Rn;
6991   let Inst{4-0}   = Rd;
6992 }
6993
6994 // ARMv8.2 Index Dot product instructions
6995 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, string asm, string dst_kind,
6996                                       string lhs_kind, string rhs_kind> :
6997         BaseSIMDIndexedTied<Q, U, 0b0, 0b10, 0b1110, V128, V128, V128, VectorIndexS,
6998                             asm, "", dst_kind, lhs_kind, rhs_kind, []> {
6999   bits<2> idx;
7000   let Inst{21}    = idx{0};  // L
7001   let Inst{11}    = idx{1};  // H
7002 }
7003
7004 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
7005                          SDPatternOperator OpNode> {
7006   let Predicates = [HasNEON, HasFullFP16] in {
7007   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
7008                                       V64, V64,
7009                                       V128_lo, VectorIndexH,
7010                                       asm, ".4h", ".4h", ".4h", ".h",
7011     [(set (v4f16 V64:$Rd),
7012         (OpNode (v4f16 V64:$Rn),
7013          (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7014     bits<3> idx;
7015     let Inst{11} = idx{2};
7016     let Inst{21} = idx{1};
7017     let Inst{20} = idx{0};
7018   }
7019
7020   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
7021                                       V128, V128,
7022                                       V128_lo, VectorIndexH,
7023                                       asm, ".8h", ".8h", ".8h", ".h",
7024     [(set (v8f16 V128:$Rd),
7025         (OpNode (v8f16 V128:$Rn),
7026          (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7027     bits<3> idx;
7028     let Inst{11} = idx{2};
7029     let Inst{21} = idx{1};
7030     let Inst{20} = idx{0};
7031   }
7032   } // Predicates = [HasNEON, HasFullFP16]
7033
7034   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7035                                       V64, V64,
7036                                       V128, VectorIndexS,
7037                                       asm, ".2s", ".2s", ".2s", ".s",
7038     [(set (v2f32 V64:$Rd),
7039         (OpNode (v2f32 V64:$Rn),
7040          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7041     bits<2> idx;
7042     let Inst{11} = idx{1};
7043     let Inst{21} = idx{0};
7044   }
7045
7046   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7047                                       V128, V128,
7048                                       V128, VectorIndexS,
7049                                       asm, ".4s", ".4s", ".4s", ".s",
7050     [(set (v4f32 V128:$Rd),
7051         (OpNode (v4f32 V128:$Rn),
7052          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7053     bits<2> idx;
7054     let Inst{11} = idx{1};
7055     let Inst{21} = idx{0};
7056   }
7057
7058   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
7059                                       V128, V128,
7060                                       V128, VectorIndexD,
7061                                       asm, ".2d", ".2d", ".2d", ".d",
7062     [(set (v2f64 V128:$Rd),
7063         (OpNode (v2f64 V128:$Rn),
7064          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
7065     bits<1> idx;
7066     let Inst{11} = idx{0};
7067     let Inst{21} = 0;
7068   }
7069
7070   let Predicates = [HasNEON, HasFullFP16] in {
7071   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
7072                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7073                                       asm, ".h", "", "", ".h",
7074     [(set (f16 FPR16Op:$Rd),
7075           (OpNode (f16 FPR16Op:$Rn),
7076                   (f16 (vector_extract (v8f16 V128_lo:$Rm),
7077                                        VectorIndexH:$idx))))]> {
7078     bits<3> idx;
7079     let Inst{11} = idx{2};
7080     let Inst{21} = idx{1};
7081     let Inst{20} = idx{0};
7082   }
7083   } // Predicates = [HasNEON, HasFullFP16]
7084
7085   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7086                                       FPR32Op, FPR32Op, V128, VectorIndexS,
7087                                       asm, ".s", "", "", ".s",
7088     [(set (f32 FPR32Op:$Rd),
7089           (OpNode (f32 FPR32Op:$Rn),
7090                   (f32 (vector_extract (v4f32 V128:$Rm),
7091                                        VectorIndexS:$idx))))]> {
7092     bits<2> idx;
7093     let Inst{11} = idx{1};
7094     let Inst{21} = idx{0};
7095   }
7096
7097   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
7098                                       FPR64Op, FPR64Op, V128, VectorIndexD,
7099                                       asm, ".d", "", "", ".d",
7100     [(set (f64 FPR64Op:$Rd),
7101           (OpNode (f64 FPR64Op:$Rn),
7102                   (f64 (vector_extract (v2f64 V128:$Rm),
7103                                        VectorIndexD:$idx))))]> {
7104     bits<1> idx;
7105     let Inst{11} = idx{0};
7106     let Inst{21} = 0;
7107   }
7108 }
7109
7110 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
7111   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
7112   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7113                            (AArch64duplane32 (v4f32 V128:$Rm),
7114                                            VectorIndexS:$idx))),
7115             (!cast<Instruction>(INST # v2i32_indexed)
7116                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7117   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7118                            (AArch64dup (f32 FPR32Op:$Rm)))),
7119             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
7120                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7121
7122
7123   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
7124   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7125                            (AArch64duplane32 (v4f32 V128:$Rm),
7126                                            VectorIndexS:$idx))),
7127             (!cast<Instruction>(INST # "v4i32_indexed")
7128                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7129   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7130                            (AArch64dup (f32 FPR32Op:$Rm)))),
7131             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
7132                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7133
7134   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
7135   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7136                            (AArch64duplane64 (v2f64 V128:$Rm),
7137                                            VectorIndexD:$idx))),
7138             (!cast<Instruction>(INST # "v2i64_indexed")
7139                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7140   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7141                            (AArch64dup (f64 FPR64Op:$Rm)))),
7142             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
7143                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
7144
7145   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
7146   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7147                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
7148             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7149                 V128:$Rm, VectorIndexS:$idx)>;
7150   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7151                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
7152             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7153                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
7154
7155   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
7156   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
7157                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
7158             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
7159                 V128:$Rm, VectorIndexD:$idx)>;
7160 }
7161
7162 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
7163   let Predicates = [HasNEON, HasFullFP16] in {
7164   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
7165                                           V128_lo, VectorIndexH,
7166                                           asm, ".4h", ".4h", ".4h", ".h", []> {
7167     bits<3> idx;
7168     let Inst{11} = idx{2};
7169     let Inst{21} = idx{1};
7170     let Inst{20} = idx{0};
7171   }
7172
7173   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
7174                                           V128, V128,
7175                                           V128_lo, VectorIndexH,
7176                                           asm, ".8h", ".8h", ".8h", ".h", []> {
7177     bits<3> idx;
7178     let Inst{11} = idx{2};
7179     let Inst{21} = idx{1};
7180     let Inst{20} = idx{0};
7181   }
7182   } // Predicates = [HasNEON, HasFullFP16]
7183
7184   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
7185                                           V128, VectorIndexS,
7186                                           asm, ".2s", ".2s", ".2s", ".s", []> {
7187     bits<2> idx;
7188     let Inst{11} = idx{1};
7189     let Inst{21} = idx{0};
7190   }
7191
7192   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7193                                       V128, V128,
7194                                       V128, VectorIndexS,
7195                                       asm, ".4s", ".4s", ".4s", ".s", []> {
7196     bits<2> idx;
7197     let Inst{11} = idx{1};
7198     let Inst{21} = idx{0};
7199   }
7200
7201   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
7202                                       V128, V128,
7203                                       V128, VectorIndexD,
7204                                       asm, ".2d", ".2d", ".2d", ".d", []> {
7205     bits<1> idx;
7206     let Inst{11} = idx{0};
7207     let Inst{21} = 0;
7208   }
7209
7210   let Predicates = [HasNEON, HasFullFP16] in {
7211   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
7212                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7213                                       asm, ".h", "", "", ".h", []> {
7214     bits<3> idx;
7215     let Inst{11} = idx{2};
7216     let Inst{21} = idx{1};
7217     let Inst{20} = idx{0};
7218   }
7219   } // Predicates = [HasNEON, HasFullFP16]
7220
7221   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7222                                       FPR32Op, FPR32Op, V128, VectorIndexS,
7223                                       asm, ".s", "", "", ".s", []> {
7224     bits<2> idx;
7225     let Inst{11} = idx{1};
7226     let Inst{21} = idx{0};
7227   }
7228
7229   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7230                                       FPR64Op, FPR64Op, V128, VectorIndexD,
7231                                       asm, ".d", "", "", ".d", []> {
7232     bits<1> idx;
7233     let Inst{11} = idx{0};
7234     let Inst{21} = 0;
7235   }
7236 }
7237
7238 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7239                          SDPatternOperator OpNode> {
7240   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7241                                       V128_lo, VectorIndexH,
7242                                       asm, ".4h", ".4h", ".4h", ".h",
7243     [(set (v4i16 V64:$Rd),
7244         (OpNode (v4i16 V64:$Rn),
7245          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7246     bits<3> idx;
7247     let Inst{11} = idx{2};
7248     let Inst{21} = idx{1};
7249     let Inst{20} = idx{0};
7250   }
7251
7252   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7253                                       V128, V128,
7254                                       V128_lo, VectorIndexH,
7255                                       asm, ".8h", ".8h", ".8h", ".h",
7256     [(set (v8i16 V128:$Rd),
7257        (OpNode (v8i16 V128:$Rn),
7258          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7259     bits<3> idx;
7260     let Inst{11} = idx{2};
7261     let Inst{21} = idx{1};
7262     let Inst{20} = idx{0};
7263   }
7264
7265   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7266                                       V64, V64,
7267                                       V128, VectorIndexS,
7268                                       asm, ".2s", ".2s", ".2s",  ".s",
7269     [(set (v2i32 V64:$Rd),
7270        (OpNode (v2i32 V64:$Rn),
7271           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7272     bits<2> idx;
7273     let Inst{11} = idx{1};
7274     let Inst{21} = idx{0};
7275   }
7276
7277   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7278                                       V128, V128,
7279                                       V128, VectorIndexS,
7280                                       asm, ".4s", ".4s", ".4s", ".s",
7281     [(set (v4i32 V128:$Rd),
7282        (OpNode (v4i32 V128:$Rn),
7283           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7284     bits<2> idx;
7285     let Inst{11} = idx{1};
7286     let Inst{21} = idx{0};
7287   }
7288
7289   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7290                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7291                                       asm, ".h", "", "", ".h", []> {
7292     bits<3> idx;
7293     let Inst{11} = idx{2};
7294     let Inst{21} = idx{1};
7295     let Inst{20} = idx{0};
7296   }
7297
7298   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7299                                       FPR32Op, FPR32Op, V128, VectorIndexS,
7300                                       asm, ".s", "", "", ".s",
7301       [(set (i32 FPR32Op:$Rd),
7302             (OpNode FPR32Op:$Rn,
7303                     (i32 (vector_extract (v4i32 V128:$Rm),
7304                                          VectorIndexS:$idx))))]> {
7305     bits<2> idx;
7306     let Inst{11} = idx{1};
7307     let Inst{21} = idx{0};
7308   }
7309 }
7310
7311 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
7312                                SDPatternOperator OpNode> {
7313   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7314                                       V64, V64,
7315                                       V128_lo, VectorIndexH,
7316                                       asm, ".4h", ".4h", ".4h", ".h",
7317     [(set (v4i16 V64:$Rd),
7318         (OpNode (v4i16 V64:$Rn),
7319          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7320     bits<3> idx;
7321     let Inst{11} = idx{2};
7322     let Inst{21} = idx{1};
7323     let Inst{20} = idx{0};
7324   }
7325
7326   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7327                                       V128, V128,
7328                                       V128_lo, VectorIndexH,
7329                                       asm, ".8h", ".8h", ".8h", ".h",
7330     [(set (v8i16 V128:$Rd),
7331        (OpNode (v8i16 V128:$Rn),
7332          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7333     bits<3> idx;
7334     let Inst{11} = idx{2};
7335     let Inst{21} = idx{1};
7336     let Inst{20} = idx{0};
7337   }
7338
7339   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7340                                       V64, V64,
7341                                       V128, VectorIndexS,
7342                                       asm, ".2s", ".2s", ".2s", ".s",
7343     [(set (v2i32 V64:$Rd),
7344        (OpNode (v2i32 V64:$Rn),
7345           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7346     bits<2> idx;
7347     let Inst{11} = idx{1};
7348     let Inst{21} = idx{0};
7349   }
7350
7351   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7352                                       V128, V128,
7353                                       V128, VectorIndexS,
7354                                       asm, ".4s", ".4s", ".4s", ".s",
7355     [(set (v4i32 V128:$Rd),
7356        (OpNode (v4i32 V128:$Rn),
7357           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7358     bits<2> idx;
7359     let Inst{11} = idx{1};
7360     let Inst{21} = idx{0};
7361   }
7362 }
7363
7364 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
7365                                    SDPatternOperator OpNode> {
7366   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
7367                                           V128_lo, VectorIndexH,
7368                                           asm, ".4h", ".4h", ".4h", ".h",
7369     [(set (v4i16 V64:$dst),
7370         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
7371          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
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   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7379                                       V128, V128,
7380                                       V128_lo, VectorIndexH,
7381                                       asm, ".8h", ".8h", ".8h", ".h",
7382     [(set (v8i16 V128:$dst),
7383        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7384          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7385     bits<3> idx;
7386     let Inst{11} = idx{2};
7387     let Inst{21} = idx{1};
7388     let Inst{20} = idx{0};
7389   }
7390
7391   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7392                                       V64, V64,
7393                                       V128, VectorIndexS,
7394                                       asm, ".2s", ".2s", ".2s", ".s",
7395     [(set (v2i32 V64:$dst),
7396        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7397           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7398     bits<2> idx;
7399     let Inst{11} = idx{1};
7400     let Inst{21} = idx{0};
7401   }
7402
7403   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7404                                       V128, V128,
7405                                       V128, VectorIndexS,
7406                                       asm, ".4s", ".4s", ".4s", ".s",
7407     [(set (v4i32 V128:$dst),
7408        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7409           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7410     bits<2> idx;
7411     let Inst{11} = idx{1};
7412     let Inst{21} = idx{0};
7413   }
7414 }
7415
7416 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
7417                              SDPatternOperator OpNode> {
7418   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7419                                       V128, V64,
7420                                       V128_lo, VectorIndexH,
7421                                       asm, ".4s", ".4s", ".4h", ".h",
7422     [(set (v4i32 V128:$Rd),
7423         (OpNode (v4i16 V64:$Rn),
7424          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7425     bits<3> idx;
7426     let Inst{11} = idx{2};
7427     let Inst{21} = idx{1};
7428     let Inst{20} = idx{0};
7429   }
7430
7431   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7432                                       V128, V128,
7433                                       V128_lo, VectorIndexH,
7434                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7435     [(set (v4i32 V128:$Rd),
7436           (OpNode (extract_high_v8i16 V128:$Rn),
7437                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7438                                                       VectorIndexH:$idx))))]> {
7439
7440     bits<3> idx;
7441     let Inst{11} = idx{2};
7442     let Inst{21} = idx{1};
7443     let Inst{20} = idx{0};
7444   }
7445
7446   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7447                                       V128, V64,
7448                                       V128, VectorIndexS,
7449                                       asm, ".2d", ".2d", ".2s", ".s",
7450     [(set (v2i64 V128:$Rd),
7451         (OpNode (v2i32 V64:$Rn),
7452          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7453     bits<2> idx;
7454     let Inst{11} = idx{1};
7455     let Inst{21} = idx{0};
7456   }
7457
7458   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7459                                       V128, V128,
7460                                       V128, VectorIndexS,
7461                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7462     [(set (v2i64 V128:$Rd),
7463           (OpNode (extract_high_v4i32 V128:$Rn),
7464                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7465                                                       VectorIndexS:$idx))))]> {
7466     bits<2> idx;
7467     let Inst{11} = idx{1};
7468     let Inst{21} = idx{0};
7469   }
7470
7471   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7472                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7473                                       asm, ".h", "", "", ".h", []> {
7474     bits<3> idx;
7475     let Inst{11} = idx{2};
7476     let Inst{21} = idx{1};
7477     let Inst{20} = idx{0};
7478   }
7479
7480   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7481                                       FPR64Op, FPR32Op, V128, VectorIndexS,
7482                                       asm, ".s", "", "", ".s", []> {
7483     bits<2> idx;
7484     let Inst{11} = idx{1};
7485     let Inst{21} = idx{0};
7486   }
7487 }
7488
7489 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7490                                        SDPatternOperator Accum> {
7491   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7492                                       V128, V64,
7493                                       V128_lo, VectorIndexH,
7494                                       asm, ".4s", ".4s", ".4h", ".h",
7495     [(set (v4i32 V128:$dst),
7496           (Accum (v4i32 V128:$Rd),
7497                  (v4i32 (int_aarch64_neon_sqdmull
7498                              (v4i16 V64:$Rn),
7499                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7500                                                     VectorIndexH:$idx))))))]> {
7501     bits<3> idx;
7502     let Inst{11} = idx{2};
7503     let Inst{21} = idx{1};
7504     let Inst{20} = idx{0};
7505   }
7506
7507   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7508   // intermediate EXTRACT_SUBREG would be untyped.
7509   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7510                 (i32 (vector_extract (v4i32
7511                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7512                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7513                                                     VectorIndexH:$idx)))),
7514                          (i64 0))))),
7515             (EXTRACT_SUBREG
7516                 (!cast<Instruction>(NAME # v4i16_indexed)
7517                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7518                     V128_lo:$Rm, VectorIndexH:$idx),
7519                 ssub)>;
7520
7521   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7522                                       V128, V128,
7523                                       V128_lo, VectorIndexH,
7524                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7525     [(set (v4i32 V128:$dst),
7526           (Accum (v4i32 V128:$Rd),
7527                  (v4i32 (int_aarch64_neon_sqdmull
7528                             (extract_high_v8i16 V128:$Rn),
7529                             (extract_high_v8i16
7530                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7531                                                 VectorIndexH:$idx))))))]> {
7532     bits<3> idx;
7533     let Inst{11} = idx{2};
7534     let Inst{21} = idx{1};
7535     let Inst{20} = idx{0};
7536   }
7537
7538   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7539                                       V128, V64,
7540                                       V128, VectorIndexS,
7541                                       asm, ".2d", ".2d", ".2s", ".s",
7542     [(set (v2i64 V128:$dst),
7543         (Accum (v2i64 V128:$Rd),
7544                (v2i64 (int_aarch64_neon_sqdmull
7545                           (v2i32 V64:$Rn),
7546                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7547                                                  VectorIndexS:$idx))))))]> {
7548     bits<2> idx;
7549     let Inst{11} = idx{1};
7550     let Inst{21} = idx{0};
7551   }
7552
7553   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7554                                       V128, V128,
7555                                       V128, VectorIndexS,
7556                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7557     [(set (v2i64 V128:$dst),
7558           (Accum (v2i64 V128:$Rd),
7559                  (v2i64 (int_aarch64_neon_sqdmull
7560                             (extract_high_v4i32 V128:$Rn),
7561                             (extract_high_v4i32
7562                                 (AArch64duplane32 (v4i32 V128:$Rm),
7563                                                 VectorIndexS:$idx))))))]> {
7564     bits<2> idx;
7565     let Inst{11} = idx{1};
7566     let Inst{21} = idx{0};
7567   }
7568
7569   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7570                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7571                                       asm, ".h", "", "", ".h", []> {
7572     bits<3> idx;
7573     let Inst{11} = idx{2};
7574     let Inst{21} = idx{1};
7575     let Inst{20} = idx{0};
7576   }
7577
7578
7579   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7580                                       FPR64Op, FPR32Op, V128, VectorIndexS,
7581                                       asm, ".s", "", "", ".s",
7582     [(set (i64 FPR64Op:$dst),
7583           (Accum (i64 FPR64Op:$Rd),
7584                  (i64 (int_aarch64_neon_sqdmulls_scalar
7585                             (i32 FPR32Op:$Rn),
7586                             (i32 (vector_extract (v4i32 V128:$Rm),
7587                                                  VectorIndexS:$idx))))))]> {
7588
7589     bits<2> idx;
7590     let Inst{11} = idx{1};
7591     let Inst{21} = idx{0};
7592   }
7593 }
7594
7595 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7596                                    SDPatternOperator OpNode> {
7597   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7598   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7599                                       V128, V64,
7600                                       V128_lo, VectorIndexH,
7601                                       asm, ".4s", ".4s", ".4h", ".h",
7602     [(set (v4i32 V128:$Rd),
7603         (OpNode (v4i16 V64:$Rn),
7604          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7605     bits<3> idx;
7606     let Inst{11} = idx{2};
7607     let Inst{21} = idx{1};
7608     let Inst{20} = idx{0};
7609   }
7610
7611   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7612                                       V128, V128,
7613                                       V128_lo, VectorIndexH,
7614                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7615     [(set (v4i32 V128:$Rd),
7616           (OpNode (extract_high_v8i16 V128:$Rn),
7617                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7618                                                       VectorIndexH:$idx))))]> {
7619
7620     bits<3> idx;
7621     let Inst{11} = idx{2};
7622     let Inst{21} = idx{1};
7623     let Inst{20} = idx{0};
7624   }
7625
7626   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7627                                       V128, V64,
7628                                       V128, VectorIndexS,
7629                                       asm, ".2d", ".2d", ".2s", ".s",
7630     [(set (v2i64 V128:$Rd),
7631         (OpNode (v2i32 V64:$Rn),
7632          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7633     bits<2> idx;
7634     let Inst{11} = idx{1};
7635     let Inst{21} = idx{0};
7636   }
7637
7638   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7639                                       V128, V128,
7640                                       V128, VectorIndexS,
7641                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7642     [(set (v2i64 V128:$Rd),
7643           (OpNode (extract_high_v4i32 V128:$Rn),
7644                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7645                                                       VectorIndexS:$idx))))]> {
7646     bits<2> idx;
7647     let Inst{11} = idx{1};
7648     let Inst{21} = idx{0};
7649   }
7650   }
7651 }
7652
7653 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7654                                        SDPatternOperator OpNode> {
7655   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7656   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7657                                       V128, V64,
7658                                       V128_lo, VectorIndexH,
7659                                       asm, ".4s", ".4s", ".4h", ".h",
7660     [(set (v4i32 V128:$dst),
7661         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7662          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7663     bits<3> idx;
7664     let Inst{11} = idx{2};
7665     let Inst{21} = idx{1};
7666     let Inst{20} = idx{0};
7667   }
7668
7669   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7670                                       V128, V128,
7671                                       V128_lo, VectorIndexH,
7672                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7673     [(set (v4i32 V128:$dst),
7674           (OpNode (v4i32 V128:$Rd),
7675                   (extract_high_v8i16 V128:$Rn),
7676                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7677                                                       VectorIndexH:$idx))))]> {
7678     bits<3> idx;
7679     let Inst{11} = idx{2};
7680     let Inst{21} = idx{1};
7681     let Inst{20} = idx{0};
7682   }
7683
7684   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7685                                       V128, V64,
7686                                       V128, VectorIndexS,
7687                                       asm, ".2d", ".2d", ".2s", ".s",
7688     [(set (v2i64 V128:$dst),
7689         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7690          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7691     bits<2> idx;
7692     let Inst{11} = idx{1};
7693     let Inst{21} = idx{0};
7694   }
7695
7696   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7697                                       V128, V128,
7698                                       V128, VectorIndexS,
7699                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7700     [(set (v2i64 V128:$dst),
7701           (OpNode (v2i64 V128:$Rd),
7702                   (extract_high_v4i32 V128:$Rn),
7703                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7704                                                       VectorIndexS:$idx))))]> {
7705     bits<2> idx;
7706     let Inst{11} = idx{1};
7707     let Inst{21} = idx{0};
7708   }
7709   }
7710 }
7711
7712 //----------------------------------------------------------------------------
7713 // AdvSIMD scalar shift by immediate
7714 //----------------------------------------------------------------------------
7715
7716 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7717 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7718                      RegisterClass regtype1, RegisterClass regtype2,
7719                      Operand immtype, string asm, list<dag> pattern>
7720   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7721       asm, "\t$Rd, $Rn, $imm", "", pattern>,
7722     Sched<[WriteV]> {
7723   bits<5> Rd;
7724   bits<5> Rn;
7725   bits<7> imm;
7726   let Inst{31-30} = 0b01;
7727   let Inst{29}    = U;
7728   let Inst{28-23} = 0b111110;
7729   let Inst{22-16} = fixed_imm;
7730   let Inst{15-11} = opc;
7731   let Inst{10}    = 1;
7732   let Inst{9-5} = Rn;
7733   let Inst{4-0} = Rd;
7734 }
7735
7736 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7737 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7738                      RegisterClass regtype1, RegisterClass regtype2,
7739                      Operand immtype, string asm, list<dag> pattern>
7740   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7741       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7742     Sched<[WriteV]> {
7743   bits<5> Rd;
7744   bits<5> Rn;
7745   bits<7> imm;
7746   let Inst{31-30} = 0b01;
7747   let Inst{29}    = U;
7748   let Inst{28-23} = 0b111110;
7749   let Inst{22-16} = fixed_imm;
7750   let Inst{15-11} = opc;
7751   let Inst{10}    = 1;
7752   let Inst{9-5} = Rn;
7753   let Inst{4-0} = Rd;
7754 }
7755
7756
7757 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
7758   let Predicates = [HasNEON, HasFullFP16] in {
7759   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7760                               FPR16, FPR16, vecshiftR16, asm, []> {
7761     let Inst{19-16} = imm{3-0};
7762   }
7763   } // Predicates = [HasNEON, HasFullFP16]
7764   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7765                               FPR32, FPR32, vecshiftR32, asm, []> {
7766     let Inst{20-16} = imm{4-0};
7767   }
7768
7769   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7770                               FPR64, FPR64, vecshiftR64, asm, []> {
7771     let Inst{21-16} = imm{5-0};
7772   }
7773 }
7774
7775 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7776                              SDPatternOperator OpNode> {
7777   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7778                               FPR64, FPR64, vecshiftR64, asm,
7779   [(set (i64 FPR64:$Rd),
7780      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7781     let Inst{21-16} = imm{5-0};
7782   }
7783
7784   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7785             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7786 }
7787
7788 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7789                                  SDPatternOperator OpNode = null_frag> {
7790   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7791                               FPR64, FPR64, vecshiftR64, asm,
7792   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7793                                                    (i32 vecshiftR64:$imm)))]> {
7794     let Inst{21-16} = imm{5-0};
7795   }
7796
7797   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7798                            (i32 vecshiftR64:$imm))),
7799             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7800                                             vecshiftR64:$imm)>;
7801 }
7802
7803 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7804                              SDPatternOperator OpNode> {
7805   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7806                               FPR64, FPR64, vecshiftL64, asm,
7807     [(set (v1i64 FPR64:$Rd),
7808        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7809     let Inst{21-16} = imm{5-0};
7810   }
7811 }
7812
7813 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7814 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7815   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7816                               FPR64, FPR64, vecshiftL64, asm, []> {
7817     let Inst{21-16} = imm{5-0};
7818   }
7819 }
7820
7821 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7822 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7823                                SDPatternOperator OpNode = null_frag> {
7824   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7825                               FPR8, FPR16, vecshiftR8, asm, []> {
7826     let Inst{18-16} = imm{2-0};
7827   }
7828
7829   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7830                               FPR16, FPR32, vecshiftR16, asm, []> {
7831     let Inst{19-16} = imm{3-0};
7832   }
7833
7834   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7835                               FPR32, FPR64, vecshiftR32, asm,
7836     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7837     let Inst{20-16} = imm{4-0};
7838   }
7839 }
7840
7841 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7842                                 SDPatternOperator OpNode> {
7843   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7844                               FPR8, FPR8, vecshiftL8, asm, []> {
7845     let Inst{18-16} = imm{2-0};
7846   }
7847
7848   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7849                               FPR16, FPR16, vecshiftL16, asm, []> {
7850     let Inst{19-16} = imm{3-0};
7851   }
7852
7853   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7854                               FPR32, FPR32, vecshiftL32, asm,
7855     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7856     let Inst{20-16} = imm{4-0};
7857   }
7858
7859   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7860                               FPR64, FPR64, vecshiftL64, asm,
7861     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7862     let Inst{21-16} = imm{5-0};
7863   }
7864
7865   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7866             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7867 }
7868
7869 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7870   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7871                               FPR8, FPR8, vecshiftR8, asm, []> {
7872     let Inst{18-16} = imm{2-0};
7873   }
7874
7875   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7876                               FPR16, FPR16, vecshiftR16, asm, []> {
7877     let Inst{19-16} = imm{3-0};
7878   }
7879
7880   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7881                               FPR32, FPR32, vecshiftR32, asm, []> {
7882     let Inst{20-16} = imm{4-0};
7883   }
7884
7885   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7886                               FPR64, FPR64, vecshiftR64, asm, []> {
7887     let Inst{21-16} = imm{5-0};
7888   }
7889 }
7890
7891 //----------------------------------------------------------------------------
7892 // AdvSIMD vector x indexed element
7893 //----------------------------------------------------------------------------
7894
7895 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7896 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7897                      RegisterOperand dst_reg, RegisterOperand src_reg,
7898                      Operand immtype,
7899                      string asm, string dst_kind, string src_kind,
7900                      list<dag> pattern>
7901   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7902       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7903            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7904     Sched<[WriteV]> {
7905   bits<5> Rd;
7906   bits<5> Rn;
7907   let Inst{31}    = 0;
7908   let Inst{30}    = Q;
7909   let Inst{29}    = U;
7910   let Inst{28-23} = 0b011110;
7911   let Inst{22-16} = fixed_imm;
7912   let Inst{15-11} = opc;
7913   let Inst{10}    = 1;
7914   let Inst{9-5}   = Rn;
7915   let Inst{4-0}   = Rd;
7916 }
7917
7918 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7919 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7920                      RegisterOperand vectype1, RegisterOperand vectype2,
7921                      Operand immtype,
7922                      string asm, string dst_kind, string src_kind,
7923                      list<dag> pattern>
7924   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7925       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7926            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7927     Sched<[WriteV]> {
7928   bits<5> Rd;
7929   bits<5> Rn;
7930   let Inst{31}    = 0;
7931   let Inst{30}    = Q;
7932   let Inst{29}    = U;
7933   let Inst{28-23} = 0b011110;
7934   let Inst{22-16} = fixed_imm;
7935   let Inst{15-11} = opc;
7936   let Inst{10}    = 1;
7937   let Inst{9-5}   = Rn;
7938   let Inst{4-0}   = Rd;
7939 }
7940
7941 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7942                               Intrinsic OpNode> {
7943   let Predicates = [HasNEON, HasFullFP16] in {
7944   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7945                                   V64, V64, vecshiftR16,
7946                                   asm, ".4h", ".4h",
7947       [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
7948     bits<4> imm;
7949     let Inst{19-16} = imm;
7950   }
7951
7952   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7953                                   V128, V128, vecshiftR16,
7954                                   asm, ".8h", ".8h",
7955       [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
7956     bits<4> imm;
7957     let Inst{19-16} = imm;
7958   }
7959   } // Predicates = [HasNEON, HasFullFP16]
7960   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7961                                   V64, V64, vecshiftR32,
7962                                   asm, ".2s", ".2s",
7963       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7964     bits<5> imm;
7965     let Inst{20-16} = imm;
7966   }
7967
7968   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7969                                   V128, V128, vecshiftR32,
7970                                   asm, ".4s", ".4s",
7971       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7972     bits<5> imm;
7973     let Inst{20-16} = imm;
7974   }
7975
7976   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7977                                   V128, V128, vecshiftR64,
7978                                   asm, ".2d", ".2d",
7979       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7980     bits<6> imm;
7981     let Inst{21-16} = imm;
7982   }
7983 }
7984
7985 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
7986                                   Intrinsic OpNode> {
7987   let Predicates = [HasNEON, HasFullFP16] in {
7988   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7989                                   V64, V64, vecshiftR16,
7990                                   asm, ".4h", ".4h",
7991       [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
7992     bits<4> imm;
7993     let Inst{19-16} = imm;
7994   }
7995
7996   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7997                                   V128, V128, vecshiftR16,
7998                                   asm, ".8h", ".8h",
7999       [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
8000     bits<4> imm;
8001     let Inst{19-16} = imm;
8002   }
8003   } // Predicates = [HasNEON, HasFullFP16]
8004
8005   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8006                                   V64, V64, vecshiftR32,
8007                                   asm, ".2s", ".2s",
8008       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
8009     bits<5> imm;
8010     let Inst{20-16} = imm;
8011   }
8012
8013   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8014                                   V128, V128, vecshiftR32,
8015                                   asm, ".4s", ".4s",
8016       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
8017     bits<5> imm;
8018     let Inst{20-16} = imm;
8019   }
8020
8021   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8022                                   V128, V128, vecshiftR64,
8023                                   asm, ".2d", ".2d",
8024       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
8025     bits<6> imm;
8026     let Inst{21-16} = imm;
8027   }
8028 }
8029
8030 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
8031                                      SDPatternOperator OpNode> {
8032   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8033                                   V64, V128, vecshiftR16Narrow,
8034                                   asm, ".8b", ".8h",
8035       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
8036     bits<3> imm;
8037     let Inst{18-16} = imm;
8038   }
8039
8040   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8041                                   V128, V128, vecshiftR16Narrow,
8042                                   asm#"2", ".16b", ".8h", []> {
8043     bits<3> imm;
8044     let Inst{18-16} = imm;
8045     let hasSideEffects = 0;
8046   }
8047
8048   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8049                                   V64, V128, vecshiftR32Narrow,
8050                                   asm, ".4h", ".4s",
8051       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
8052     bits<4> imm;
8053     let Inst{19-16} = imm;
8054   }
8055
8056   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8057                                   V128, V128, vecshiftR32Narrow,
8058                                   asm#"2", ".8h", ".4s", []> {
8059     bits<4> imm;
8060     let Inst{19-16} = imm;
8061     let hasSideEffects = 0;
8062   }
8063
8064   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8065                                   V64, V128, vecshiftR64Narrow,
8066                                   asm, ".2s", ".2d",
8067       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
8068     bits<5> imm;
8069     let Inst{20-16} = imm;
8070   }
8071
8072   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8073                                   V128, V128, vecshiftR64Narrow,
8074                                   asm#"2", ".4s", ".2d", []> {
8075     bits<5> imm;
8076     let Inst{20-16} = imm;
8077     let hasSideEffects = 0;
8078   }
8079
8080   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
8081   // themselves, so put them here instead.
8082
8083   // Patterns involving what's effectively an insert high and a normal
8084   // intrinsic, represented by CONCAT_VECTORS.
8085   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
8086                                                    vecshiftR16Narrow:$imm)),
8087             (!cast<Instruction>(NAME # "v16i8_shift")
8088                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8089                 V128:$Rn, vecshiftR16Narrow:$imm)>;
8090   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
8091                                                      vecshiftR32Narrow:$imm)),
8092             (!cast<Instruction>(NAME # "v8i16_shift")
8093                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8094                 V128:$Rn, vecshiftR32Narrow:$imm)>;
8095   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
8096                                                      vecshiftR64Narrow:$imm)),
8097             (!cast<Instruction>(NAME # "v4i32_shift")
8098                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8099                 V128:$Rn, vecshiftR64Narrow:$imm)>;
8100 }
8101
8102 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
8103                                 SDPatternOperator OpNode> {
8104   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8105                                   V64, V64, vecshiftL8,
8106                                   asm, ".8b", ".8b",
8107                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8108                        (i32 vecshiftL8:$imm)))]> {
8109     bits<3> imm;
8110     let Inst{18-16} = imm;
8111   }
8112
8113   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8114                                   V128, V128, vecshiftL8,
8115                                   asm, ".16b", ".16b",
8116              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8117                    (i32 vecshiftL8:$imm)))]> {
8118     bits<3> imm;
8119     let Inst{18-16} = imm;
8120   }
8121
8122   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8123                                   V64, V64, vecshiftL16,
8124                                   asm, ".4h", ".4h",
8125               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8126                     (i32 vecshiftL16:$imm)))]> {
8127     bits<4> imm;
8128     let Inst{19-16} = imm;
8129   }
8130
8131   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8132                                   V128, V128, vecshiftL16,
8133                                   asm, ".8h", ".8h",
8134             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8135                   (i32 vecshiftL16:$imm)))]> {
8136     bits<4> imm;
8137     let Inst{19-16} = imm;
8138   }
8139
8140   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8141                                   V64, V64, vecshiftL32,
8142                                   asm, ".2s", ".2s",
8143               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8144                     (i32 vecshiftL32:$imm)))]> {
8145     bits<5> imm;
8146     let Inst{20-16} = imm;
8147   }
8148
8149   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8150                                   V128, V128, vecshiftL32,
8151                                   asm, ".4s", ".4s",
8152             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8153                   (i32 vecshiftL32:$imm)))]> {
8154     bits<5> imm;
8155     let Inst{20-16} = imm;
8156   }
8157
8158   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8159                                   V128, V128, vecshiftL64,
8160                                   asm, ".2d", ".2d",
8161             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8162                   (i32 vecshiftL64:$imm)))]> {
8163     bits<6> imm;
8164     let Inst{21-16} = imm;
8165   }
8166 }
8167
8168 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
8169                                 SDPatternOperator OpNode> {
8170   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8171                                   V64, V64, vecshiftR8,
8172                                   asm, ".8b", ".8b",
8173                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8174                        (i32 vecshiftR8:$imm)))]> {
8175     bits<3> imm;
8176     let Inst{18-16} = imm;
8177   }
8178
8179   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8180                                   V128, V128, vecshiftR8,
8181                                   asm, ".16b", ".16b",
8182              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8183                    (i32 vecshiftR8:$imm)))]> {
8184     bits<3> imm;
8185     let Inst{18-16} = imm;
8186   }
8187
8188   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8189                                   V64, V64, vecshiftR16,
8190                                   asm, ".4h", ".4h",
8191               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8192                     (i32 vecshiftR16:$imm)))]> {
8193     bits<4> imm;
8194     let Inst{19-16} = imm;
8195   }
8196
8197   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8198                                   V128, V128, vecshiftR16,
8199                                   asm, ".8h", ".8h",
8200             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8201                   (i32 vecshiftR16:$imm)))]> {
8202     bits<4> imm;
8203     let Inst{19-16} = imm;
8204   }
8205
8206   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8207                                   V64, V64, vecshiftR32,
8208                                   asm, ".2s", ".2s",
8209               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8210                     (i32 vecshiftR32:$imm)))]> {
8211     bits<5> imm;
8212     let Inst{20-16} = imm;
8213   }
8214
8215   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8216                                   V128, V128, vecshiftR32,
8217                                   asm, ".4s", ".4s",
8218             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8219                   (i32 vecshiftR32:$imm)))]> {
8220     bits<5> imm;
8221     let Inst{20-16} = imm;
8222   }
8223
8224   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8225                                   V128, V128, vecshiftR64,
8226                                   asm, ".2d", ".2d",
8227             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8228                   (i32 vecshiftR64:$imm)))]> {
8229     bits<6> imm;
8230     let Inst{21-16} = imm;
8231   }
8232 }
8233
8234 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8235 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8236                                     SDPatternOperator OpNode = null_frag> {
8237   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8238                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
8239                  [(set (v8i8 V64:$dst),
8240                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8241                            (i32 vecshiftR8:$imm)))]> {
8242     bits<3> imm;
8243     let Inst{18-16} = imm;
8244   }
8245
8246   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8247                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
8248              [(set (v16i8 V128:$dst),
8249                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8250                        (i32 vecshiftR8:$imm)))]> {
8251     bits<3> imm;
8252     let Inst{18-16} = imm;
8253   }
8254
8255   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8256                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
8257               [(set (v4i16 V64:$dst),
8258                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8259                         (i32 vecshiftR16:$imm)))]> {
8260     bits<4> imm;
8261     let Inst{19-16} = imm;
8262   }
8263
8264   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8265                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
8266             [(set (v8i16 V128:$dst),
8267               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8268                       (i32 vecshiftR16:$imm)))]> {
8269     bits<4> imm;
8270     let Inst{19-16} = imm;
8271   }
8272
8273   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8274                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
8275               [(set (v2i32 V64:$dst),
8276                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8277                         (i32 vecshiftR32:$imm)))]> {
8278     bits<5> imm;
8279     let Inst{20-16} = imm;
8280   }
8281
8282   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8283                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
8284             [(set (v4i32 V128:$dst),
8285               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8286                       (i32 vecshiftR32:$imm)))]> {
8287     bits<5> imm;
8288     let Inst{20-16} = imm;
8289   }
8290
8291   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8292                                   V128, V128, vecshiftR64,
8293                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8294               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8295                       (i32 vecshiftR64:$imm)))]> {
8296     bits<6> imm;
8297     let Inst{21-16} = imm;
8298   }
8299 }
8300
8301 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
8302                                     SDPatternOperator OpNode = null_frag> {
8303   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8304                                   V64, V64, vecshiftL8,
8305                                   asm, ".8b", ".8b",
8306                     [(set (v8i8 V64:$dst),
8307                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8308                                   (i32 vecshiftL8:$imm)))]> {
8309     bits<3> imm;
8310     let Inst{18-16} = imm;
8311   }
8312
8313   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8314                                   V128, V128, vecshiftL8,
8315                                   asm, ".16b", ".16b",
8316                     [(set (v16i8 V128:$dst),
8317                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8318                                   (i32 vecshiftL8:$imm)))]> {
8319     bits<3> imm;
8320     let Inst{18-16} = imm;
8321   }
8322
8323   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8324                                   V64, V64, vecshiftL16,
8325                                   asm, ".4h", ".4h",
8326                     [(set (v4i16 V64:$dst),
8327                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8328                                    (i32 vecshiftL16:$imm)))]> {
8329     bits<4> imm;
8330     let Inst{19-16} = imm;
8331   }
8332
8333   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8334                                   V128, V128, vecshiftL16,
8335                                   asm, ".8h", ".8h",
8336                     [(set (v8i16 V128:$dst),
8337                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8338                                   (i32 vecshiftL16:$imm)))]> {
8339     bits<4> imm;
8340     let Inst{19-16} = imm;
8341   }
8342
8343   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8344                                   V64, V64, vecshiftL32,
8345                                   asm, ".2s", ".2s",
8346                     [(set (v2i32 V64:$dst),
8347                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8348                                   (i32 vecshiftL32:$imm)))]> {
8349     bits<5> imm;
8350     let Inst{20-16} = imm;
8351   }
8352
8353   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8354                                   V128, V128, vecshiftL32,
8355                                   asm, ".4s", ".4s",
8356                     [(set (v4i32 V128:$dst),
8357                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8358                                   (i32 vecshiftL32:$imm)))]> {
8359     bits<5> imm;
8360     let Inst{20-16} = imm;
8361   }
8362
8363   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8364                                   V128, V128, vecshiftL64,
8365                                   asm, ".2d", ".2d",
8366                     [(set (v2i64 V128:$dst),
8367                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8368                                   (i32 vecshiftL64:$imm)))]> {
8369     bits<6> imm;
8370     let Inst{21-16} = imm;
8371   }
8372 }
8373
8374 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
8375                                    SDPatternOperator OpNode> {
8376   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8377                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
8378       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
8379     bits<3> imm;
8380     let Inst{18-16} = imm;
8381   }
8382
8383   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8384                                   V128, V128, vecshiftL8,
8385                                   asm#"2", ".8h", ".16b",
8386       [(set (v8i16 V128:$Rd),
8387             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
8388     bits<3> imm;
8389     let Inst{18-16} = imm;
8390   }
8391
8392   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8393                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
8394       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
8395     bits<4> imm;
8396     let Inst{19-16} = imm;
8397   }
8398
8399   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8400                                   V128, V128, vecshiftL16,
8401                                   asm#"2", ".4s", ".8h",
8402       [(set (v4i32 V128:$Rd),
8403             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
8404
8405     bits<4> imm;
8406     let Inst{19-16} = imm;
8407   }
8408
8409   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8410                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
8411       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
8412     bits<5> imm;
8413     let Inst{20-16} = imm;
8414   }
8415
8416   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8417                                   V128, V128, vecshiftL32,
8418                                   asm#"2", ".2d", ".4s",
8419       [(set (v2i64 V128:$Rd),
8420             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
8421     bits<5> imm;
8422     let Inst{20-16} = imm;
8423   }
8424 }
8425
8426
8427 //---
8428 // Vector load/store
8429 //---
8430 // SIMD ldX/stX no-index memory references don't allow the optional
8431 // ", #0" constant and handle post-indexing explicitly, so we use
8432 // a more specialized parse method for them. Otherwise, it's the same as
8433 // the general GPR64sp handling.
8434
8435 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
8436                    string asm, dag oops, dag iops, list<dag> pattern>
8437   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
8438   bits<5> Vt;
8439   bits<5> Rn;
8440   let Inst{31} = 0;
8441   let Inst{30} = Q;
8442   let Inst{29-23} = 0b0011000;
8443   let Inst{22} = L;
8444   let Inst{21-16} = 0b000000;
8445   let Inst{15-12} = opcode;
8446   let Inst{11-10} = size;
8447   let Inst{9-5} = Rn;
8448   let Inst{4-0} = Vt;
8449 }
8450
8451 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
8452                        string asm, dag oops, dag iops>
8453   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
8454   bits<5> Vt;
8455   bits<5> Rn;
8456   bits<5> Xm;
8457   let Inst{31} = 0;
8458   let Inst{30} = Q;
8459   let Inst{29-23} = 0b0011001;
8460   let Inst{22} = L;
8461   let Inst{21} = 0;
8462   let Inst{20-16} = Xm;
8463   let Inst{15-12} = opcode;
8464   let Inst{11-10} = size;
8465   let Inst{9-5} = Rn;
8466   let Inst{4-0} = Vt;
8467 }
8468
8469 // The immediate form of AdvSIMD post-indexed addressing is encoded with
8470 // register post-index addressing from the zero register.
8471 multiclass SIMDLdStAliases<string asm, string layout, string Count,
8472                            int Offset, int Size> {
8473   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8474   //      "ld1\t$Vt, [$Rn], #16"
8475   // may get mapped to
8476   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8477   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8478                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8479                       GPR64sp:$Rn,
8480                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8481                       XZR), 1>;
8482
8483   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8484   //      "ld1.8b\t$Vt, [$Rn], #16"
8485   // may get mapped to
8486   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8487   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8488                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8489                       GPR64sp:$Rn,
8490                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8491                       XZR), 0>;
8492
8493   // E.g. "ld1.8b { v0, v1 }, [x1]"
8494   //      "ld1\t$Vt, [$Rn]"
8495   // may get mapped to
8496   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8497   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8498                   (!cast<Instruction>(NAME # Count # "v" # layout)
8499                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8500                       GPR64sp:$Rn), 0>;
8501
8502   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8503   //      "ld1\t$Vt, [$Rn], $Xm"
8504   // may get mapped to
8505   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8506   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8507                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8508                       GPR64sp:$Rn,
8509                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8510                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8511 }
8512
8513 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
8514                        int Offset64, bits<4> opcode> {
8515   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8516     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8517                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8518                            (ins GPR64sp:$Rn), []>;
8519     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8520                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8521                            (ins GPR64sp:$Rn), []>;
8522     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8523                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8524                            (ins GPR64sp:$Rn), []>;
8525     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8526                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8527                            (ins GPR64sp:$Rn), []>;
8528     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8529                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8530                            (ins GPR64sp:$Rn), []>;
8531     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8532                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8533                            (ins GPR64sp:$Rn), []>;
8534     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8535                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8536                            (ins GPR64sp:$Rn), []>;
8537
8538
8539     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8540                        (outs GPR64sp:$wback,
8541                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
8542                        (ins GPR64sp:$Rn,
8543                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8544     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8545                        (outs GPR64sp:$wback,
8546                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
8547                        (ins GPR64sp:$Rn,
8548                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8549     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8550                        (outs GPR64sp:$wback,
8551                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
8552                        (ins GPR64sp:$Rn,
8553                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8554     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8555                        (outs GPR64sp:$wback,
8556                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
8557                        (ins GPR64sp:$Rn,
8558                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8559     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8560                        (outs GPR64sp:$wback,
8561                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
8562                        (ins GPR64sp:$Rn,
8563                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8564     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8565                        (outs GPR64sp:$wback,
8566                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
8567                        (ins GPR64sp:$Rn,
8568                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8569     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8570                        (outs GPR64sp:$wback,
8571                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
8572                        (ins GPR64sp:$Rn,
8573                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8574   }
8575
8576   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8577   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8578   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8579   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8580   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8581   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8582   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8583 }
8584
8585 // Only ld1/st1 has a v1d version.
8586 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
8587                        int Offset64, bits<4> opcode> {
8588   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8589     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8590                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8591                                  GPR64sp:$Rn), []>;
8592     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8593                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8594                                 GPR64sp:$Rn), []>;
8595     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8596                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8597                                 GPR64sp:$Rn), []>;
8598     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8599                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8600                                 GPR64sp:$Rn), []>;
8601     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8602                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8603                                 GPR64sp:$Rn), []>;
8604     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8605                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8606                                 GPR64sp:$Rn), []>;
8607     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8608                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8609                                 GPR64sp:$Rn), []>;
8610
8611     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8612                        (outs GPR64sp:$wback),
8613                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8614                             GPR64sp:$Rn,
8615                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8616     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8617                        (outs GPR64sp:$wback),
8618                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8619                             GPR64sp:$Rn,
8620                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8621     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8622                        (outs GPR64sp:$wback),
8623                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8624                             GPR64sp:$Rn,
8625                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8626     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8627                        (outs GPR64sp:$wback),
8628                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8629                             GPR64sp:$Rn,
8630                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8631     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8632                        (outs GPR64sp:$wback),
8633                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8634                             GPR64sp:$Rn,
8635                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8636     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8637                        (outs GPR64sp:$wback),
8638                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8639                             GPR64sp:$Rn,
8640                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8641     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8642                        (outs GPR64sp:$wback),
8643                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8644                             GPR64sp:$Rn,
8645                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8646   }
8647
8648   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8649   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8650   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8651   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8652   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8653   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8654   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8655 }
8656
8657 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8658                        int Offset128, int Offset64, bits<4> opcode>
8659   : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8660
8661   // LD1 instructions have extra "1d" variants.
8662   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8663     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8664                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8665                            (ins GPR64sp:$Rn), []>;
8666
8667     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8668                        (outs GPR64sp:$wback,
8669                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
8670                        (ins GPR64sp:$Rn,
8671                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8672   }
8673
8674   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8675 }
8676
8677 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8678                        int Offset128, int Offset64, bits<4> opcode>
8679   : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8680
8681   // ST1 instructions have extra "1d" variants.
8682   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8683     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8684                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8685                                 GPR64sp:$Rn), []>;
8686
8687     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8688                        (outs GPR64sp:$wback),
8689                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8690                             GPR64sp:$Rn,
8691                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8692   }
8693
8694   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8695 }
8696
8697 multiclass SIMDLd1Multiple<string asm> {
8698   defm One   : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8,  0b0111>;
8699   defm Two   : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8700   defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8701   defm Four  : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8702 }
8703
8704 multiclass SIMDSt1Multiple<string asm> {
8705   defm One   : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8,  0b0111>;
8706   defm Two   : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8707   defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8708   defm Four  : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8709 }
8710
8711 multiclass SIMDLd2Multiple<string asm> {
8712   defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8713 }
8714
8715 multiclass SIMDSt2Multiple<string asm> {
8716   defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8717 }
8718
8719 multiclass SIMDLd3Multiple<string asm> {
8720   defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8721 }
8722
8723 multiclass SIMDSt3Multiple<string asm> {
8724   defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8725 }
8726
8727 multiclass SIMDLd4Multiple<string asm> {
8728   defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8729 }
8730
8731 multiclass SIMDSt4Multiple<string asm> {
8732   defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8733 }
8734
8735 //---
8736 // AdvSIMD Load/store single-element
8737 //---
8738
8739 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8740                          string asm, string operands, string cst,
8741                          dag oops, dag iops, list<dag> pattern>
8742   : I<oops, iops, asm, operands, cst, pattern> {
8743   bits<5> Vt;
8744   bits<5> Rn;
8745   let Inst{31} = 0;
8746   let Inst{29-24} = 0b001101;
8747   let Inst{22} = L;
8748   let Inst{21} = R;
8749   let Inst{15-13} = opcode;
8750   let Inst{9-5} = Rn;
8751   let Inst{4-0} = Vt;
8752 }
8753
8754 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8755                          string asm, string operands, string cst,
8756                          dag oops, dag iops, list<dag> pattern>
8757   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8758   bits<5> Vt;
8759   bits<5> Rn;
8760   let Inst{31} = 0;
8761   let Inst{29-24} = 0b001101;
8762   let Inst{22} = L;
8763   let Inst{21} = R;
8764   let Inst{15-13} = opcode;
8765   let Inst{9-5} = Rn;
8766   let Inst{4-0} = Vt;
8767 }
8768
8769
8770 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8771 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8772                   Operand listtype>
8773   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8774                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
8775                        []> {
8776   let Inst{30} = Q;
8777   let Inst{23} = 0;
8778   let Inst{20-16} = 0b00000;
8779   let Inst{12} = S;
8780   let Inst{11-10} = size;
8781 }
8782 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8783 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8784                       string asm, Operand listtype, Operand GPR64pi>
8785   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8786                        "$Rn = $wback",
8787                        (outs GPR64sp:$wback, listtype:$Vt),
8788                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8789   bits<5> Xm;
8790   let Inst{30} = Q;
8791   let Inst{23} = 1;
8792   let Inst{20-16} = Xm;
8793   let Inst{12} = S;
8794   let Inst{11-10} = size;
8795 }
8796
8797 multiclass SIMDLdrAliases<string asm, string layout, string Count,
8798                           int Offset, int Size> {
8799   // E.g. "ld1r { v0.8b }, [x1], #1"
8800   //      "ld1r.8b\t$Vt, [$Rn], #1"
8801   // may get mapped to
8802   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8803   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8804                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8805                       GPR64sp:$Rn,
8806                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8807                       XZR), 1>;
8808
8809   // E.g. "ld1r.8b { v0 }, [x1], #1"
8810   //      "ld1r.8b\t$Vt, [$Rn], #1"
8811   // may get mapped to
8812   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8813   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8814                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8815                       GPR64sp:$Rn,
8816                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8817                       XZR), 0>;
8818
8819   // E.g. "ld1r.8b { v0 }, [x1]"
8820   //      "ld1r.8b\t$Vt, [$Rn]"
8821   // may get mapped to
8822   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8823   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8824                   (!cast<Instruction>(NAME # "v" # layout)
8825                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8826                       GPR64sp:$Rn), 0>;
8827
8828   // E.g. "ld1r.8b { v0 }, [x1], x2"
8829   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
8830   // may get mapped to
8831   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8832   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8833                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8834                       GPR64sp:$Rn,
8835                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8836                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8837 }
8838
8839 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8840   int Offset1, int Offset2, int Offset4, int Offset8> {
8841   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8842                         !cast<Operand>("VecList" # Count # "8b")>;
8843   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8844                         !cast<Operand>("VecList" # Count #"16b")>;
8845   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8846                         !cast<Operand>("VecList" # Count #"4h")>;
8847   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8848                         !cast<Operand>("VecList" # Count #"8h")>;
8849   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8850                         !cast<Operand>("VecList" # Count #"2s")>;
8851   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8852                         !cast<Operand>("VecList" # Count #"4s")>;
8853   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8854                         !cast<Operand>("VecList" # Count #"1d")>;
8855   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8856                         !cast<Operand>("VecList" # Count #"2d")>;
8857
8858   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8859                                  !cast<Operand>("VecList" # Count # "8b"),
8860                                  !cast<Operand>("GPR64pi" # Offset1)>;
8861   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8862                                  !cast<Operand>("VecList" # Count # "16b"),
8863                                  !cast<Operand>("GPR64pi" # Offset1)>;
8864   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8865                                  !cast<Operand>("VecList" # Count # "4h"),
8866                                  !cast<Operand>("GPR64pi" # Offset2)>;
8867   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8868                                  !cast<Operand>("VecList" # Count # "8h"),
8869                                  !cast<Operand>("GPR64pi" # Offset2)>;
8870   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8871                                  !cast<Operand>("VecList" # Count # "2s"),
8872                                  !cast<Operand>("GPR64pi" # Offset4)>;
8873   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8874                                  !cast<Operand>("VecList" # Count # "4s"),
8875                                  !cast<Operand>("GPR64pi" # Offset4)>;
8876   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8877                                  !cast<Operand>("VecList" # Count # "1d"),
8878                                  !cast<Operand>("GPR64pi" # Offset8)>;
8879   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8880                                  !cast<Operand>("VecList" # Count # "2d"),
8881                                  !cast<Operand>("GPR64pi" # Offset8)>;
8882
8883   defm : SIMDLdrAliases<asm, "8b",  Count, Offset1,  64>;
8884   defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8885   defm : SIMDLdrAliases<asm, "4h",  Count, Offset2,  64>;
8886   defm : SIMDLdrAliases<asm, "8h",  Count, Offset2, 128>;
8887   defm : SIMDLdrAliases<asm, "2s",  Count, Offset4,  64>;
8888   defm : SIMDLdrAliases<asm, "4s",  Count, Offset4, 128>;
8889   defm : SIMDLdrAliases<asm, "1d",  Count, Offset8,  64>;
8890   defm : SIMDLdrAliases<asm, "2d",  Count, Offset8, 128>;
8891 }
8892
8893 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8894                       dag oops, dag iops, list<dag> pattern>
8895   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8896                        pattern> {
8897   // idx encoded in Q:S:size fields.
8898   bits<4> idx;
8899   let Inst{30} = idx{3};
8900   let Inst{23} = 0;
8901   let Inst{20-16} = 0b00000;
8902   let Inst{12} = idx{2};
8903   let Inst{11-10} = idx{1-0};
8904 }
8905 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8906                       dag oops, dag iops, list<dag> pattern>
8907   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8908                            oops, iops, pattern> {
8909   // idx encoded in Q:S:size fields.
8910   bits<4> idx;
8911   let Inst{30} = idx{3};
8912   let Inst{23} = 0;
8913   let Inst{20-16} = 0b00000;
8914   let Inst{12} = idx{2};
8915   let Inst{11-10} = idx{1-0};
8916 }
8917 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8918                           dag oops, dag iops>
8919   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8920                        "$Rn = $wback", oops, iops, []> {
8921   // idx encoded in Q:S:size fields.
8922   bits<4> idx;
8923   bits<5> Xm;
8924   let Inst{30} = idx{3};
8925   let Inst{23} = 1;
8926   let Inst{20-16} = Xm;
8927   let Inst{12} = idx{2};
8928   let Inst{11-10} = idx{1-0};
8929 }
8930 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8931                           dag oops, dag iops>
8932   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8933                            "$Rn = $wback", oops, iops, []> {
8934   // idx encoded in Q:S:size fields.
8935   bits<4> idx;
8936   bits<5> Xm;
8937   let Inst{30} = idx{3};
8938   let Inst{23} = 1;
8939   let Inst{20-16} = Xm;
8940   let Inst{12} = idx{2};
8941   let Inst{11-10} = idx{1-0};
8942 }
8943
8944 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8945                       dag oops, dag iops, list<dag> pattern>
8946   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8947                        pattern> {
8948   // idx encoded in Q:S:size<1> fields.
8949   bits<3> idx;
8950   let Inst{30} = idx{2};
8951   let Inst{23} = 0;
8952   let Inst{20-16} = 0b00000;
8953   let Inst{12} = idx{1};
8954   let Inst{11} = idx{0};
8955   let Inst{10} = size;
8956 }
8957 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8958                       dag oops, dag iops, list<dag> pattern>
8959   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8960                            oops, iops, pattern> {
8961   // idx encoded in Q:S:size<1> fields.
8962   bits<3> idx;
8963   let Inst{30} = idx{2};
8964   let Inst{23} = 0;
8965   let Inst{20-16} = 0b00000;
8966   let Inst{12} = idx{1};
8967   let Inst{11} = idx{0};
8968   let Inst{10} = size;
8969 }
8970
8971 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8972                           dag oops, dag iops>
8973   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8974                        "$Rn = $wback", oops, iops, []> {
8975   // idx encoded in Q:S:size<1> fields.
8976   bits<3> idx;
8977   bits<5> Xm;
8978   let Inst{30} = idx{2};
8979   let Inst{23} = 1;
8980   let Inst{20-16} = Xm;
8981   let Inst{12} = idx{1};
8982   let Inst{11} = idx{0};
8983   let Inst{10} = size;
8984 }
8985 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8986                           dag oops, dag iops>
8987   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8988                            "$Rn = $wback", oops, iops, []> {
8989   // idx encoded in Q:S:size<1> fields.
8990   bits<3> idx;
8991   bits<5> Xm;
8992   let Inst{30} = idx{2};
8993   let Inst{23} = 1;
8994   let Inst{20-16} = Xm;
8995   let Inst{12} = idx{1};
8996   let Inst{11} = idx{0};
8997   let Inst{10} = size;
8998 }
8999 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9000                       dag oops, dag iops, list<dag> pattern>
9001   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9002                        pattern> {
9003   // idx encoded in Q:S fields.
9004   bits<2> idx;
9005   let Inst{30} = idx{1};
9006   let Inst{23} = 0;
9007   let Inst{20-16} = 0b00000;
9008   let Inst{12} = idx{0};
9009   let Inst{11-10} = size;
9010 }
9011 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9012                       dag oops, dag iops, list<dag> pattern>
9013   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9014                            oops, iops, pattern> {
9015   // idx encoded in Q:S fields.
9016   bits<2> idx;
9017   let Inst{30} = idx{1};
9018   let Inst{23} = 0;
9019   let Inst{20-16} = 0b00000;
9020   let Inst{12} = idx{0};
9021   let Inst{11-10} = size;
9022 }
9023 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
9024                           string asm, dag oops, dag iops>
9025   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9026                        "$Rn = $wback", oops, iops, []> {
9027   // idx encoded in Q:S fields.
9028   bits<2> idx;
9029   bits<5> Xm;
9030   let Inst{30} = idx{1};
9031   let Inst{23} = 1;
9032   let Inst{20-16} = Xm;
9033   let Inst{12} = idx{0};
9034   let Inst{11-10} = size;
9035 }
9036 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9037                           string asm, dag oops, dag iops>
9038   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9039                            "$Rn = $wback", oops, iops, []> {
9040   // idx encoded in Q:S fields.
9041   bits<2> idx;
9042   bits<5> Xm;
9043   let Inst{30} = idx{1};
9044   let Inst{23} = 1;
9045   let Inst{20-16} = Xm;
9046   let Inst{12} = idx{0};
9047   let Inst{11-10} = size;
9048 }
9049 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9050                       dag oops, dag iops, list<dag> pattern>
9051   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9052                        pattern> {
9053   // idx encoded in Q field.
9054   bits<1> idx;
9055   let Inst{30} = idx;
9056   let Inst{23} = 0;
9057   let Inst{20-16} = 0b00000;
9058   let Inst{12} = 0;
9059   let Inst{11-10} = size;
9060 }
9061 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9062                       dag oops, dag iops, list<dag> pattern>
9063   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9064                            oops, iops, pattern> {
9065   // idx encoded in Q field.
9066   bits<1> idx;
9067   let Inst{30} = idx;
9068   let Inst{23} = 0;
9069   let Inst{20-16} = 0b00000;
9070   let Inst{12} = 0;
9071   let Inst{11-10} = size;
9072 }
9073 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
9074                           string asm, dag oops, dag iops>
9075   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9076                        "$Rn = $wback", oops, iops, []> {
9077   // idx encoded in Q field.
9078   bits<1> idx;
9079   bits<5> Xm;
9080   let Inst{30} = idx;
9081   let Inst{23} = 1;
9082   let Inst{20-16} = Xm;
9083   let Inst{12} = 0;
9084   let Inst{11-10} = size;
9085 }
9086 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9087                           string asm, dag oops, dag iops>
9088   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9089                            "$Rn = $wback", oops, iops, []> {
9090   // idx encoded in Q field.
9091   bits<1> idx;
9092   bits<5> Xm;
9093   let Inst{30} = idx;
9094   let Inst{23} = 1;
9095   let Inst{20-16} = Xm;
9096   let Inst{12} = 0;
9097   let Inst{11-10} = size;
9098 }
9099
9100 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9101 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
9102                          RegisterOperand listtype,
9103                          RegisterOperand GPR64pi> {
9104   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
9105                            (outs listtype:$dst),
9106                            (ins listtype:$Vt, VectorIndexB:$idx,
9107                                 GPR64sp:$Rn), []>;
9108
9109   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
9110                             (outs GPR64sp:$wback, listtype:$dst),
9111                             (ins listtype:$Vt, VectorIndexB:$idx,
9112                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9113 }
9114 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9115 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
9116                          RegisterOperand listtype,
9117                          RegisterOperand GPR64pi> {
9118   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
9119                             (outs listtype:$dst),
9120                             (ins listtype:$Vt, VectorIndexH:$idx,
9121                                  GPR64sp:$Rn), []>;
9122
9123   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
9124                             (outs GPR64sp:$wback, listtype:$dst),
9125                             (ins listtype:$Vt, VectorIndexH:$idx,
9126                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9127 }
9128 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9129 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
9130                          RegisterOperand listtype,
9131                          RegisterOperand GPR64pi> {
9132   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
9133                             (outs listtype:$dst),
9134                             (ins listtype:$Vt, VectorIndexS:$idx,
9135                                  GPR64sp:$Rn), []>;
9136
9137   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
9138                             (outs GPR64sp:$wback, listtype:$dst),
9139                             (ins listtype:$Vt, VectorIndexS:$idx,
9140                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9141 }
9142 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9143 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
9144                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9145   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
9146                             (outs listtype:$dst),
9147                             (ins listtype:$Vt, VectorIndexD:$idx,
9148                                  GPR64sp:$Rn), []>;
9149
9150   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
9151                             (outs GPR64sp:$wback, listtype:$dst),
9152                             (ins listtype:$Vt, VectorIndexD:$idx,
9153                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9154 }
9155 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9156 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
9157                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9158   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
9159                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
9160                                         GPR64sp:$Rn), []>;
9161
9162   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
9163                                     (outs GPR64sp:$wback),
9164                                     (ins listtype:$Vt, VectorIndexB:$idx,
9165                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
9166 }
9167 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9168 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
9169                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9170   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
9171                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
9172                                          GPR64sp:$Rn), []>;
9173
9174   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
9175                             (outs GPR64sp:$wback),
9176                             (ins listtype:$Vt, VectorIndexH:$idx,
9177                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9178 }
9179 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9180 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
9181                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9182   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
9183                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
9184                                          GPR64sp:$Rn), []>;
9185
9186   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
9187                             (outs GPR64sp:$wback),
9188                             (ins listtype:$Vt, VectorIndexS:$idx,
9189                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9190 }
9191 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9192 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
9193                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9194   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
9195                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
9196                                          GPR64sp:$Rn), []>;
9197
9198   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
9199                             (outs GPR64sp:$wback),
9200                             (ins listtype:$Vt, VectorIndexD:$idx,
9201                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9202 }
9203
9204 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
9205                                  string Count, int Offset, Operand idxtype> {
9206   // E.g. "ld1 { v0.8b }[0], [x1], #1"
9207   //      "ld1\t$Vt, [$Rn], #1"
9208   // may get mapped to
9209   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9210   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
9211                   (!cast<Instruction>(NAME # Type  # "_POST")
9212                       GPR64sp:$Rn,
9213                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9214                       idxtype:$idx, XZR), 1>;
9215
9216   // E.g. "ld1.8b { v0 }[0], [x1], #1"
9217   //      "ld1.8b\t$Vt, [$Rn], #1"
9218   // may get mapped to
9219   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9220   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9221                   (!cast<Instruction>(NAME # Type # "_POST")
9222                       GPR64sp:$Rn,
9223                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9224                       idxtype:$idx, XZR), 0>;
9225
9226   // E.g. "ld1.8b { v0 }[0], [x1]"
9227   //      "ld1.8b\t$Vt, [$Rn]"
9228   // may get mapped to
9229   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9230   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9231                       (!cast<Instruction>(NAME # Type)
9232                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9233                          idxtype:$idx, GPR64sp:$Rn), 0>;
9234
9235   // E.g. "ld1.8b { v0 }[0], [x1], x2"
9236   //      "ld1.8b\t$Vt, [$Rn], $Xm"
9237   // may get mapped to
9238   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9239   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9240                       (!cast<Instruction>(NAME # Type # "_POST")
9241                          GPR64sp:$Rn,
9242                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9243                          idxtype:$idx,
9244                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9245 }
9246
9247 multiclass SIMDLdSt1SingleAliases<string asm> {
9248   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
9249   defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9250   defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9251   defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9252 }
9253
9254 multiclass SIMDLdSt2SingleAliases<string asm> {
9255   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
9256   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
9257   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
9258   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9259 }
9260
9261 multiclass SIMDLdSt3SingleAliases<string asm> {
9262   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
9263   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
9264   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9265   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9266 }
9267
9268 multiclass SIMDLdSt4SingleAliases<string asm> {
9269   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
9270   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
9271   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9272   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9273 }
9274 } // end of 'let Predicates = [HasNEON]'
9275
9276 //----------------------------------------------------------------------------
9277 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9278 //----------------------------------------------------------------------------
9279
9280 let Predicates = [HasNEON, HasRDM] in {
9281
9282 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9283                                     RegisterOperand regtype, string asm, 
9284                                     string kind, list<dag> pattern>
9285   : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 
9286                                 pattern> {
9287 }
9288 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9289                                              SDPatternOperator Accum> {
9290   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9291     [(set (v4i16 V64:$dst),
9292           (Accum (v4i16 V64:$Rd),
9293                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9294                                                    (v4i16 V64:$Rm)))))]>;         
9295   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
9296     [(set (v8i16 V128:$dst),
9297           (Accum (v8i16 V128:$Rd),
9298                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
9299                                                    (v8i16 V128:$Rm)))))]>;
9300   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
9301     [(set (v2i32 V64:$dst),
9302           (Accum (v2i32 V64:$Rd),
9303                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
9304                                                    (v2i32 V64:$Rm)))))]>;
9305   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
9306     [(set (v4i32 V128:$dst),
9307           (Accum (v4i32 V128:$Rd),
9308                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
9309                                                    (v4i32 V128:$Rm)))))]>;
9310 }
9311
9312 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
9313                                      SDPatternOperator Accum> {
9314   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9315                                           V64, V64, V128_lo, VectorIndexH,
9316                                           asm, ".4h", ".4h", ".4h", ".h",
9317     [(set (v4i16 V64:$dst),
9318           (Accum (v4i16 V64:$Rd),
9319                  (v4i16 (int_aarch64_neon_sqrdmulh
9320                           (v4i16 V64:$Rn),
9321                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9322                                                     VectorIndexH:$idx))))))]> {
9323     bits<3> idx;
9324     let Inst{11} = idx{2};
9325     let Inst{21} = idx{1};
9326     let Inst{20} = idx{0};
9327   }
9328
9329   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9330                                           V128, V128, V128_lo, VectorIndexH,
9331                                           asm, ".8h", ".8h", ".8h", ".h",
9332     [(set (v8i16 V128:$dst),
9333           (Accum (v8i16 V128:$Rd),
9334                  (v8i16 (int_aarch64_neon_sqrdmulh
9335                           (v8i16 V128:$Rn),
9336                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9337                                                    VectorIndexH:$idx))))))]> {
9338     bits<3> idx;
9339     let Inst{11} = idx{2};
9340     let Inst{21} = idx{1};
9341     let Inst{20} = idx{0};
9342   }
9343
9344   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9345                                           V64, V64, V128, VectorIndexS,
9346                                           asm, ".2s", ".2s", ".2s", ".s",
9347     [(set (v2i32 V64:$dst),
9348         (Accum (v2i32 V64:$Rd),
9349                (v2i32 (int_aarch64_neon_sqrdmulh
9350                         (v2i32 V64:$Rn),
9351                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
9352                                                  VectorIndexS:$idx))))))]> {
9353     bits<2> idx;
9354     let Inst{11} = idx{1};
9355     let Inst{21} = idx{0};
9356   }
9357
9358   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 
9359   // an intermediate EXTRACT_SUBREG would be untyped.
9360   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 
9361   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
9362   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9363                        (i32 (vector_extract 
9364                                (v4i32 (insert_subvector
9365                                        (undef), 
9366                                         (v2i32 (int_aarch64_neon_sqrdmulh 
9367                                                  (v2i32 V64:$Rn),
9368                                                  (v2i32 (AArch64duplane32 
9369                                                           (v4i32 V128:$Rm),
9370                                                           VectorIndexS:$idx)))),
9371                                       (i32 0))),
9372                                (i64 0))))),
9373             (EXTRACT_SUBREG
9374                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
9375                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 
9376                                                 FPR32Op:$Rd, 
9377                                                 ssub)), 
9378                           V64:$Rn,
9379                           V128:$Rm, 
9380                           VectorIndexS:$idx)),
9381                 ssub)>;
9382
9383   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9384                                           V128, V128, V128, VectorIndexS,
9385                                           asm, ".4s", ".4s", ".4s", ".s",
9386     [(set (v4i32 V128:$dst),
9387           (Accum (v4i32 V128:$Rd),
9388                  (v4i32 (int_aarch64_neon_sqrdmulh
9389                           (v4i32 V128:$Rn),
9390                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
9391                                                    VectorIndexS:$idx))))))]> {
9392     bits<2> idx;
9393     let Inst{11} = idx{1};
9394     let Inst{21} = idx{0};
9395   }
9396
9397   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9398   // an intermediate EXTRACT_SUBREG would be untyped.
9399   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9400                         (i32 (vector_extract 
9401                                (v4i32 (int_aarch64_neon_sqrdmulh 
9402                                         (v4i32 V128:$Rn),
9403                                         (v4i32 (AArch64duplane32 
9404                                                  (v4i32 V128:$Rm),
9405                                                  VectorIndexS:$idx)))),
9406                                (i64 0))))),
9407             (EXTRACT_SUBREG
9408                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
9409                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 
9410                                                FPR32Op:$Rd, 
9411                                                ssub)), 
9412                          V128:$Rn,
9413                          V128:$Rm, 
9414                          VectorIndexS:$idx)),
9415                 ssub)>;
9416
9417   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9418                                         FPR16Op, FPR16Op, V128_lo,
9419                                         VectorIndexH, asm, ".h", "", "", ".h", 
9420                                         []> {
9421     bits<3> idx;
9422     let Inst{11} = idx{2};
9423     let Inst{21} = idx{1};
9424     let Inst{20} = idx{0};
9425   }
9426
9427   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9428                                         FPR32Op, FPR32Op, V128, VectorIndexS,
9429                                         asm, ".s", "", "", ".s",
9430     [(set (i32 FPR32Op:$dst),
9431           (Accum (i32 FPR32Op:$Rd),
9432                  (i32 (int_aarch64_neon_sqrdmulh
9433                         (i32 FPR32Op:$Rn),
9434                         (i32 (vector_extract (v4i32 V128:$Rm),
9435                                              VectorIndexS:$idx))))))]> {
9436     bits<2> idx;
9437     let Inst{11} = idx{1};
9438     let Inst{21} = idx{0};
9439   }
9440 }
9441 } // let Predicates = [HasNeon, HasRDM]
9442
9443 //----------------------------------------------------------------------------
9444 // ARMv8.3 Complex ADD/MLA instructions
9445 //----------------------------------------------------------------------------
9446
9447 class ComplexRotationOperand<int Angle, int Remainder, string Type>
9448   : AsmOperandClass {
9449   let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
9450   let DiagnosticType = "InvalidComplexRotation" # Type;
9451   let Name = "ComplexRotation" # Type;
9452 }
9453 def complexrotateop : Operand<i32> {
9454   let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
9455   let PrintMethod = "printComplexRotationOp<90, 0>";
9456 }
9457 def complexrotateopodd : Operand<i32> {
9458   let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
9459   let PrintMethod = "printComplexRotationOp<180, 90>";
9460 }
9461
9462 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9463 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
9464                                      RegisterOperand regtype, Operand rottype,
9465                                      string asm, string kind, list<dag> pattern>
9466   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9467       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9468       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
9469     Sched<[WriteV]> {
9470   bits<5> Rd;
9471   bits<5> Rn;
9472   bits<5> Rm;
9473   bits<1> rot;
9474   let Inst{31}    = 0;
9475   let Inst{30}    = Q;
9476   let Inst{29}    = U;
9477   let Inst{28-24} = 0b01110;
9478   let Inst{23-22} = size;
9479   let Inst{21}    = 0;
9480   let Inst{20-16} = Rm;
9481   let Inst{15-13} = opcode;
9482   // Non-tied version (FCADD) only has one rotation bit
9483   let Inst{12}    = rot;
9484   let Inst{11}    = 0;
9485   let Inst{10}    = 1;
9486   let Inst{9-5}   = Rn;
9487   let Inst{4-0}   = Rd;
9488 }
9489
9490 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
9491                                           string asm, SDPatternOperator OpNode>{
9492   let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9493   def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
9494               asm, ".4h",
9495               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9496                                               (v4f16 V64:$Rn),
9497                                               (v4f16 V64:$Rm),
9498                                               (rottype i32:$rot)))]>;
9499
9500   def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
9501               asm, ".8h",
9502               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9503                                                (v8f16 V128:$Rn),
9504                                                (v8f16 V128:$Rm),
9505                                                (rottype i32:$rot)))]>;
9506   }
9507
9508   let Predicates = [HasV8_3a, HasNEON] in {
9509   def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
9510               asm, ".2s",
9511               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9512                                               (v2f32 V64:$Rn),
9513                                               (v2f32 V64:$Rm),
9514                                               (rottype i32:$rot)))]>;
9515
9516   def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
9517               asm, ".4s",
9518               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9519                                                (v4f32 V128:$Rn),
9520                                                (v4f32 V128:$Rm),
9521                                                (rottype i32:$rot)))]>;
9522
9523   def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
9524               asm, ".2d",
9525               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9526                                                (v2f64 V128:$Rn),
9527                                                (v2f64 V128:$Rm),
9528                                                (rottype i32:$rot)))]>;
9529   }
9530 }
9531
9532 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9533 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
9534                                          bits<3> opcode,
9535                                          RegisterOperand regtype,
9536                                          Operand rottype, string asm,
9537                                          string kind, list<dag> pattern>
9538   : I<(outs regtype:$dst),
9539       (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9540       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9541       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
9542     Sched<[WriteV]> {
9543   bits<5> Rd;
9544   bits<5> Rn;
9545   bits<5> Rm;
9546   bits<2> rot;
9547   let Inst{31}    = 0;
9548   let Inst{30}    = Q;
9549   let Inst{29}    = U;
9550   let Inst{28-24} = 0b01110;
9551   let Inst{23-22} = size;
9552   let Inst{21}    = 0;
9553   let Inst{20-16} = Rm;
9554   let Inst{15-13} = opcode;
9555   let Inst{12-11} = rot;
9556   let Inst{10}    = 1;
9557   let Inst{9-5}   = Rn;
9558   let Inst{4-0}   = Rd;
9559 }
9560
9561 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
9562                                              Operand rottype, string asm,
9563                                              SDPatternOperator OpNode> {
9564   let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9565   def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
9566               rottype, asm, ".4h",
9567               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9568                                               (v4f16 V64:$Rn),
9569                                               (v4f16 V64:$Rm),
9570                                               (rottype i32:$rot)))]>;
9571
9572   def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
9573               rottype, asm, ".8h",
9574               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9575                                                (v8f16 V128:$Rn),
9576                                                (v8f16 V128:$Rm),
9577                                                (rottype i32:$rot)))]>;
9578   }
9579
9580   let Predicates = [HasV8_3a, HasNEON] in {
9581   def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
9582               rottype, asm, ".2s",
9583               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9584                                               (v2f32 V64:$Rn),
9585                                               (v2f32 V64:$Rm),
9586                                               (rottype i32:$rot)))]>;
9587
9588   def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
9589               rottype, asm, ".4s",
9590               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9591                                                (v4f32 V128:$Rn),
9592                                                (v4f32 V128:$Rm),
9593                                                (rottype i32:$rot)))]>;
9594
9595   def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
9596               rottype, asm, ".2d",
9597               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9598                                                (v2f64 V128:$Rn),
9599                                                (v2f64 V128:$Rm),
9600                                                (rottype i32:$rot)))]>;
9601   }
9602 }
9603
9604 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9605 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
9606                                  bit opc1, bit opc2, RegisterOperand dst_reg,
9607                                  RegisterOperand lhs_reg,
9608                                  RegisterOperand rhs_reg, Operand vec_idx,
9609                                  Operand rottype, string asm, string apple_kind,
9610                                  string dst_kind, string lhs_kind,
9611                                  string rhs_kind, list<dag> pattern>
9612   : I<(outs dst_reg:$dst),
9613       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
9614       asm,
9615       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
9616       "$idx, $rot" # "|" # apple_kind #
9617       "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
9618     Sched<[WriteV]> {
9619   bits<5> Rd;
9620   bits<5> Rn;
9621   bits<5> Rm;
9622   bits<2> rot;
9623
9624   let Inst{31}    = 0;
9625   let Inst{30}    = Q;
9626   let Inst{29}    = U;
9627   let Inst{28}    = Scalar;
9628   let Inst{27-24} = 0b1111;
9629   let Inst{23-22} = size;
9630   // Bit 21 must be set by the derived class.
9631   let Inst{20-16} = Rm;
9632   let Inst{15}    = opc1;
9633   let Inst{14-13} = rot;
9634   let Inst{12}    = opc2;
9635   // Bit 11 must be set by the derived class.
9636   let Inst{10}    = 0;
9637   let Inst{9-5}   = Rn;
9638   let Inst{4-0}   = Rd;
9639 }
9640
9641 // The complex instructions index by pairs of elements, so the VectorIndexes
9642 // don't match the lane types, and the index bits are different to the other
9643 // classes.
9644 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
9645                                      string asm, SDPatternOperator OpNode> {
9646   let Predicates = [HasV8_3a,HasNEON,HasFullFP16] in {
9647   def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
9648                       V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
9649                       ".4h", ".h", []> {
9650     bits<1> idx;
9651     let Inst{11} = 0;
9652     let Inst{21} = idx{0};
9653   }
9654
9655   def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
9656                       V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
9657                       ".8h", ".8h", ".h", []> {
9658     bits<2> idx;
9659     let Inst{11} = idx{1};
9660     let Inst{21} = idx{0};
9661   }
9662   } // Predicates = [HasV8_3a,HasNEON,HasFullFP16]
9663
9664   let Predicates = [HasV8_3a,HasNEON] in {
9665   def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
9666                       V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
9667                       ".4s", ".4s", ".s", []> {
9668     bits<1> idx;
9669     let Inst{11} = idx{0};
9670     let Inst{21} = 0;
9671   }
9672   } // Predicates = [HasV8_3a,HasNEON]
9673 }
9674
9675 //----------------------------------------------------------------------------
9676 // Crypto extensions
9677 //----------------------------------------------------------------------------
9678
9679 let Predicates = [HasCrypto] in {
9680 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9681 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
9682               list<dag> pat>
9683   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
9684     Sched<[WriteV]>{
9685   bits<5> Rd;
9686   bits<5> Rn;
9687   let Inst{31-16} = 0b0100111000101000;
9688   let Inst{15-12} = opc;
9689   let Inst{11-10} = 0b10;
9690   let Inst{9-5}   = Rn;
9691   let Inst{4-0}   = Rd;
9692 }
9693
9694 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9695   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9696             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9697
9698 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9699   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9700             "$Rd = $dst",
9701             [(set (v16i8 V128:$dst),
9702                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9703
9704 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9705 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9706                      dag oops, dag iops, list<dag> pat>
9707   : I<oops, iops, asm,
9708       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9709       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9710     Sched<[WriteV]>{
9711   bits<5> Rd;
9712   bits<5> Rn;
9713   bits<5> Rm;
9714   let Inst{31-21} = 0b01011110000;
9715   let Inst{20-16} = Rm;
9716   let Inst{15}    = 0;
9717   let Inst{14-12} = opc;
9718   let Inst{11-10} = 0b00;
9719   let Inst{9-5}   = Rn;
9720   let Inst{4-0}   = Rd;
9721 }
9722
9723 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9724   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9725                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9726                    [(set (v4i32 FPR128:$dst),
9727                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9728                                  (v4i32 V128:$Rm)))]>;
9729
9730 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9731   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9732                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
9733                    [(set (v4i32 V128:$dst),
9734                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9735                                  (v4i32 V128:$Rm)))]>;
9736
9737 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9738   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9739                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
9740                    [(set (v4i32 FPR128:$dst),
9741                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
9742                                  (v4i32 V128:$Rm)))]>;
9743
9744 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9745 class SHA2OpInst<bits<4> opc, string asm, string kind,
9746                  string cstr, dag oops, dag iops,
9747                  list<dag> pat>
9748   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
9749                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
9750     Sched<[WriteV]>{
9751   bits<5> Rd;
9752   bits<5> Rn;
9753   let Inst{31-16} = 0b0101111000101000;
9754   let Inst{15-12} = opc;
9755   let Inst{11-10} = 0b10;
9756   let Inst{9-5}   = Rn;
9757   let Inst{4-0}   = Rd;
9758 }
9759
9760 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
9761   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
9762                (ins V128:$Rd, V128:$Rn),
9763                [(set (v4i32 V128:$dst),
9764                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
9765
9766 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
9767   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
9768                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
9769 } // end of 'let Predicates = [HasCrypto]'
9770
9771 //----------------------------------------------------------------------------
9772 // v8.1 atomic instructions extension:
9773 // * CAS
9774 // * CASP
9775 // * SWP
9776 // * LDOPregister<OP>, and aliases STOPregister<OP>
9777
9778 // Instruction encodings:
9779 //
9780 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
9781 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
9782 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
9783 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
9784 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
9785 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
9786
9787 // Instruction syntax:
9788 //
9789 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9790 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
9791 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
9792 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
9793 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9794 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
9795 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9796 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
9797 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
9798 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
9799
9800 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9801 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
9802                       string cstr, list<dag> pattern>
9803       : I<oops, iops, asm, operands, cstr, pattern> {
9804   bits<2> Sz;
9805   bit NP;
9806   bit Acq;
9807   bit Rel;
9808   bits<5> Rs;
9809   bits<5> Rn;
9810   bits<5> Rt;
9811   let Inst{31-30} = Sz;
9812   let Inst{29-24} = 0b001000;
9813   let Inst{23} = NP;
9814   let Inst{22} = Acq;
9815   let Inst{21} = 0b1;
9816   let Inst{20-16} = Rs;
9817   let Inst{15} = Rel;
9818   let Inst{14-10} = 0b11111;
9819   let Inst{9-5} = Rn;
9820   let Inst{4-0} = Rt;
9821   let Predicates = [HasLSE];
9822 }
9823
9824 class BaseCAS<string order, string size, RegisterClass RC>
9825       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9826                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
9827                         "$out = $Rs",[]>,
9828         Sched<[WriteAtomic]> {
9829   let NP = 1;
9830 }
9831
9832 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
9833   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
9834   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
9835   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
9836   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
9837 }
9838
9839 class BaseCASP<string order, string size, RegisterOperand RC>
9840       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9841                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
9842                         "$out = $Rs",[]>,
9843         Sched<[WriteAtomic]> {
9844   let NP = 0;
9845 }
9846
9847 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9848   let Sz = 0b00, Acq = Acq, Rel = Rel in
9849     def W : BaseCASP<order, "", WSeqPairClassOperand>;
9850   let Sz = 0b01, Acq = Acq, Rel = Rel in
9851     def X : BaseCASP<order, "", XSeqPairClassOperand>;
9852 }
9853
9854 let Predicates = [HasLSE] in
9855 class BaseSWP<string order, string size, RegisterClass RC>
9856       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9857           "\t$Rs, $Rt, [$Rn]","",[]>,
9858         Sched<[WriteAtomic]> {
9859   bits<2> Sz;
9860   bit Acq;
9861   bit Rel;
9862   bits<5> Rs;
9863   bits<3> opc = 0b000;
9864   bits<5> Rn;
9865   bits<5> Rt;
9866   let Inst{31-30} = Sz;
9867   let Inst{29-24} = 0b111000;
9868   let Inst{23} = Acq;
9869   let Inst{22} = Rel;
9870   let Inst{21} = 0b1;
9871   let Inst{20-16} = Rs;
9872   let Inst{15} = 0b1;
9873   let Inst{14-12} = opc;
9874   let Inst{11-10} = 0b00;
9875   let Inst{9-5} = Rn;
9876   let Inst{4-0} = Rt;
9877   let Predicates = [HasLSE];
9878 }
9879
9880 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9881   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
9882   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
9883   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
9884   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
9885 }
9886
9887 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9888 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9889       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9890           "\t$Rs, $Rt, [$Rn]","",[]>,
9891         Sched<[WriteAtomic]> {
9892   bits<2> Sz;
9893   bit Acq;
9894   bit Rel;
9895   bits<5> Rs;
9896   bits<3> opc;
9897   bits<5> Rn;
9898   bits<5> Rt;
9899   let Inst{31-30} = Sz;
9900   let Inst{29-24} = 0b111000;
9901   let Inst{23} = Acq;
9902   let Inst{22} = Rel;
9903   let Inst{21} = 0b1;
9904   let Inst{20-16} = Rs;
9905   let Inst{15} = 0b0;
9906   let Inst{14-12} = opc;
9907   let Inst{11-10} = 0b00;
9908   let Inst{9-5} = Rn;
9909   let Inst{4-0} = Rt;
9910   let Predicates = [HasLSE];
9911 }
9912
9913 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 
9914                         string order> {
9915   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9916     def B : BaseLDOPregister<op, order, "b", GPR32>;
9917   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9918     def H : BaseLDOPregister<op, order, "h", GPR32>;
9919   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9920     def W : BaseLDOPregister<op, order, "", GPR32>;
9921   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9922     def X : BaseLDOPregister<op, order, "", GPR64>;
9923 }
9924
9925 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
9926 // complex DAG for DstRHS.
9927 let Predicates = [HasLSE] in
9928 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
9929                                          string size, dag SrcRHS, dag DstRHS> {
9930   def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
9931             (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
9932   def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
9933             (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
9934   def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
9935             (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
9936   def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
9937             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
9938   def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
9939             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
9940 }
9941
9942 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
9943                                      string size, dag RHS> {
9944   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
9945 }
9946
9947 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
9948                                          string size, dag LHS, dag RHS> {
9949   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
9950 }
9951
9952 multiclass LDOPregister_patterns<string inst, string op> {
9953   defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
9954   defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
9955   defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
9956   defm : LDOPregister_patterns_ord<inst, "B", op, "8",  (i32 GPR32:$Rm)>;
9957 }
9958
9959 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
9960   defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
9961                         (i64 GPR64:$Rm),
9962                         (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
9963   defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
9964                         (i32 GPR32:$Rm),
9965                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
9966   defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
9967                         (i32 GPR32:$Rm),
9968                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
9969   defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
9970                         (i32 GPR32:$Rm),
9971                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
9972 }
9973
9974 let Predicates = [HasLSE] in
9975 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
9976                                         string size, dag OLD, dag NEW> {
9977   def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
9978             (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
9979   def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
9980             (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9981   def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
9982             (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9983   def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
9984             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9985   def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
9986             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9987 }
9988
9989 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
9990                                     string size, dag OLD, dag NEW> {
9991   defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
9992 }
9993
9994 multiclass CASregister_patterns<string inst, string op> {
9995   defm : CASregister_patterns_ord<inst, "X", op, "64",
9996                         (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
9997   defm : CASregister_patterns_ord<inst, "W", op, "32",
9998                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
9999   defm : CASregister_patterns_ord<inst, "H", op, "16",
10000                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10001   defm : CASregister_patterns_ord<inst, "B", op, "8",
10002                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10003 }
10004
10005 let Predicates = [HasLSE] in
10006 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
10007                         Instruction inst> :
10008       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
10009
10010 multiclass STOPregister<string asm, string instr> {
10011   def : BaseSTOPregister<asm # "lb", GPR32, WZR,
10012                     !cast<Instruction>(instr # "LB")>;
10013   def : BaseSTOPregister<asm # "lh", GPR32, WZR,
10014                     !cast<Instruction>(instr # "LH")>;
10015   def : BaseSTOPregister<asm # "l",  GPR32, WZR,
10016                     !cast<Instruction>(instr # "LW")>;
10017   def : BaseSTOPregister<asm # "l",  GPR64, XZR,
10018                     !cast<Instruction>(instr # "LX")>;
10019   def : BaseSTOPregister<asm # "b",  GPR32, WZR,
10020                     !cast<Instruction>(instr # "B")>;
10021   def : BaseSTOPregister<asm # "h",  GPR32, WZR,
10022                     !cast<Instruction>(instr # "H")>;
10023   def : BaseSTOPregister<asm,        GPR32, WZR,
10024                     !cast<Instruction>(instr # "W")>;
10025   def : BaseSTOPregister<asm,        GPR64, XZR,
10026                     !cast<Instruction>(instr # "X")>;
10027 }
10028
10029 //----------------------------------------------------------------------------
10030 // Allow the size specifier tokens to be upper case, not just lower.
10031 def : TokenAlias<".4B", ".4b">;  // Add dot product
10032 def : TokenAlias<".8B", ".8b">;
10033 def : TokenAlias<".4H", ".4h">;
10034 def : TokenAlias<".2S", ".2s">;
10035 def : TokenAlias<".1D", ".1d">;
10036 def : TokenAlias<".16B", ".16b">;
10037 def : TokenAlias<".8H", ".8h">;
10038 def : TokenAlias<".4S", ".4s">;
10039 def : TokenAlias<".2D", ".2d">;
10040 def : TokenAlias<".1Q", ".1q">;
10041 def : TokenAlias<".2H", ".2h">;
10042 def : TokenAlias<".B", ".b">;
10043 def : TokenAlias<".H", ".h">;
10044 def : TokenAlias<".S", ".s">;
10045 def : TokenAlias<".D", ".d">;
10046 def : TokenAlias<".Q", ".q">;