]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrFormats.td
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / AArch64 / AArch64InstrFormats.td
1 //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 //===----------------------------------------------------------------------===//
10 //  Describe AArch64 instructions format here
11 //
12
13 // Format specifies the encoding used by the instruction.  This is part of the
14 // ad-hoc solution used to emit machine instruction encodings by our machine
15 // code emitter.
16 class Format<bits<2> val> {
17   bits<2> Value = val;
18 }
19
20 def PseudoFrm   : Format<0>;
21 def NormalFrm   : Format<1>; // Do we need any others?
22
23 // Enum describing whether an instruction is
24 // destructive in its first source operand.
25 class DestructiveInstTypeEnum<bits<4> val> {
26   bits<4> Value = val;
27 }
28 def NotDestructive                : DestructiveInstTypeEnum<0>;
29 // Destructive in its first operand and can be MOVPRFX'd, but has no other
30 // special properties.
31 def DestructiveOther              : DestructiveInstTypeEnum<1>;
32 def DestructiveUnary              : DestructiveInstTypeEnum<2>;
33 def DestructiveBinaryImm          : DestructiveInstTypeEnum<3>;
34 def DestructiveBinaryShImmUnpred  : DestructiveInstTypeEnum<4>;
35 def DestructiveBinary             : DestructiveInstTypeEnum<5>;
36 def DestructiveBinaryComm         : DestructiveInstTypeEnum<6>;
37 def DestructiveBinaryCommWithRev  : DestructiveInstTypeEnum<7>;
38 def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>;
39
40 class FalseLanesEnum<bits<2> val> {
41   bits<2> Value = val;
42 }
43 def FalseLanesNone  : FalseLanesEnum<0>;
44 def FalseLanesZero  : FalseLanesEnum<1>;
45 def FalseLanesUndef : FalseLanesEnum<2>;
46
47 // AArch64 Instruction Format
48 class AArch64Inst<Format f, string cstr> : Instruction {
49   field bits<32> Inst; // Instruction encoding.
50   // Mask of bits that cause an encoding to be UNPREDICTABLE.
51   // If a bit is set, then if the corresponding bit in the
52   // target encoding differs from its value in the "Inst" field,
53   // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
54   field bits<32> Unpredictable = 0;
55   // SoftFail is the generic name for this field, but we alias it so
56   // as to make it more obvious what it means in ARM-land.
57   field bits<32> SoftFail = Unpredictable;
58   let Namespace   = "AArch64";
59   Format F        = f;
60   bits<2> Form    = F.Value;
61
62   // Defaults
63   FalseLanesEnum FalseLanes = FalseLanesNone;
64   DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
65   ElementSizeEnum ElementSize = ElementSizeNone;
66
67   let TSFlags{8-7} = FalseLanes.Value;
68   let TSFlags{6-3} = DestructiveInstType.Value;
69   let TSFlags{2-0} = ElementSize.Value;
70
71   let Pattern     = [];
72   let Constraints = cstr;
73 }
74
75 class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
76   : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
77
78 // Pseudo instructions (don't have encoding information)
79 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
80     : AArch64Inst<PseudoFrm, cstr> {
81   dag OutOperandList = oops;
82   dag InOperandList  = iops;
83   let Pattern        = pattern;
84   let isCodeGenOnly  = 1;
85   let isPseudo       = 1;
86 }
87
88 // Real instructions (have encoding information)
89 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
90   let Pattern = pattern;
91   let Size = 4;
92 }
93
94 // Normal instructions
95 class I<dag oops, dag iops, string asm, string operands, string cstr,
96         list<dag> pattern>
97     : EncodedI<cstr, pattern> {
98   dag OutOperandList = oops;
99   dag InOperandList  = iops;
100   let AsmString      = !strconcat(asm, operands);
101 }
102
103 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
104 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
105 class UnOpFrag<dag res>  : PatFrag<(ops node:$LHS), res>;
106
107 // Helper fragment for an extract of the high portion of a 128-bit vector.
108 def extract_high_v16i8 :
109    UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
110 def extract_high_v8i16 :
111    UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
112 def extract_high_v4i32 :
113    UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
114 def extract_high_v2i64 :
115    UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
116
117 //===----------------------------------------------------------------------===//
118 // Asm Operand Classes.
119 //
120
121 // Shifter operand for arithmetic shifted encodings.
122 def ShifterOperand : AsmOperandClass {
123   let Name = "Shifter";
124 }
125
126 // Shifter operand for mov immediate encodings.
127 def MovImm32ShifterOperand : AsmOperandClass {
128   let SuperClasses = [ShifterOperand];
129   let Name = "MovImm32Shifter";
130   let RenderMethod = "addShifterOperands";
131   let DiagnosticType = "InvalidMovImm32Shift";
132 }
133 def MovImm64ShifterOperand : AsmOperandClass {
134   let SuperClasses = [ShifterOperand];
135   let Name = "MovImm64Shifter";
136   let RenderMethod = "addShifterOperands";
137   let DiagnosticType = "InvalidMovImm64Shift";
138 }
139
140 // Shifter operand for arithmetic register shifted encodings.
141 class ArithmeticShifterOperand<int width> : AsmOperandClass {
142   let SuperClasses = [ShifterOperand];
143   let Name = "ArithmeticShifter" # width;
144   let PredicateMethod = "isArithmeticShifter<" # width # ">";
145   let RenderMethod = "addShifterOperands";
146   let DiagnosticType = "AddSubRegShift" # width;
147 }
148
149 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
150 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
151
152 // Shifter operand for logical register shifted encodings.
153 class LogicalShifterOperand<int width> : AsmOperandClass {
154   let SuperClasses = [ShifterOperand];
155   let Name = "LogicalShifter" # width;
156   let PredicateMethod = "isLogicalShifter<" # width # ">";
157   let RenderMethod = "addShifterOperands";
158   let DiagnosticType = "AddSubRegShift" # width;
159 }
160
161 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
162 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
163
164 // Shifter operand for logical vector 128/64-bit shifted encodings.
165 def LogicalVecShifterOperand : AsmOperandClass {
166   let SuperClasses = [ShifterOperand];
167   let Name = "LogicalVecShifter";
168   let RenderMethod = "addShifterOperands";
169 }
170 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
171   let SuperClasses = [LogicalVecShifterOperand];
172   let Name = "LogicalVecHalfWordShifter";
173   let RenderMethod = "addShifterOperands";
174 }
175
176 // The "MSL" shifter on the vector MOVI instruction.
177 def MoveVecShifterOperand : AsmOperandClass {
178   let SuperClasses = [ShifterOperand];
179   let Name = "MoveVecShifter";
180   let RenderMethod = "addShifterOperands";
181 }
182
183 // Extend operand for arithmetic encodings.
184 def ExtendOperand : AsmOperandClass {
185   let Name = "Extend";
186   let DiagnosticType = "AddSubRegExtendLarge";
187 }
188 def ExtendOperand64 : AsmOperandClass {
189   let SuperClasses = [ExtendOperand];
190   let Name = "Extend64";
191   let DiagnosticType = "AddSubRegExtendSmall";
192 }
193 // 'extend' that's a lsl of a 64-bit register.
194 def ExtendOperandLSL64 : AsmOperandClass {
195   let SuperClasses = [ExtendOperand];
196   let Name = "ExtendLSL64";
197   let RenderMethod = "addExtend64Operands";
198   let DiagnosticType = "AddSubRegExtendLarge";
199 }
200
201 // 8-bit floating-point immediate encodings.
202 def FPImmOperand : AsmOperandClass {
203   let Name = "FPImm";
204   let ParserMethod = "tryParseFPImm<true>";
205   let DiagnosticType = "InvalidFPImm";
206 }
207
208 def CondCode : AsmOperandClass {
209   let Name = "CondCode";
210   let DiagnosticType = "InvalidCondCode";
211 }
212
213 // A 32-bit register pasrsed as 64-bit
214 def GPR32as64Operand : AsmOperandClass {
215   let Name = "GPR32as64";
216   let ParserMethod =
217       "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";
218 }
219 def GPR32as64 : RegisterOperand<GPR32> {
220   let ParserMatchClass = GPR32as64Operand;
221 }
222
223 // A 64-bit register pasrsed as 32-bit
224 def GPR64as32Operand : AsmOperandClass {
225   let Name = "GPR64as32";
226   let ParserMethod =
227       "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";
228 }
229 def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {
230   let ParserMatchClass = GPR64as32Operand;
231 }
232
233 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
234 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
235 // are encoded as the eight bit value 'abcdefgh'.
236 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
237
238 class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
239   let Name = "UImm" # Width # "s" # Scale;
240   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;
241   let RenderMethod = "addImmScaledOperands<" # Scale # ">";
242   let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";
243 }
244
245 class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
246   let Name = "SImm" # Width # "s" # Scale;
247   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;
248   let RenderMethod = "addImmScaledOperands<" # Scale # ">";
249   let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";
250 }
251
252 //===----------------------------------------------------------------------===//
253 // Operand Definitions.
254 //
255
256 // ADR[P] instruction labels.
257 def AdrpOperand : AsmOperandClass {
258   let Name = "AdrpLabel";
259   let ParserMethod = "tryParseAdrpLabel";
260   let DiagnosticType = "InvalidLabel";
261 }
262 def adrplabel : Operand<i64> {
263   let EncoderMethod = "getAdrLabelOpValue";
264   let PrintMethod = "printAdrpLabel";
265   let ParserMatchClass = AdrpOperand;
266 }
267
268 def AdrOperand : AsmOperandClass {
269   let Name = "AdrLabel";
270   let ParserMethod = "tryParseAdrLabel";
271   let DiagnosticType = "InvalidLabel";
272 }
273 def adrlabel : Operand<i64> {
274   let EncoderMethod = "getAdrLabelOpValue";
275   let ParserMatchClass = AdrOperand;
276 }
277
278 class SImmOperand<int width> : AsmOperandClass {
279   let Name = "SImm" # width;
280   let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
281   let RenderMethod = "addImmOperands";
282   let PredicateMethod = "isSImm<" # width # ">";
283 }
284
285
286 class AsmImmRange<int Low, int High> : AsmOperandClass {
287   let Name = "Imm" # Low # "_" # High;
288   let DiagnosticType = "InvalidImm" # Low # "_" # High;
289   let RenderMethod = "addImmOperands";
290   let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
291 }
292
293 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
294 def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;
295 def simm10Scaled : Operand<i64> {
296   let ParserMatchClass = SImm10s8Operand;
297   let DecoderMethod = "DecodeSImm<10>";
298   let PrintMethod = "printImmScale<8>";
299 }
300
301 def simm9s16 : Operand<i64> {
302   let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;
303   let DecoderMethod = "DecodeSImm<9>";
304   let PrintMethod = "printImmScale<16>";
305 }
306
307 // uimm6 predicate - True if the immediate is in the range [0, 63].
308 def UImm6Operand : AsmOperandClass {
309   let Name = "UImm6";
310   let DiagnosticType = "InvalidImm0_63";
311 }
312
313 def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
314   let ParserMatchClass = UImm6Operand;
315 }
316
317 def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
318   let ParserMatchClass = AsmImmRange<0, 65535>;
319 }
320
321 def SImm9Operand : SImmOperand<9>;
322 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
323   let ParserMatchClass = SImm9Operand;
324   let DecoderMethod = "DecodeSImm<9>";
325 }
326
327 def SImm8Operand : SImmOperand<8>;
328 def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 127; }]> {
329   let ParserMatchClass = SImm8Operand;
330   let DecoderMethod = "DecodeSImm<8>";
331 }
332
333 def SImm6Operand : SImmOperand<6>;
334 def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
335   let ParserMatchClass = SImm6Operand;
336   let DecoderMethod = "DecodeSImm<6>";
337 }
338
339 def SImm5Operand : SImmOperand<5>;
340 def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
341   let ParserMatchClass = SImm5Operand;
342   let DecoderMethod = "DecodeSImm<5>";
343 }
344
345 def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
346   let ParserMatchClass = SImm5Operand;
347   let DecoderMethod = "DecodeSImm<5>";
348 }
349
350 def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {
351   let ParserMatchClass = SImm5Operand;
352   let DecoderMethod = "DecodeSImm<5>";
353   let PrintMethod = "printSImm<8>";
354 }
355
356 def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {
357   let ParserMatchClass = SImm5Operand;
358   let DecoderMethod = "DecodeSImm<5>";
359   let PrintMethod = "printSImm<16>";
360 }
361
362 // simm7sN predicate - True if the immediate is a multiple of N in the range
363 // [-64 * N, 63 * N].
364
365 def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;
366 def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;
367 def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
368
369 def simm7s4 : Operand<i32> {
370   let ParserMatchClass = SImm7s4Operand;
371   let PrintMethod = "printImmScale<4>";
372 }
373
374 def simm7s8 : Operand<i32> {
375   let ParserMatchClass = SImm7s8Operand;
376   let PrintMethod = "printImmScale<8>";
377 }
378
379 def simm7s16 : Operand<i32> {
380   let ParserMatchClass = SImm7s16Operand;
381   let PrintMethod = "printImmScale<16>";
382 }
383
384 def am_sve_fi : ComplexPattern<i64, 2, "SelectAddrModeFrameIndexSVE", []>;
385
386 def am_indexed7s8   : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
387 def am_indexed7s16  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
388 def am_indexed7s32  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
389 def am_indexed7s64  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
390 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
391
392 def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>;
393 def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>;
394
395 def UImmS1XForm : SDNodeXForm<imm, [{
396   return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64);
397 }]>;
398 def UImmS2XForm : SDNodeXForm<imm, [{
399   return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);
400 }]>;
401 def UImmS4XForm : SDNodeXForm<imm, [{
402   return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);
403 }]>;
404 def UImmS8XForm : SDNodeXForm<imm, [{
405   return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
406 }]>;
407
408 // uimm5sN predicate - True if the immediate is a multiple of N in the range
409 // [0 * N, 32 * N].
410 def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
411 def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;
412 def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;
413
414 def uimm5s2 : Operand<i64>, ImmLeaf<i64,
415                 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
416                 UImmS2XForm> {
417   let ParserMatchClass = UImm5s2Operand;
418   let PrintMethod = "printImmScale<2>";
419 }
420 def uimm5s4 : Operand<i64>, ImmLeaf<i64,
421                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
422                 UImmS4XForm> {
423   let ParserMatchClass = UImm5s4Operand;
424   let PrintMethod = "printImmScale<4>";
425 }
426 def uimm5s8 : Operand<i64>, ImmLeaf<i64,
427                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
428                 UImmS8XForm> {
429   let ParserMatchClass = UImm5s8Operand;
430   let PrintMethod = "printImmScale<8>";
431 }
432
433 // tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant)
434 // instead of ImmLeaf (Constant)
435 def tuimm5s2 : Operand<i64>, TImmLeaf<i64,
436                 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
437                 UImmS2XForm> {
438   let ParserMatchClass = UImm5s2Operand;
439   let PrintMethod = "printImmScale<2>";
440 }
441 def tuimm5s4 : Operand<i64>, TImmLeaf<i64,
442                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
443                 UImmS4XForm> {
444   let ParserMatchClass = UImm5s4Operand;
445   let PrintMethod = "printImmScale<4>";
446 }
447 def tuimm5s8 : Operand<i64>, TImmLeaf<i64,
448                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
449                 UImmS8XForm> {
450   let ParserMatchClass = UImm5s8Operand;
451   let PrintMethod = "printImmScale<8>";
452 }
453
454 // uimm6sN predicate - True if the immediate is a multiple of N in the range
455 // [0 * N, 64 * N].
456 def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;
457 def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;
458 def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;
459 def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;
460 def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;
461
462 def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
463   let ParserMatchClass = UImm6s1Operand;
464 }
465 def uimm6s2 : Operand<i64>, ImmLeaf<i64,
466 [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
467   let PrintMethod = "printImmScale<2>";
468   let ParserMatchClass = UImm6s2Operand;
469 }
470 def uimm6s4 : Operand<i64>, ImmLeaf<i64,
471 [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
472   let PrintMethod = "printImmScale<4>";
473   let ParserMatchClass = UImm6s4Operand;
474 }
475 def uimm6s8 : Operand<i64>, ImmLeaf<i64,
476 [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
477   let PrintMethod = "printImmScale<8>";
478   let ParserMatchClass = UImm6s8Operand;
479 }
480 def uimm6s16 : Operand<i64>, ImmLeaf<i64,
481 [{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {
482   let PrintMethod = "printImmScale<16>";
483   let ParserMatchClass = UImm6s16Operand;
484 }
485
486 def SImmS2XForm : SDNodeXForm<imm, [{
487   return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64);
488 }]>;
489 def SImmS3XForm : SDNodeXForm<imm, [{
490   return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64);
491 }]>;
492 def SImmS4XForm : SDNodeXForm<imm, [{
493   return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64);
494 }]>;
495 def SImmS16XForm : SDNodeXForm<imm, [{
496   return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64);
497 }]>;
498 def SImmS32XForm : SDNodeXForm<imm, [{
499   return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64);
500 }]>;
501
502 // simm6sN predicate - True if the immediate is a multiple of N in the range
503 // [-32 * N, 31 * N].
504 def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
505 def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
506   let ParserMatchClass = SImm6s1Operand;
507   let DecoderMethod = "DecodeSImm<6>";
508 }
509
510 // simm4sN predicate - True if the immediate is a multiple of N in the range
511 // [ -8* N, 7 * N].
512 def SImm4s1Operand  : SImmScaledMemoryIndexed<4, 1>;
513 def SImm4s2Operand  : SImmScaledMemoryIndexed<4, 2>;
514 def SImm4s3Operand  : SImmScaledMemoryIndexed<4, 3>;
515 def SImm4s4Operand  : SImmScaledMemoryIndexed<4, 4>;
516 def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
517 def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>;
518
519 def simm4s1 : Operand<i64>, ImmLeaf<i64,
520 [{ return Imm >=-8  && Imm <= 7; }]> {
521   let ParserMatchClass = SImm4s1Operand;
522   let DecoderMethod = "DecodeSImm<4>";
523 }
524
525 def simm4s2 : Operand<i64>, ImmLeaf<i64,
526 [{ return Imm >=-16  && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> {
527   let PrintMethod = "printImmScale<2>";
528   let ParserMatchClass = SImm4s2Operand;
529   let DecoderMethod = "DecodeSImm<4>";
530 }
531
532 def simm4s3 : Operand<i64>, ImmLeaf<i64,
533 [{ return Imm >=-24  && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> {
534   let PrintMethod = "printImmScale<3>";
535   let ParserMatchClass = SImm4s3Operand;
536   let DecoderMethod = "DecodeSImm<4>";
537 }
538
539 def simm4s4 : Operand<i64>, ImmLeaf<i64,
540 [{ return Imm >=-32  && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> {
541   let PrintMethod = "printImmScale<4>";
542   let ParserMatchClass = SImm4s4Operand;
543   let DecoderMethod = "DecodeSImm<4>";
544 }
545 def simm4s16 : Operand<i64>, ImmLeaf<i64,
546 [{ return Imm >=-128  && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> {
547   let PrintMethod = "printImmScale<16>";
548   let ParserMatchClass = SImm4s16Operand;
549   let DecoderMethod = "DecodeSImm<4>";
550 }
551 def simm4s32 : Operand<i64>, ImmLeaf<i64,
552 [{ return Imm >=-256  && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> {
553   let PrintMethod = "printImmScale<32>";
554   let ParserMatchClass = SImm4s32Operand;
555   let DecoderMethod = "DecodeSImm<4>";
556 }
557
558 def Imm1_8Operand : AsmImmRange<1, 8>;
559 def Imm1_16Operand : AsmImmRange<1, 16>;
560 def Imm1_32Operand : AsmImmRange<1, 32>;
561 def Imm1_64Operand : AsmImmRange<1, 64>;
562
563 class BranchTarget<int N> : AsmOperandClass {
564   let Name = "BranchTarget" # N;
565   let DiagnosticType = "InvalidLabel";
566   let PredicateMethod = "isBranchTarget<" # N # ">";
567 }
568
569 class PCRelLabel<int N> : BranchTarget<N> {
570   let Name = "PCRelLabel" # N;
571 }
572
573 def BranchTarget14Operand : BranchTarget<14>;
574 def BranchTarget26Operand : BranchTarget<26>;
575 def PCRelLabel19Operand   : PCRelLabel<19>;
576
577 def MovWSymbolG3AsmOperand : AsmOperandClass {
578   let Name = "MovWSymbolG3";
579   let RenderMethod = "addImmOperands";
580 }
581
582 def movw_symbol_g3 : Operand<i32> {
583   let ParserMatchClass = MovWSymbolG3AsmOperand;
584 }
585
586 def MovWSymbolG2AsmOperand : AsmOperandClass {
587   let Name = "MovWSymbolG2";
588   let RenderMethod = "addImmOperands";
589 }
590
591 def movw_symbol_g2 : Operand<i32> {
592   let ParserMatchClass = MovWSymbolG2AsmOperand;
593 }
594
595 def MovWSymbolG1AsmOperand : AsmOperandClass {
596   let Name = "MovWSymbolG1";
597   let RenderMethod = "addImmOperands";
598 }
599
600 def movw_symbol_g1 : Operand<i32> {
601   let ParserMatchClass = MovWSymbolG1AsmOperand;
602 }
603
604 def MovWSymbolG0AsmOperand : AsmOperandClass {
605   let Name = "MovWSymbolG0";
606   let RenderMethod = "addImmOperands";
607 }
608
609 def movw_symbol_g0 : Operand<i32> {
610   let ParserMatchClass = MovWSymbolG0AsmOperand;
611 }
612
613 class fixedpoint_i32<ValueType FloatVT>
614   : Operand<FloatVT>,
615     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
616   let EncoderMethod = "getFixedPointScaleOpValue";
617   let DecoderMethod = "DecodeFixedPointScaleImm32";
618   let ParserMatchClass = Imm1_32Operand;
619 }
620
621 class fixedpoint_i64<ValueType FloatVT>
622   : Operand<FloatVT>,
623     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
624   let EncoderMethod = "getFixedPointScaleOpValue";
625   let DecoderMethod = "DecodeFixedPointScaleImm64";
626   let ParserMatchClass = Imm1_64Operand;
627 }
628
629 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
630 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
631 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
632
633 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
634 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
635 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
636
637 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
638   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
639 }]> {
640   let EncoderMethod = "getVecShiftR8OpValue";
641   let DecoderMethod = "DecodeVecShiftR8Imm";
642   let ParserMatchClass = Imm1_8Operand;
643 }
644 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
645   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
646 }]> {
647   let EncoderMethod = "getVecShiftR16OpValue";
648   let DecoderMethod = "DecodeVecShiftR16Imm";
649   let ParserMatchClass = Imm1_16Operand;
650 }
651 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
652   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
653 }]> {
654   let EncoderMethod = "getVecShiftR16OpValue";
655   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
656   let ParserMatchClass = Imm1_8Operand;
657 }
658 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
659   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
660 }]> {
661   let EncoderMethod = "getVecShiftR32OpValue";
662   let DecoderMethod = "DecodeVecShiftR32Imm";
663   let ParserMatchClass = Imm1_32Operand;
664 }
665 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
666   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
667 }]> {
668   let EncoderMethod = "getVecShiftR32OpValue";
669   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
670   let ParserMatchClass = Imm1_16Operand;
671 }
672 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
673   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
674 }]> {
675   let EncoderMethod = "getVecShiftR64OpValue";
676   let DecoderMethod = "DecodeVecShiftR64Imm";
677   let ParserMatchClass = Imm1_64Operand;
678 }
679 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
680   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
681 }]> {
682   let EncoderMethod = "getVecShiftR64OpValue";
683   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
684   let ParserMatchClass = Imm1_32Operand;
685 }
686
687 // Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant
688 // (ImmLeaf)
689 def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
690   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
691 }]> {
692   let EncoderMethod = "getVecShiftR8OpValue";
693   let DecoderMethod = "DecodeVecShiftR8Imm";
694   let ParserMatchClass = Imm1_8Operand;
695 }
696 def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
697   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
698 }]> {
699   let EncoderMethod = "getVecShiftR16OpValue";
700   let DecoderMethod = "DecodeVecShiftR16Imm";
701   let ParserMatchClass = Imm1_16Operand;
702 }
703 def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
704   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
705 }]> {
706   let EncoderMethod = "getVecShiftR32OpValue";
707   let DecoderMethod = "DecodeVecShiftR32Imm";
708   let ParserMatchClass = Imm1_32Operand;
709 }
710 def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{
711   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
712 }]> {
713   let EncoderMethod = "getVecShiftR64OpValue";
714   let DecoderMethod = "DecodeVecShiftR64Imm";
715   let ParserMatchClass = Imm1_64Operand;
716 }
717
718 def Imm0_1Operand : AsmImmRange<0, 1>;
719 def Imm0_7Operand : AsmImmRange<0, 7>;
720 def Imm0_15Operand : AsmImmRange<0, 15>;
721 def Imm0_31Operand : AsmImmRange<0, 31>;
722 def Imm0_63Operand : AsmImmRange<0, 63>;
723
724 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
725   return (((uint32_t)Imm) < 8);
726 }]> {
727   let EncoderMethod = "getVecShiftL8OpValue";
728   let DecoderMethod = "DecodeVecShiftL8Imm";
729   let ParserMatchClass = Imm0_7Operand;
730 }
731 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
732   return (((uint32_t)Imm) < 16);
733 }]> {
734   let EncoderMethod = "getVecShiftL16OpValue";
735   let DecoderMethod = "DecodeVecShiftL16Imm";
736   let ParserMatchClass = Imm0_15Operand;
737 }
738 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
739   return (((uint32_t)Imm) < 32);
740 }]> {
741   let EncoderMethod = "getVecShiftL32OpValue";
742   let DecoderMethod = "DecodeVecShiftL32Imm";
743   let ParserMatchClass = Imm0_31Operand;
744 }
745 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
746   return (((uint32_t)Imm) < 64);
747 }]> {
748   let EncoderMethod = "getVecShiftL64OpValue";
749   let DecoderMethod = "DecodeVecShiftL64Imm";
750   let ParserMatchClass = Imm0_63Operand;
751 }
752
753 // Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant
754 // (ImmLeaf)
755 def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{
756   return (((uint32_t)Imm) < 8);
757 }]> {
758   let EncoderMethod = "getVecShiftL8OpValue";
759   let DecoderMethod = "DecodeVecShiftL8Imm";
760   let ParserMatchClass = Imm0_7Operand;
761 }
762 def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{
763   return (((uint32_t)Imm) < 16);
764 }]> {
765   let EncoderMethod = "getVecShiftL16OpValue";
766   let DecoderMethod = "DecodeVecShiftL16Imm";
767   let ParserMatchClass = Imm0_15Operand;
768 }
769 def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{
770   return (((uint32_t)Imm) < 32);
771 }]> {
772   let EncoderMethod = "getVecShiftL32OpValue";
773   let DecoderMethod = "DecodeVecShiftL32Imm";
774   let ParserMatchClass = Imm0_31Operand;
775 }
776 def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{
777   return (((uint32_t)Imm) < 64);
778 }]> {
779   let EncoderMethod = "getVecShiftL64OpValue";
780   let DecoderMethod = "DecodeVecShiftL64Imm";
781   let ParserMatchClass = Imm0_63Operand;
782 }
783
784 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
785 // instructions for splatting repeating bit patterns across the immediate.
786 def logical_imm32_XFORM : SDNodeXForm<imm, [{
787   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
788   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
789 }]>;
790 def logical_imm64_XFORM : SDNodeXForm<imm, [{
791   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
792   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
793 }]>;
794
795 def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">,
796   GISDNodeXFormEquiv<logical_imm32_XFORM>;
797 def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">,
798   GISDNodeXFormEquiv<logical_imm64_XFORM>;
799
800 let DiagnosticType = "LogicalSecondSource" in {
801   def LogicalImm32Operand : AsmOperandClass {
802     let Name = "LogicalImm32";
803     let PredicateMethod = "isLogicalImm<int32_t>";
804     let RenderMethod = "addLogicalImmOperands<int32_t>";
805   }
806   def LogicalImm64Operand : AsmOperandClass {
807     let Name = "LogicalImm64";
808     let PredicateMethod = "isLogicalImm<int64_t>";
809     let RenderMethod = "addLogicalImmOperands<int64_t>";
810   }
811   def LogicalImm32NotOperand : AsmOperandClass {
812     let Name = "LogicalImm32Not";
813     let PredicateMethod = "isLogicalImm<int32_t>";
814     let RenderMethod = "addLogicalImmNotOperands<int32_t>";
815   }
816   def LogicalImm64NotOperand : AsmOperandClass {
817     let Name = "LogicalImm64Not";
818     let PredicateMethod = "isLogicalImm<int64_t>";
819     let RenderMethod = "addLogicalImmNotOperands<int64_t>";
820   }
821 }
822 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
823   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
824 }], logical_imm32_XFORM> {
825   let PrintMethod = "printLogicalImm<int32_t>";
826   let ParserMatchClass = LogicalImm32Operand;
827 }
828 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
829   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
830 }], logical_imm64_XFORM> {
831   let PrintMethod = "printLogicalImm<int64_t>";
832   let ParserMatchClass = LogicalImm64Operand;
833 }
834 def logical_imm32_not : Operand<i32> {
835   let ParserMatchClass = LogicalImm32NotOperand;
836 }
837 def logical_imm64_not : Operand<i64> {
838   let ParserMatchClass = LogicalImm64NotOperand;
839 }
840
841 // iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535].
842 let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in {
843 def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{
844   return ((uint32_t)Imm) < 65536;
845 }]>;
846
847 def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{
848   return ((uint64_t)Imm) < 65536;
849 }]>;
850 }
851
852 // imm0_255 predicate - True if the immediate is in the range [0,255].
853 def Imm0_255Operand : AsmImmRange<0,255>;
854
855 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
856   return ((uint32_t)Imm) < 256;
857 }]> {
858   let ParserMatchClass = Imm0_255Operand;
859   let PrintMethod = "printImm";
860 }
861
862 // imm0_127 predicate - True if the immediate is in the range [0,127]
863 def Imm0_127Operand : AsmImmRange<0, 127>;
864 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
865   return ((uint32_t)Imm) < 128;
866 }]> {
867   let ParserMatchClass = Imm0_127Operand;
868   let PrintMethod = "printImm";
869 }
870
871 def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{
872   return ((uint64_t)Imm) < 128;
873 }]> {
874   let ParserMatchClass = Imm0_127Operand;
875   let PrintMethod = "printImm";
876 }
877
878 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
879 // for all shift-amounts.
880
881 // imm0_63 predicate - True if the immediate is in the range [0,63]
882 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
883   return ((uint64_t)Imm) < 64;
884 }]> {
885   let ParserMatchClass = Imm0_63Operand;
886 }
887
888 // imm0_31 predicate - True if the immediate is in the range [0,31]
889 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
890   return ((uint64_t)Imm) < 32;
891 }]> {
892   let ParserMatchClass = Imm0_31Operand;
893 }
894
895 // timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf)
896 // instead of Constant (ImmLeaf)
897 def timm0_31 : Operand<i64>, TImmLeaf<i64, [{
898   return ((uint64_t)Imm) < 32;
899 }]> {
900   let ParserMatchClass = Imm0_31Operand;
901 }
902
903 // True if the 32-bit immediate is in the range [0,31]
904 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
905   return ((uint64_t)Imm) < 32;
906 }]> {
907   let ParserMatchClass = Imm0_31Operand;
908 }
909
910 // imm0_1 predicate - True if the immediate is in the range [0,1]
911 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
912   return ((uint64_t)Imm) < 2;
913 }]> {
914   let ParserMatchClass = Imm0_1Operand;
915 }
916
917 // imm0_15 predicate - True if the immediate is in the range [0,15]
918 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
919   return ((uint64_t)Imm) < 16;
920 }]> {
921   let ParserMatchClass = Imm0_15Operand;
922 }
923
924 // imm0_7 predicate - True if the immediate is in the range [0,7]
925 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
926   return ((uint64_t)Imm) < 8;
927 }]> {
928   let ParserMatchClass = Imm0_7Operand;
929 }
930
931 // imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
932 def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{
933   return ((uint32_t)Imm) < 8;
934 }]> {
935   let ParserMatchClass = Imm0_7Operand;
936 }
937
938 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
939 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
940   return ((uint32_t)Imm) < 16;
941 }]> {
942   let ParserMatchClass = Imm0_15Operand;
943 }
944
945 // An arithmetic shifter operand:
946 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
947 //  {5-0} - imm6
948 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
949   let PrintMethod = "printShifter";
950   let ParserMatchClass = !cast<AsmOperandClass>(
951                          "ArithmeticShifterOperand" # width);
952 }
953
954 def arith_shift32 : arith_shift<i32, 32>;
955 def arith_shift64 : arith_shift<i64, 64>;
956
957 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
958     : Operand<Ty>,
959       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
960   let PrintMethod = "printShiftedRegister";
961   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
962 }
963
964 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
965 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
966
967 def gi_arith_shifted_reg32 :
968   GIComplexOperandMatcher<s32, "selectArithShiftedRegister">,
969   GIComplexPatternEquiv<arith_shifted_reg32>;
970
971 def gi_arith_shifted_reg64 :
972   GIComplexOperandMatcher<s64, "selectArithShiftedRegister">,
973   GIComplexPatternEquiv<arith_shifted_reg64>;
974
975 // An arithmetic shifter operand:
976 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
977 //  {5-0} - imm6
978 class logical_shift<int width> : Operand<i32> {
979   let PrintMethod = "printShifter";
980   let ParserMatchClass = !cast<AsmOperandClass>(
981                          "LogicalShifterOperand" # width);
982 }
983
984 def logical_shift32 : logical_shift<32>;
985 def logical_shift64 : logical_shift<64>;
986
987 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
988     : Operand<Ty>,
989       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
990   let PrintMethod = "printShiftedRegister";
991   let MIOperandInfo = (ops regclass, shiftop);
992 }
993
994 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
995 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
996
997 def gi_logical_shifted_reg32 :
998   GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">,
999   GIComplexPatternEquiv<logical_shifted_reg32>;
1000
1001 def gi_logical_shifted_reg64 :
1002   GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">,
1003   GIComplexPatternEquiv<logical_shifted_reg64>;
1004
1005 // A logical vector shifter operand:
1006 //  {7-6} - shift type: 00 = lsl
1007 //  {5-0} - imm6: #0, #8, #16, or #24
1008 def logical_vec_shift : Operand<i32> {
1009   let PrintMethod = "printShifter";
1010   let EncoderMethod = "getVecShifterOpValue";
1011   let ParserMatchClass = LogicalVecShifterOperand;
1012 }
1013
1014 // A logical vector half-word shifter operand:
1015 //  {7-6} - shift type: 00 = lsl
1016 //  {5-0} - imm6: #0 or #8
1017 def logical_vec_hw_shift : Operand<i32> {
1018   let PrintMethod = "printShifter";
1019   let EncoderMethod = "getVecShifterOpValue";
1020   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
1021 }
1022
1023 // A vector move shifter operand:
1024 //  {0} - imm1: #8 or #16
1025 def move_vec_shift : Operand<i32> {
1026   let PrintMethod = "printShifter";
1027   let EncoderMethod = "getMoveVecShifterOpValue";
1028   let ParserMatchClass = MoveVecShifterOperand;
1029 }
1030
1031 let DiagnosticType = "AddSubSecondSource" in {
1032   def AddSubImmOperand : AsmOperandClass {
1033     let Name = "AddSubImm";
1034     let ParserMethod = "tryParseImmWithOptionalShift";
1035     let RenderMethod = "addImmWithOptionalShiftOperands<12>";
1036   }
1037   def AddSubImmNegOperand : AsmOperandClass {
1038     let Name = "AddSubImmNeg";
1039     let ParserMethod = "tryParseImmWithOptionalShift";
1040     let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
1041   }
1042 }
1043 // An ADD/SUB immediate shifter operand:
1044 //  second operand:
1045 //  {7-6} - shift type: 00 = lsl
1046 //  {5-0} - imm6: #0 or #12
1047 class addsub_shifted_imm<ValueType Ty>
1048     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
1049   let PrintMethod = "printAddSubImm";
1050   let EncoderMethod = "getAddSubImmOpValue";
1051   let ParserMatchClass = AddSubImmOperand;
1052   let MIOperandInfo = (ops i32imm, i32imm);
1053 }
1054
1055 class addsub_shifted_imm_neg<ValueType Ty>
1056     : Operand<Ty> {
1057   let EncoderMethod = "getAddSubImmOpValue";
1058   let ParserMatchClass = AddSubImmNegOperand;
1059   let MIOperandInfo = (ops i32imm, i32imm);
1060 }
1061
1062 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
1063 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
1064 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
1065 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
1066
1067 def gi_addsub_shifted_imm32 :
1068     GIComplexOperandMatcher<s32, "selectArithImmed">,
1069     GIComplexPatternEquiv<addsub_shifted_imm32>;
1070
1071 def gi_addsub_shifted_imm64 :
1072     GIComplexOperandMatcher<s64, "selectArithImmed">,
1073     GIComplexPatternEquiv<addsub_shifted_imm64>;
1074
1075 class neg_addsub_shifted_imm<ValueType Ty>
1076     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
1077   let PrintMethod = "printAddSubImm";
1078   let EncoderMethod = "getAddSubImmOpValue";
1079   let ParserMatchClass = AddSubImmOperand;
1080   let MIOperandInfo = (ops i32imm, i32imm);
1081 }
1082
1083 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
1084 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
1085
1086 def gi_neg_addsub_shifted_imm32 :
1087     GIComplexOperandMatcher<s32, "selectNegArithImmed">,
1088     GIComplexPatternEquiv<neg_addsub_shifted_imm32>;
1089
1090 def gi_neg_addsub_shifted_imm64 :
1091     GIComplexOperandMatcher<s64, "selectNegArithImmed">,
1092     GIComplexPatternEquiv<neg_addsub_shifted_imm64>;
1093
1094 // An extend operand:
1095 //  {5-3} - extend type
1096 //  {2-0} - imm3
1097 def arith_extend : Operand<i32> {
1098   let PrintMethod = "printArithExtend";
1099   let ParserMatchClass = ExtendOperand;
1100 }
1101 def arith_extend64 : Operand<i32> {
1102   let PrintMethod = "printArithExtend";
1103   let ParserMatchClass = ExtendOperand64;
1104 }
1105
1106 // 'extend' that's a lsl of a 64-bit register.
1107 def arith_extendlsl64 : Operand<i32> {
1108   let PrintMethod = "printArithExtend";
1109   let ParserMatchClass = ExtendOperandLSL64;
1110 }
1111
1112 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
1113                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1114   let PrintMethod = "printExtendedRegister";
1115   let MIOperandInfo = (ops GPR32, arith_extend);
1116 }
1117
1118 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
1119                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1120   let PrintMethod = "printExtendedRegister";
1121   let MIOperandInfo = (ops GPR32, arith_extend64);
1122 }
1123
1124 def arith_extended_reg32_i32 : arith_extended_reg32<i32>;
1125 def gi_arith_extended_reg32_i32 :
1126     GIComplexOperandMatcher<s32, "selectArithExtendedRegister">,
1127     GIComplexPatternEquiv<arith_extended_reg32_i32>;
1128
1129 def arith_extended_reg32_i64 : arith_extended_reg32<i64>;
1130 def gi_arith_extended_reg32_i64 :
1131     GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1132     GIComplexPatternEquiv<arith_extended_reg32_i64>;
1133
1134 def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>;
1135 def gi_arith_extended_reg32to64_i64 :
1136     GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1137     GIComplexPatternEquiv<arith_extended_reg32to64_i64>;
1138
1139 // Floating-point immediate.
1140 def fpimm16 : Operand<f16>,
1141               FPImmLeaf<f16, [{
1142       return AArch64_AM::getFP16Imm(Imm) != -1;
1143     }], SDNodeXForm<fpimm, [{
1144       APFloat InVal = N->getValueAPF();
1145       uint32_t enc = AArch64_AM::getFP16Imm(InVal);
1146       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1147     }]>> {
1148   let ParserMatchClass = FPImmOperand;
1149   let PrintMethod = "printFPImmOperand";
1150 }
1151 def fpimm32 : Operand<f32>,
1152               FPImmLeaf<f32, [{
1153       return AArch64_AM::getFP32Imm(Imm) != -1;
1154     }], SDNodeXForm<fpimm, [{
1155       APFloat InVal = N->getValueAPF();
1156       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
1157       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1158     }]>> {
1159   let ParserMatchClass = FPImmOperand;
1160   let PrintMethod = "printFPImmOperand";
1161 }
1162 def fpimm64 : Operand<f64>,
1163               FPImmLeaf<f64, [{
1164       return AArch64_AM::getFP64Imm(Imm) != -1;
1165     }], SDNodeXForm<fpimm, [{
1166       APFloat InVal = N->getValueAPF();
1167       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
1168       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1169     }]>> {
1170   let ParserMatchClass = FPImmOperand;
1171   let PrintMethod = "printFPImmOperand";
1172 }
1173
1174 def fpimm8 : Operand<i32> {
1175   let ParserMatchClass = FPImmOperand;
1176   let PrintMethod = "printFPImmOperand";
1177 }
1178
1179 def fpimm0 : FPImmLeaf<fAny, [{
1180   return Imm.isExactlyValue(+0.0);
1181 }]>;
1182
1183 // Vector lane operands
1184 class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {
1185   let Name = NamePrefix # "IndexRange" # Min # "_" # Max;
1186   let DiagnosticType = "Invalid" # Name;
1187   let PredicateMethod = "isVectorIndex<" # Min # ", " # Max #  ">";
1188   let RenderMethod = "addVectorIndexOperands";
1189 }
1190
1191 class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc>
1192     : Operand<ty> {
1193   let ParserMatchClass = mc;
1194   let PrintMethod = "printVectorIndex";
1195 }
1196
1197 multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> {
1198   def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>;
1199   def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>;
1200 }
1201
1202 def VectorIndex1Operand : AsmVectorIndex<1, 1>;
1203 def VectorIndexBOperand : AsmVectorIndex<0, 15>;
1204 def VectorIndexHOperand : AsmVectorIndex<0, 7>;
1205 def VectorIndexSOperand : AsmVectorIndex<0, 3>;
1206 def VectorIndexDOperand : AsmVectorIndex<0, 1>;
1207
1208 defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,
1209                                 [{ return ((uint64_t)Imm) == 1; }]>;
1210 defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand,
1211                                 [{ return ((uint64_t)Imm) < 16; }]>;
1212 defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand,
1213                                 [{ return ((uint64_t)Imm) < 8; }]>;
1214 defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand,
1215                                 [{ return ((uint64_t)Imm) < 4; }]>;
1216 defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand,
1217                                 [{ return ((uint64_t)Imm) < 2; }]>;
1218
1219 defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand,
1220                                    [{ return ((uint64_t)Imm) == 1; }]>;
1221 defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand,
1222                                    [{ return ((uint64_t)Imm) < 16; }]>;
1223 defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand,
1224                                    [{ return ((uint64_t)Imm) < 8; }]>;
1225 defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand,
1226                                    [{ return ((uint64_t)Imm) < 4; }]>;
1227 defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand,
1228                                    [{ return ((uint64_t)Imm) < 2; }]>;
1229
1230 def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
1231 def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
1232 def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
1233 def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
1234 def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
1235
1236 defm sve_elm_idx_extdup_b
1237   : VectorIndex<i64, SVEVectorIndexExtDupBOperand,
1238                 [{ return ((uint64_t)Imm) < 64; }]>;
1239 defm sve_elm_idx_extdup_h
1240   : VectorIndex<i64, SVEVectorIndexExtDupHOperand,
1241                 [{ return ((uint64_t)Imm) < 32; }]>;
1242 defm sve_elm_idx_extdup_s
1243   : VectorIndex<i64, SVEVectorIndexExtDupSOperand,
1244                 [{ return ((uint64_t)Imm) < 16; }]>;
1245 defm sve_elm_idx_extdup_d
1246   : VectorIndex<i64, SVEVectorIndexExtDupDOperand,
1247                 [{ return ((uint64_t)Imm) < 8; }]>;
1248 defm sve_elm_idx_extdup_q
1249   : VectorIndex<i64, SVEVectorIndexExtDupQOperand,
1250                 [{ return ((uint64_t)Imm) < 4; }]>;
1251
1252 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
1253 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
1254 // are encoded as the eight bit value 'abcdefgh'.
1255 def simdimmtype10 : Operand<i32>,
1256                     FPImmLeaf<f64, [{
1257       return AArch64_AM::isAdvSIMDModImmType10(
1258                  Imm.bitcastToAPInt().getZExtValue());
1259     }], SDNodeXForm<fpimm, [{
1260       APFloat InVal = N->getValueAPF();
1261       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
1262                                                            .bitcastToAPInt()
1263                                                            .getZExtValue());
1264       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1265     }]>> {
1266   let ParserMatchClass = SIMDImmType10Operand;
1267   let PrintMethod = "printSIMDType10Operand";
1268 }
1269
1270
1271 //---
1272 // System management
1273 //---
1274
1275 // Base encoding for system instruction operands.
1276 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
1277 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
1278                   list<dag> pattern = []>
1279     : I<oops, iops, asm, operands, "", pattern> {
1280   let Inst{31-22} = 0b1101010100;
1281   let Inst{21}    = L;
1282 }
1283
1284 // System instructions which do not have an Rt register.
1285 class SimpleSystemI<bit L, dag iops, string asm, string operands,
1286                     list<dag> pattern = []>
1287     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
1288   let Inst{4-0} = 0b11111;
1289 }
1290
1291 // System instructions which have an Rt register.
1292 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
1293     : BaseSystemI<L, oops, iops, asm, operands>,
1294       Sched<[WriteSys]> {
1295   bits<5> Rt;
1296   let Inst{4-0} = Rt;
1297 }
1298
1299 // System instructions for transactional memory extension
1300 class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops,
1301                     string asm, string operands, list<dag> pattern>
1302     : BaseSystemI<L, oops, iops, asm, operands, pattern>,
1303       Sched<[WriteSys]> {
1304   let Inst{20-12} = 0b000110011;
1305   let Inst{11-8} = CRm;
1306   let Inst{7-5} = op2;
1307   let DecoderMethod = "";
1308
1309   let mayLoad = 1;
1310   let mayStore = 1;
1311 }
1312
1313 // System instructions for transactional memory - single input operand
1314 class TMSystemI<bits<4> CRm, string asm, list<dag> pattern>
1315     : TMBaseSystemI<0b1, CRm, 0b011,
1316                     (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> {
1317   bits<5> Rt;
1318   let Inst{4-0} = Rt;
1319 }
1320
1321 // System instructions for transactional memory - no operand
1322 class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern>
1323     : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> {
1324   let Inst{4-0} = 0b11111;
1325 }
1326
1327 // System instructions for exit from transactions
1328 class TMSystemException<bits<3> op1, string asm, list<dag> pattern>
1329     : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>,
1330       Sched<[WriteSys]> {
1331   bits<16> imm;
1332   let Inst{31-24} = 0b11010100;
1333   let Inst{23-21} = op1;
1334   let Inst{20-5}  = imm;
1335   let Inst{4-0}   = 0b00000;
1336 }
1337
1338 // Hint instructions that take both a CRm and a 3-bit immediate.
1339 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
1340 // model patterns with sufficiently fine granularity
1341 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
1342   class HintI<string mnemonic>
1343       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
1344                       [(int_aarch64_hint imm0_127:$imm)]>,
1345         Sched<[WriteHint]> {
1346     bits <7> imm;
1347     let Inst{20-12} = 0b000110010;
1348     let Inst{11-5} = imm;
1349   }
1350
1351 // System instructions taking a single literal operand which encodes into
1352 // CRm. op2 differentiates the opcodes.
1353 def BarrierAsmOperand : AsmOperandClass {
1354   let Name = "Barrier";
1355   let ParserMethod = "tryParseBarrierOperand";
1356 }
1357 def barrier_op : Operand<i32> {
1358   let PrintMethod = "printBarrierOption";
1359   let ParserMatchClass = BarrierAsmOperand;
1360 }
1361 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
1362                  list<dag> pattern = []>
1363     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
1364       Sched<[WriteBarrier]> {
1365   bits<4> CRm;
1366   let Inst{20-12} = 0b000110011;
1367   let Inst{11-8} = CRm;
1368   let Inst{7-5} = opc;
1369 }
1370
1371 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
1372     : SimpleSystemI<0, (ins), asm, "", pattern>,
1373       Sched<[]> {
1374   bits<4> CRm;
1375   let CRm = 0b0011;
1376   let Inst{31-12} = 0b11010101000000110010;
1377   let Inst{11-8} = CRm;
1378   let Inst{7-5} = op2;
1379   let Inst{4-0} = 0b11111;
1380 }
1381
1382 // MRS/MSR system instructions. These have different operand classes because
1383 // a different subset of registers can be accessed through each instruction.
1384 def MRSSystemRegisterOperand : AsmOperandClass {
1385   let Name = "MRSSystemRegister";
1386   let ParserMethod = "tryParseSysReg";
1387   let DiagnosticType = "MRS";
1388 }
1389 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
1390 def mrs_sysreg_op : Operand<i32> {
1391   let ParserMatchClass = MRSSystemRegisterOperand;
1392   let DecoderMethod = "DecodeMRSSystemRegister";
1393   let PrintMethod = "printMRSSystemRegister";
1394 }
1395
1396 def MSRSystemRegisterOperand : AsmOperandClass {
1397   let Name = "MSRSystemRegister";
1398   let ParserMethod = "tryParseSysReg";
1399   let DiagnosticType = "MSR";
1400 }
1401 def msr_sysreg_op : Operand<i32> {
1402   let ParserMatchClass = MSRSystemRegisterOperand;
1403   let DecoderMethod = "DecodeMSRSystemRegister";
1404   let PrintMethod = "printMSRSystemRegister";
1405 }
1406
1407 def PSBHintOperand : AsmOperandClass {
1408   let Name = "PSBHint";
1409   let ParserMethod = "tryParsePSBHint";
1410 }
1411 def psbhint_op : Operand<i32> {
1412   let ParserMatchClass = PSBHintOperand;
1413   let PrintMethod = "printPSBHintOp";
1414   let MCOperandPredicate = [{
1415     // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
1416     // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
1417     if (!MCOp.isImm())
1418       return false;
1419     return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
1420   }];
1421 }
1422
1423 def BTIHintOperand : AsmOperandClass {
1424   let Name = "BTIHint";
1425   let ParserMethod = "tryParseBTIHint";
1426 }
1427 def btihint_op : Operand<i32> {
1428   let ParserMatchClass = BTIHintOperand;
1429   let PrintMethod = "printBTIHintOp";
1430   let MCOperandPredicate = [{
1431     // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.
1432     if (!MCOp.isImm())
1433       return false;
1434     return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr;
1435   }];
1436 }
1437
1438 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
1439                        "mrs", "\t$Rt, $systemreg"> {
1440   bits<16> systemreg;
1441   let Inst{20-5} = systemreg;
1442 }
1443
1444 // FIXME: Some of these def NZCV, others don't. Best way to model that?
1445 // Explicitly modeling each of the system register as a register class
1446 // would do it, but feels like overkill at this point.
1447 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
1448                        "msr", "\t$systemreg, $Rt"> {
1449   bits<16> systemreg;
1450   let Inst{20-5} = systemreg;
1451 }
1452
1453 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
1454   let Name = "SystemPStateFieldWithImm0_15";
1455   let ParserMethod = "tryParseSysReg";
1456 }
1457 def pstatefield4_op : Operand<i32> {
1458   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
1459   let PrintMethod = "printSystemPStateField";
1460 }
1461
1462 // Instructions to modify PSTATE, no input reg
1463 let Defs = [NZCV] in
1464 class PstateWriteSimple<dag iops, string asm, string operands>
1465   : SimpleSystemI<0, iops, asm, operands> {
1466
1467   let Inst{20-19} = 0b00;
1468   let Inst{15-12} = 0b0100;
1469 }
1470
1471 class MSRpstateImm0_15
1472   : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr",
1473                   "\t$pstatefield, $imm">,
1474     Sched<[WriteSys]> {
1475
1476   bits<6> pstatefield;
1477   bits<4> imm;
1478   let Inst{18-16} = pstatefield{5-3};
1479   let Inst{11-8} = imm;
1480   let Inst{7-5} = pstatefield{2-0};
1481
1482   let DecoderMethod = "DecodeSystemPStateInstruction";
1483   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1484   // Fail the decoder should attempt to decode the instruction as MSRI.
1485   let hasCompleteDecoder = 0;
1486 }
1487
1488 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1489   let Name = "SystemPStateFieldWithImm0_1";
1490   let ParserMethod = "tryParseSysReg";
1491 }
1492 def pstatefield1_op : Operand<i32> {
1493   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1494   let PrintMethod = "printSystemPStateField";
1495 }
1496
1497 class MSRpstateImm0_1
1498   : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",
1499                  "\t$pstatefield, $imm">,
1500     Sched<[WriteSys]> {
1501
1502   bits<6> pstatefield;
1503   bit imm;
1504   let Inst{18-16} = pstatefield{5-3};
1505   let Inst{11-9} = 0b000;
1506   let Inst{8} = imm;
1507   let Inst{7-5} = pstatefield{2-0};
1508
1509   let DecoderMethod = "DecodeSystemPStateInstruction";
1510   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1511   // Fail the decoder should attempt to decode the instruction as MSRI.
1512   let hasCompleteDecoder = 0;
1513 }
1514
1515 // SYS and SYSL generic system instructions.
1516 def SysCRAsmOperand : AsmOperandClass {
1517   let Name = "SysCR";
1518   let ParserMethod = "tryParseSysCROperand";
1519 }
1520
1521 def sys_cr_op : Operand<i32> {
1522   let PrintMethod = "printSysCROperand";
1523   let ParserMatchClass = SysCRAsmOperand;
1524 }
1525
1526 class SystemXtI<bit L, string asm>
1527   : RtSystemI<L, (outs),
1528        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1529        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1530   bits<3> op1;
1531   bits<4> Cn;
1532   bits<4> Cm;
1533   bits<3> op2;
1534   let Inst{20-19} = 0b01;
1535   let Inst{18-16} = op1;
1536   let Inst{15-12} = Cn;
1537   let Inst{11-8}  = Cm;
1538   let Inst{7-5}   = op2;
1539 }
1540
1541 class SystemLXtI<bit L, string asm>
1542   : RtSystemI<L, (outs),
1543        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1544        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1545   bits<3> op1;
1546   bits<4> Cn;
1547   bits<4> Cm;
1548   bits<3> op2;
1549   let Inst{20-19} = 0b01;
1550   let Inst{18-16} = op1;
1551   let Inst{15-12} = Cn;
1552   let Inst{11-8}  = Cm;
1553   let Inst{7-5}   = op2;
1554 }
1555
1556
1557 // Branch (register) instructions:
1558 //
1559 //  case opc of
1560 //    0001 blr
1561 //    0000 br
1562 //    0101 dret
1563 //    0100 eret
1564 //    0010 ret
1565 //    otherwise UNDEFINED
1566 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1567                     string operands, list<dag> pattern>
1568     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1569   let Inst{31-25} = 0b1101011;
1570   let Inst{24-21} = opc;
1571   let Inst{20-16} = 0b11111;
1572   let Inst{15-10} = 0b000000;
1573   let Inst{4-0}   = 0b00000;
1574 }
1575
1576 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1577     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1578   bits<5> Rn;
1579   let Inst{9-5} = Rn;
1580 }
1581
1582 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1583 class SpecialReturn<bits<4> opc, string asm>
1584     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1585   let Inst{9-5} = 0b11111;
1586 }
1587
1588 let mayLoad = 1 in
1589 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
1590   : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
1591   Sched<[]> {
1592   bits<5> Rn;
1593   bits<5> Rt;
1594   let Inst{31-30} = sz;
1595   let Inst{29-10} = 0b11100010111111110000;
1596   let Inst{9-5} = Rn;
1597   let Inst{4-0} = Rt;
1598 }
1599
1600 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
1601                list<dag> pattern>
1602   : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
1603   let isAuthenticated = 1;
1604   let Inst{31-25} = 0b1101011;
1605   let Inst{20-11} = 0b1111100001;
1606   let Inst{10} = M;
1607   let Inst{4-0} = 0b11111;
1608 }
1609
1610 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
1611   : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
1612   bits<5> Rn;
1613   bits<5> Rm;
1614   let Inst{24-22} = 0b100;
1615   let Inst{21} = op;
1616   let Inst{9-5} = Rn;
1617   let Inst{4-0} = Rm;
1618 }
1619
1620 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
1621   : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
1622   bits<5> Rn;
1623   let Inst{24} = 0;
1624   let Inst{23-21} = opc;
1625   let Inst{9-5} = Rn;
1626 }
1627
1628 let Uses = [LR,SP] in
1629 class AuthReturn<bits<3> op, bits<1> M, string asm>
1630   : AuthBase<M, (outs), (ins), asm, "", []> {
1631   let Inst{24} = 0;
1632   let Inst{23-21} = op;
1633   let Inst{9-0} = 0b1111111111;
1634 }
1635
1636 let mayLoad = 1 in
1637 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
1638                    string operands, string cstr, Operand opr>
1639   : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
1640   bits<10> offset;
1641   bits<5> Rn;
1642   bits<5> Rt;
1643   let isAuthenticated = 1;
1644   let Inst{31-24} = 0b11111000;
1645   let Inst{23} = M;
1646   let Inst{22} = offset{9};
1647   let Inst{21} = 1;
1648   let Inst{20-12} = offset{8-0};
1649   let Inst{11} = W;
1650   let Inst{10} = 1;
1651   let Inst{9-5} = Rn;
1652   let Inst{4-0} = Rt;
1653
1654   let DecoderMethod = "DecodeAuthLoadInstruction";
1655 }
1656
1657 multiclass AuthLoad<bit M, string asm, Operand opr> {
1658   def indexed   : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
1659                                (ins GPR64sp:$Rn, opr:$offset),
1660                                asm, "\t$Rt, [$Rn, $offset]", "", opr>;
1661   def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
1662                                (ins GPR64sp:$Rn, opr:$offset),
1663                                asm, "\t$Rt, [$Rn, $offset]!",
1664                                "$Rn = $wback,@earlyclobber $wback", opr>;
1665
1666   def : InstAlias<asm # "\t$Rt, [$Rn]",
1667                   (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
1668
1669   def : InstAlias<asm # "\t$Rt, [$wback]!",
1670                   (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>;
1671 }
1672
1673 //---
1674 // Conditional branch instruction.
1675 //---
1676
1677 // Condition code.
1678 // 4-bit immediate. Pretty-printed as <cc>
1679 def ccode : Operand<i32> {
1680   let PrintMethod = "printCondCode";
1681   let ParserMatchClass = CondCode;
1682 }
1683 def inv_ccode : Operand<i32> {
1684   // AL and NV are invalid in the aliases which use inv_ccode
1685   let PrintMethod = "printInverseCondCode";
1686   let ParserMatchClass = CondCode;
1687   let MCOperandPredicate = [{
1688     return MCOp.isImm() &&
1689            MCOp.getImm() != AArch64CC::AL &&
1690            MCOp.getImm() != AArch64CC::NV;
1691   }];
1692 }
1693
1694 // Conditional branch target. 19-bit immediate. The low two bits of the target
1695 // offset are implied zero and so are not part of the immediate.
1696 def am_brcond : Operand<OtherVT> {
1697   let EncoderMethod = "getCondBranchTargetOpValue";
1698   let DecoderMethod = "DecodePCRelLabel19";
1699   let PrintMethod = "printAlignedLabel";
1700   let ParserMatchClass = PCRelLabel19Operand;
1701   let OperandType = "OPERAND_PCREL";
1702 }
1703
1704 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1705                      "b", ".$cond\t$target", "",
1706                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1707                    Sched<[WriteBr]> {
1708   let isBranch = 1;
1709   let isTerminator = 1;
1710   let Uses = [NZCV];
1711
1712   bits<4> cond;
1713   bits<19> target;
1714   let Inst{31-24} = 0b01010100;
1715   let Inst{23-5} = target;
1716   let Inst{4} = 0;
1717   let Inst{3-0} = cond;
1718 }
1719
1720 //---
1721 // Compare-and-branch instructions.
1722 //---
1723 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1724     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1725          asm, "\t$Rt, $target", "",
1726          [(node regtype:$Rt, bb:$target)]>,
1727       Sched<[WriteBr]> {
1728   let isBranch = 1;
1729   let isTerminator = 1;
1730
1731   bits<5> Rt;
1732   bits<19> target;
1733   let Inst{30-25} = 0b011010;
1734   let Inst{24}    = op;
1735   let Inst{23-5}  = target;
1736   let Inst{4-0}   = Rt;
1737 }
1738
1739 multiclass CmpBranch<bit op, string asm, SDNode node> {
1740   def W : BaseCmpBranch<GPR32, op, asm, node> {
1741     let Inst{31} = 0;
1742   }
1743   def X : BaseCmpBranch<GPR64, op, asm, node> {
1744     let Inst{31} = 1;
1745   }
1746 }
1747
1748 //---
1749 // Test-bit-and-branch instructions.
1750 //---
1751 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1752 // the target offset are implied zero and so are not part of the immediate.
1753 def am_tbrcond : Operand<OtherVT> {
1754   let EncoderMethod = "getTestBranchTargetOpValue";
1755   let PrintMethod = "printAlignedLabel";
1756   let ParserMatchClass = BranchTarget14Operand;
1757   let OperandType = "OPERAND_PCREL";
1758 }
1759
1760 // AsmOperand classes to emit (or not) special diagnostics
1761 def TBZImm0_31Operand : AsmOperandClass {
1762   let Name = "TBZImm0_31";
1763   let PredicateMethod = "isImmInRange<0,31>";
1764   let RenderMethod = "addImmOperands";
1765 }
1766 def TBZImm32_63Operand : AsmOperandClass {
1767   let Name = "Imm32_63";
1768   let PredicateMethod = "isImmInRange<32,63>";
1769   let DiagnosticType = "InvalidImm0_63";
1770   let RenderMethod = "addImmOperands";
1771 }
1772
1773 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1774   return (((uint32_t)Imm) < 32);
1775 }]> {
1776   let ParserMatchClass = matcher;
1777 }
1778
1779 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1780 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1781
1782 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1783   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1784 }]> {
1785   let ParserMatchClass = TBZImm32_63Operand;
1786 }
1787
1788 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1789                      bit op, string asm, SDNode node>
1790     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1791        asm, "\t$Rt, $bit_off, $target", "",
1792        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1793       Sched<[WriteBr]> {
1794   let isBranch = 1;
1795   let isTerminator = 1;
1796
1797   bits<5> Rt;
1798   bits<6> bit_off;
1799   bits<14> target;
1800
1801   let Inst{30-25} = 0b011011;
1802   let Inst{24}    = op;
1803   let Inst{23-19} = bit_off{4-0};
1804   let Inst{18-5}  = target;
1805   let Inst{4-0}   = Rt;
1806
1807   let DecoderMethod = "DecodeTestAndBranch";
1808 }
1809
1810 multiclass TestBranch<bit op, string asm, SDNode node> {
1811   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1812     let Inst{31} = 0;
1813   }
1814
1815   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1816     let Inst{31} = 1;
1817   }
1818
1819   // Alias X-reg with 0-31 imm to W-Reg.
1820   def : InstAlias<asm # "\t$Rd, $imm, $target",
1821                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1822                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1823   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1824             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1825             tbz_imm0_31_diag:$imm, bb:$target)>;
1826 }
1827
1828 //---
1829 // Unconditional branch (immediate) instructions.
1830 //---
1831 def am_b_target : Operand<OtherVT> {
1832   let EncoderMethod = "getBranchTargetOpValue";
1833   let PrintMethod = "printAlignedLabel";
1834   let ParserMatchClass = BranchTarget26Operand;
1835   let OperandType = "OPERAND_PCREL";
1836 }
1837 def am_bl_target : Operand<i64> {
1838   let EncoderMethod = "getBranchTargetOpValue";
1839   let PrintMethod = "printAlignedLabel";
1840   let ParserMatchClass = BranchTarget26Operand;
1841   let OperandType = "OPERAND_PCREL";
1842 }
1843
1844 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1845     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1846   bits<26> addr;
1847   let Inst{31}    = op;
1848   let Inst{30-26} = 0b00101;
1849   let Inst{25-0}  = addr;
1850
1851   let DecoderMethod = "DecodeUnconditionalBranch";
1852 }
1853
1854 class BranchImm<bit op, string asm, list<dag> pattern>
1855     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1856 class CallImm<bit op, string asm, list<dag> pattern>
1857     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1858
1859 //---
1860 // Basic one-operand data processing instructions.
1861 //---
1862
1863 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1864 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1865                          SDPatternOperator node>
1866   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1867       [(set regtype:$Rd, (node regtype:$Rn))]>,
1868     Sched<[WriteI, ReadI]> {
1869   bits<5> Rd;
1870   bits<5> Rn;
1871
1872   let Inst{30-13} = 0b101101011000000000;
1873   let Inst{12-10} = opc;
1874   let Inst{9-5}   = Rn;
1875   let Inst{4-0}   = Rd;
1876 }
1877
1878 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1879 multiclass OneOperandData<bits<3> opc, string asm,
1880                           SDPatternOperator node = null_frag> {
1881   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1882     let Inst{31} = 0;
1883   }
1884
1885   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1886     let Inst{31} = 1;
1887   }
1888 }
1889
1890 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1891     : BaseOneOperandData<opc, GPR32, asm, node> {
1892   let Inst{31} = 0;
1893 }
1894
1895 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1896     : BaseOneOperandData<opc, GPR64, asm, node> {
1897   let Inst{31} = 1;
1898 }
1899
1900 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
1901   : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "",
1902       []>,
1903     Sched<[WriteI, ReadI]> {
1904   bits<5> Rd;
1905   bits<5> Rn;
1906   let Inst{31-15} = 0b11011010110000010;
1907   let Inst{14-12} = opcode_prefix;
1908   let Inst{11-10} = opcode;
1909   let Inst{9-5} = Rn;
1910   let Inst{4-0} = Rd;
1911 }
1912
1913 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
1914   : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> {
1915   bits<5> Rd;
1916   let Inst{31-15} = 0b11011010110000010;
1917   let Inst{14-12} = opcode_prefix;
1918   let Inst{11-10} = opcode;
1919   let Inst{9-5} = 0b11111;
1920   let Inst{4-0} = Rd;
1921 }
1922
1923 class SignAuthTwoOperand<bits<4> opc, string asm,
1924                          SDPatternOperator OpNode>
1925   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
1926       asm, "\t$Rd, $Rn, $Rm", "",
1927       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
1928     Sched<[WriteI, ReadI, ReadI]> {
1929   bits<5> Rd;
1930   bits<5> Rn;
1931   bits<5> Rm;
1932   let Inst{31-21} = 0b10011010110;
1933   let Inst{20-16} = Rm;
1934   let Inst{15-14} = 0b00;
1935   let Inst{13-10} = opc;
1936   let Inst{9-5}   = Rn;
1937   let Inst{4-0}   = Rd;
1938 }
1939
1940 // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
1941 class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
1942     : I<(outs), iops, asm, ops, "", []>,
1943       Sched<[WriteI, ReadI, ReadI]> {
1944   let Uses = [NZCV];
1945   bits<5> Rn;
1946   let Inst{31}    = sf;
1947   let Inst{30-15} = 0b0111010000000000;
1948   let Inst{14}    = sz;
1949   let Inst{13-10} = 0b0010;
1950   let Inst{9-5}   = Rn;
1951   let Inst{4-0}   = 0b01101;
1952 }
1953
1954 class FlagRotate<dag iops, string asm, string ops>
1955     : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
1956   bits<6> imm;
1957   bits<4> mask;
1958   let Inst{20-15} = imm;
1959   let Inst{13-10} = 0b0001;
1960   let Inst{4}     = 0b0;
1961   let Inst{3-0}   = mask;
1962 }
1963
1964 //---
1965 // Basic two-operand data processing instructions.
1966 //---
1967 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1968                           list<dag> pattern>
1969     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1970         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1971       Sched<[WriteI, ReadI, ReadI]> {
1972   let Uses = [NZCV];
1973   bits<5> Rd;
1974   bits<5> Rn;
1975   bits<5> Rm;
1976   let Inst{30}    = isSub;
1977   let Inst{28-21} = 0b11010000;
1978   let Inst{20-16} = Rm;
1979   let Inst{15-10} = 0;
1980   let Inst{9-5}   = Rn;
1981   let Inst{4-0}   = Rd;
1982 }
1983
1984 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1985                       SDNode OpNode>
1986     : BaseBaseAddSubCarry<isSub, regtype, asm,
1987         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1988
1989 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1990                               SDNode OpNode>
1991     : BaseBaseAddSubCarry<isSub, regtype, asm,
1992         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1993          (implicit NZCV)]> {
1994   let Defs = [NZCV];
1995 }
1996
1997 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1998                        SDNode OpNode, SDNode OpNode_setflags> {
1999   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
2000     let Inst{31} = 0;
2001     let Inst{29} = 0;
2002   }
2003   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
2004     let Inst{31} = 1;
2005     let Inst{29} = 0;
2006   }
2007
2008   // Sets flags.
2009   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
2010                                     OpNode_setflags> {
2011     let Inst{31} = 0;
2012     let Inst{29} = 1;
2013   }
2014   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
2015                                     OpNode_setflags> {
2016     let Inst{31} = 1;
2017     let Inst{29} = 1;
2018   }
2019 }
2020
2021 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
2022                      SDPatternOperator OpNode,
2023                      RegisterClass in1regtype = regtype,
2024                      RegisterClass in2regtype = regtype>
2025   : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm),
2026       asm, "\t$Rd, $Rn, $Rm", "",
2027       [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> {
2028   bits<5> Rd;
2029   bits<5> Rn;
2030   bits<5> Rm;
2031   let Inst{30-21} = 0b0011010110;
2032   let Inst{20-16} = Rm;
2033   let Inst{15-14} = 0b00;
2034   let Inst{13-10} = opc;
2035   let Inst{9-5}   = Rn;
2036   let Inst{4-0}   = Rd;
2037 }
2038
2039 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
2040               SDPatternOperator OpNode>
2041     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
2042   let Inst{10}    = isSigned;
2043 }
2044
2045 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
2046   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
2047            Sched<[WriteID32, ReadID, ReadID]> {
2048     let Inst{31} = 0;
2049   }
2050   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
2051            Sched<[WriteID64, ReadID, ReadID]> {
2052     let Inst{31} = 1;
2053   }
2054 }
2055
2056 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
2057                 SDPatternOperator OpNode = null_frag>
2058   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
2059     Sched<[WriteIS, ReadI]> {
2060   let Inst{11-10} = shift_type;
2061 }
2062
2063 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
2064   def Wr : BaseShift<shift_type, GPR32, asm> {
2065     let Inst{31} = 0;
2066   }
2067
2068   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
2069     let Inst{31} = 1;
2070   }
2071
2072   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
2073             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
2074                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
2075
2076   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
2077             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2078
2079   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
2080             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2081
2082   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
2083             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2084
2085   def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))),
2086             (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2087                 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2088
2089   def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))),
2090             (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2091                 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2092 }
2093
2094 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
2095     : InstAlias<asm#"\t$dst, $src1, $src2",
2096                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
2097
2098 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
2099                        RegisterClass addtype, string asm,
2100                        list<dag> pattern>
2101   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
2102       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
2103   bits<5> Rd;
2104   bits<5> Rn;
2105   bits<5> Rm;
2106   bits<5> Ra;
2107   let Inst{30-24} = 0b0011011;
2108   let Inst{23-21} = opc;
2109   let Inst{20-16} = Rm;
2110   let Inst{15}    = isSub;
2111   let Inst{14-10} = Ra;
2112   let Inst{9-5}   = Rn;
2113   let Inst{4-0}   = Rd;
2114 }
2115
2116 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
2117   // MADD/MSUB generation is decided by MachineCombiner.cpp
2118   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
2119       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
2120       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2121     let Inst{31} = 0;
2122   }
2123
2124   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
2125       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
2126       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
2127     let Inst{31} = 1;
2128   }
2129 }
2130
2131 class WideMulAccum<bit isSub, bits<3> opc, string asm,
2132                    SDNode AccNode, SDNode ExtNode>
2133   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
2134     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
2135                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
2136     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2137   let Inst{31} = 1;
2138 }
2139
2140 class MulHi<bits<3> opc, string asm, SDNode OpNode>
2141   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
2142       asm, "\t$Rd, $Rn, $Rm", "",
2143       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
2144     Sched<[WriteIM64, ReadIM, ReadIM]> {
2145   bits<5> Rd;
2146   bits<5> Rn;
2147   bits<5> Rm;
2148   let Inst{31-24} = 0b10011011;
2149   let Inst{23-21} = opc;
2150   let Inst{20-16} = Rm;
2151   let Inst{15}    = 0;
2152   let Inst{9-5}   = Rn;
2153   let Inst{4-0}   = Rd;
2154
2155   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
2156   // (i.e. all bits 1) but is ignored by the processor.
2157   let PostEncoderMethod = "fixMulHigh";
2158 }
2159
2160 class MulAccumWAlias<string asm, Instruction inst>
2161     : InstAlias<asm#"\t$dst, $src1, $src2",
2162                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
2163 class MulAccumXAlias<string asm, Instruction inst>
2164     : InstAlias<asm#"\t$dst, $src1, $src2",
2165                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
2166 class WideMulAccumAlias<string asm, Instruction inst>
2167     : InstAlias<asm#"\t$dst, $src1, $src2",
2168                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
2169
2170 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
2171               SDPatternOperator OpNode, string asm>
2172   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
2173       asm, "\t$Rd, $Rn, $Rm", "",
2174       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
2175     Sched<[WriteISReg, ReadI, ReadISReg]> {
2176   bits<5> Rd;
2177   bits<5> Rn;
2178   bits<5> Rm;
2179
2180   let Inst{31} = sf;
2181   let Inst{30-21} = 0b0011010110;
2182   let Inst{20-16} = Rm;
2183   let Inst{15-13} = 0b010;
2184   let Inst{12} = C;
2185   let Inst{11-10} = sz;
2186   let Inst{9-5} = Rn;
2187   let Inst{4-0} = Rd;
2188   let Predicates = [HasCRC];
2189 }
2190
2191 //---
2192 // Address generation.
2193 //---
2194
2195 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
2196     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
2197         pattern>,
2198       Sched<[WriteI]> {
2199   bits<5>  Xd;
2200   bits<21> label;
2201   let Inst{31}    = page;
2202   let Inst{30-29} = label{1-0};
2203   let Inst{28-24} = 0b10000;
2204   let Inst{23-5}  = label{20-2};
2205   let Inst{4-0}   = Xd;
2206
2207   let DecoderMethod = "DecodeAdrInstruction";
2208 }
2209
2210 //---
2211 // Move immediate.
2212 //---
2213
2214 def movimm32_imm : Operand<i32> {
2215   let ParserMatchClass = AsmImmRange<0, 65535>;
2216   let EncoderMethod = "getMoveWideImmOpValue";
2217   let PrintMethod = "printImm";
2218 }
2219 def movimm32_shift : Operand<i32> {
2220   let PrintMethod = "printShifter";
2221   let ParserMatchClass = MovImm32ShifterOperand;
2222 }
2223 def movimm64_shift : Operand<i32> {
2224   let PrintMethod = "printShifter";
2225   let ParserMatchClass = MovImm64ShifterOperand;
2226 }
2227
2228 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2229 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2230                         string asm>
2231   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
2232        asm, "\t$Rd, $imm$shift", "", []>,
2233     Sched<[WriteImm]> {
2234   bits<5> Rd;
2235   bits<16> imm;
2236   bits<6> shift;
2237   let Inst{30-29} = opc;
2238   let Inst{28-23} = 0b100101;
2239   let Inst{22-21} = shift{5-4};
2240   let Inst{20-5}  = imm;
2241   let Inst{4-0}   = Rd;
2242
2243   let DecoderMethod = "DecodeMoveImmInstruction";
2244 }
2245
2246 multiclass MoveImmediate<bits<2> opc, string asm> {
2247   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
2248     let Inst{31} = 0;
2249   }
2250
2251   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
2252     let Inst{31} = 1;
2253   }
2254 }
2255
2256 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2257 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2258                           string asm>
2259   : I<(outs regtype:$Rd),
2260       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
2261        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
2262     Sched<[WriteI, ReadI]> {
2263   bits<5> Rd;
2264   bits<16> imm;
2265   bits<6> shift;
2266   let Inst{30-29} = opc;
2267   let Inst{28-23} = 0b100101;
2268   let Inst{22-21} = shift{5-4};
2269   let Inst{20-5}  = imm;
2270   let Inst{4-0}   = Rd;
2271
2272   let DecoderMethod = "DecodeMoveImmInstruction";
2273 }
2274
2275 multiclass InsertImmediate<bits<2> opc, string asm> {
2276   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
2277     let Inst{31} = 0;
2278   }
2279
2280   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
2281     let Inst{31} = 1;
2282   }
2283 }
2284
2285 //---
2286 // Add/Subtract
2287 //---
2288
2289 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
2290                     string asm_inst, string asm_ops,
2291                     dag inputs, dag pattern>
2292     : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>,
2293       Sched<[WriteI, ReadI]> {
2294   bits<5>  Rd;
2295   bits<5>  Rn;
2296   let Inst{30}    = isSub;
2297   let Inst{29}    = setFlags;
2298   let Inst{28-24} = 0b10001;
2299   let Inst{9-5}   = Rn;
2300   let Inst{4-0}   = Rd;
2301 }
2302
2303 class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype,
2304                      RegisterClass srcRegtype, addsub_shifted_imm immtype,
2305                      string asm_inst, SDPatternOperator OpNode>
2306     : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm",
2307                     (ins srcRegtype:$Rn, immtype:$imm),
2308                     (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> {
2309   bits<14> imm;
2310   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
2311   let Inst{21-10} = imm{11-0};
2312   let DecoderMethod = "DecodeAddSubImmShift";
2313 }
2314
2315 class BaseAddSubRegPseudo<RegisterClass regtype,
2316                           SDPatternOperator OpNode>
2317     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2318              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2319       Sched<[WriteI, ReadI, ReadI]>;
2320
2321 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
2322                      arith_shifted_reg shifted_regtype, string asm,
2323                      SDPatternOperator OpNode>
2324     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2325         asm, "\t$Rd, $Rn, $Rm", "",
2326         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
2327       Sched<[WriteISReg, ReadI, ReadISReg]> {
2328   // The operands are in order to match the 'addr' MI operands, so we
2329   // don't need an encoder method and by-name matching. Just use the default
2330   // in-order handling. Since we're using by-order, make sure the names
2331   // do not match.
2332   bits<5> dst;
2333   bits<5> src1;
2334   bits<5> src2;
2335   bits<8> shift;
2336   let Inst{30}    = isSub;
2337   let Inst{29}    = setFlags;
2338   let Inst{28-24} = 0b01011;
2339   let Inst{23-22} = shift{7-6};
2340   let Inst{21}    = 0;
2341   let Inst{20-16} = src2;
2342   let Inst{15-10} = shift{5-0};
2343   let Inst{9-5}   = src1;
2344   let Inst{4-0}   = dst;
2345
2346   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2347 }
2348
2349 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
2350                      RegisterClass src1Regtype, Operand src2Regtype,
2351                      string asm, SDPatternOperator OpNode>
2352     : I<(outs dstRegtype:$R1),
2353         (ins src1Regtype:$R2, src2Regtype:$R3),
2354         asm, "\t$R1, $R2, $R3", "",
2355         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
2356       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2357   bits<5> Rd;
2358   bits<5> Rn;
2359   bits<5> Rm;
2360   bits<6> ext;
2361   let Inst{30}    = isSub;
2362   let Inst{29}    = setFlags;
2363   let Inst{28-24} = 0b01011;
2364   let Inst{23-21} = 0b001;
2365   let Inst{20-16} = Rm;
2366   let Inst{15-13} = ext{5-3};
2367   let Inst{12-10} = ext{2-0};
2368   let Inst{9-5}   = Rn;
2369   let Inst{4-0}   = Rd;
2370
2371   let DecoderMethod = "DecodeAddSubERegInstruction";
2372 }
2373
2374 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2375 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
2376                        RegisterClass src1Regtype, RegisterClass src2Regtype,
2377                        Operand ext_op, string asm>
2378     : I<(outs dstRegtype:$Rd),
2379         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
2380         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
2381       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2382   bits<5> Rd;
2383   bits<5> Rn;
2384   bits<5> Rm;
2385   bits<6> ext;
2386   let Inst{30}    = isSub;
2387   let Inst{29}    = setFlags;
2388   let Inst{28-24} = 0b01011;
2389   let Inst{23-21} = 0b001;
2390   let Inst{20-16} = Rm;
2391   let Inst{15}    = ext{5};
2392   let Inst{12-10} = ext{2-0};
2393   let Inst{9-5}   = Rn;
2394   let Inst{4-0}   = Rd;
2395
2396   let DecoderMethod = "DecodeAddSubERegInstruction";
2397 }
2398
2399 // Aliases for register+register add/subtract.
2400 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
2401                      RegisterClass src1Regtype, RegisterClass src2Regtype,
2402                      int shiftExt>
2403     : InstAlias<asm#"\t$dst, $src1, $src2",
2404                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
2405                       shiftExt)>;
2406
2407 multiclass AddSub<bit isSub, string mnemonic, string alias,
2408                   SDPatternOperator OpNode = null_frag> {
2409   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2410   // Add/Subtract immediate
2411   // Increase the weight of the immediate variant to try to match it before
2412   // the extended register variant.
2413   // We used to match the register variant before the immediate when the
2414   // register argument could be implicitly zero-extended.
2415   let AddedComplexity = 6 in
2416   def Wri  : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
2417                            mnemonic, OpNode> {
2418     let Inst{31} = 0;
2419   }
2420   let AddedComplexity = 6 in
2421   def Xri  : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
2422                            mnemonic, OpNode> {
2423     let Inst{31} = 1;
2424   }
2425
2426   // Add/Subtract register - Only used for CodeGen
2427   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2428   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2429
2430   // Add/Subtract shifted register
2431   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
2432                            OpNode> {
2433     let Inst{31} = 0;
2434   }
2435   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
2436                            OpNode> {
2437     let Inst{31} = 1;
2438   }
2439   }
2440
2441   // Add/Subtract extended register
2442   let AddedComplexity = 1, hasSideEffects = 0 in {
2443   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
2444                            arith_extended_reg32_i32, mnemonic, OpNode> {
2445     let Inst{31} = 0;
2446   }
2447   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
2448                            arith_extended_reg32to64_i64, mnemonic, OpNode> {
2449     let Inst{31} = 1;
2450   }
2451   }
2452
2453   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
2454                                arith_extendlsl64, mnemonic> {
2455     // UXTX and SXTX only.
2456     let Inst{14-13} = 0b11;
2457     let Inst{31} = 1;
2458   }
2459
2460   // add Rd, Rb, -imm -> sub Rd, Rn, imm
2461   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2462                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
2463                       addsub_shifted_imm32_neg:$imm), 0>;
2464   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2465                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
2466                        addsub_shifted_imm64_neg:$imm), 0>;
2467
2468   // Register/register aliases with no shift when SP is not used.
2469   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2470                        GPR32, GPR32, GPR32, 0>;
2471   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2472                        GPR64, GPR64, GPR64, 0>;
2473
2474   // Register/register aliases with no shift when either the destination or
2475   // first source register is SP.
2476   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2477                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
2478   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2479                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
2480   def : AddSubRegAlias<mnemonic,
2481                        !cast<Instruction>(NAME#"Xrx64"),
2482                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
2483   def : AddSubRegAlias<mnemonic,
2484                        !cast<Instruction>(NAME#"Xrx64"),
2485                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
2486 }
2487
2488 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
2489                    string alias, string cmpAlias> {
2490   let isCompare = 1, Defs = [NZCV] in {
2491   // Add/Subtract immediate
2492   def Wri  : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
2493                            mnemonic, OpNode> {
2494     let Inst{31} = 0;
2495   }
2496   def Xri  : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
2497                            mnemonic, OpNode> {
2498     let Inst{31} = 1;
2499   }
2500
2501   // Add/Subtract register
2502   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2503   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2504
2505   // Add/Subtract shifted register
2506   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
2507                            OpNode> {
2508     let Inst{31} = 0;
2509   }
2510   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
2511                            OpNode> {
2512     let Inst{31} = 1;
2513   }
2514
2515   // Add/Subtract extended register
2516   let AddedComplexity = 1 in {
2517   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
2518                            arith_extended_reg32_i32, mnemonic, OpNode> {
2519     let Inst{31} = 0;
2520   }
2521   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
2522                            arith_extended_reg32_i64, mnemonic, OpNode> {
2523     let Inst{31} = 1;
2524   }
2525   }
2526
2527   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
2528                                arith_extendlsl64, mnemonic> {
2529     // UXTX and SXTX only.
2530     let Inst{14-13} = 0b11;
2531     let Inst{31} = 1;
2532   }
2533   } // Defs = [NZCV]
2534
2535   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
2536   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2537                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
2538                       addsub_shifted_imm32_neg:$imm), 0>;
2539   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2540                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
2541                        addsub_shifted_imm64_neg:$imm), 0>;
2542
2543   // Compare aliases
2544   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2545                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
2546   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2547                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
2548   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
2549                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2550   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
2551                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2552   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
2553                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
2554   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
2555                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
2556   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
2557                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
2558
2559   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
2560   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2561                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
2562   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2563                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
2564
2565   // Compare shorthands
2566   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
2567                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
2568   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
2569                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
2570   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
2571                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
2572   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
2573                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
2574
2575   // Register/register aliases with no shift when SP is not used.
2576   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2577                        GPR32, GPR32, GPR32, 0>;
2578   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2579                        GPR64, GPR64, GPR64, 0>;
2580
2581   // Register/register aliases with no shift when the first source register
2582   // is SP.
2583   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2584                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
2585   def : AddSubRegAlias<mnemonic,
2586                        !cast<Instruction>(NAME#"Xrx64"),
2587                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
2588 }
2589
2590 class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode>
2591       : BaseAddSubImm<
2592           isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4",
2593           (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4),
2594           (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> {
2595   bits<6> imm6;
2596   bits<4> imm4;
2597   let Inst{31} = 1;
2598   let Inst{23-22} = 0b10;
2599   let Inst{21-16} = imm6;
2600   let Inst{15-14} = 0b00;
2601   let Inst{13-10} = imm4;
2602   let Unpredictable{15-14} = 0b11;
2603 }
2604
2605 class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode>
2606       : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> {
2607   let Inst{31} = 1;
2608   let Inst{29} = setsFlags;
2609 }
2610
2611 //---
2612 // Extract
2613 //---
2614 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2615                                       SDTCisPtrTy<3>]>;
2616 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
2617
2618 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
2619                      list<dag> patterns>
2620     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
2621          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
2622       Sched<[WriteExtr, ReadExtrHi]> {
2623   bits<5> Rd;
2624   bits<5> Rn;
2625   bits<5> Rm;
2626   bits<6> imm;
2627
2628   let Inst{30-23} = 0b00100111;
2629   let Inst{21}    = 0;
2630   let Inst{20-16} = Rm;
2631   let Inst{15-10} = imm;
2632   let Inst{9-5}   = Rn;
2633   let Inst{4-0}   = Rd;
2634 }
2635
2636 multiclass ExtractImm<string asm> {
2637   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
2638                       [(set GPR32:$Rd,
2639                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
2640     let Inst{31} = 0;
2641     let Inst{22} = 0;
2642     // imm<5> must be zero.
2643     let imm{5}   = 0;
2644   }
2645   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
2646                       [(set GPR64:$Rd,
2647                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
2648
2649     let Inst{31} = 1;
2650     let Inst{22} = 1;
2651   }
2652 }
2653
2654 //---
2655 // Bitfield
2656 //---
2657
2658 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2659 class BaseBitfieldImm<bits<2> opc,
2660                       RegisterClass regtype, Operand imm_type, string asm>
2661     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
2662          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
2663       Sched<[WriteIS, ReadI]> {
2664   bits<5> Rd;
2665   bits<5> Rn;
2666   bits<6> immr;
2667   bits<6> imms;
2668
2669   let Inst{30-29} = opc;
2670   let Inst{28-23} = 0b100110;
2671   let Inst{21-16} = immr;
2672   let Inst{15-10} = imms;
2673   let Inst{9-5}   = Rn;
2674   let Inst{4-0}   = Rd;
2675 }
2676
2677 multiclass BitfieldImm<bits<2> opc, string asm> {
2678   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2679     let Inst{31} = 0;
2680     let Inst{22} = 0;
2681     // imms<5> and immr<5> must be zero, else ReservedValue().
2682     let Inst{21} = 0;
2683     let Inst{15} = 0;
2684   }
2685   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2686     let Inst{31} = 1;
2687     let Inst{22} = 1;
2688   }
2689 }
2690
2691 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2692 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2693                       RegisterClass regtype, Operand imm_type, string asm>
2694     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2695                              imm_type:$imms),
2696          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2697       Sched<[WriteIS, ReadI]> {
2698   bits<5> Rd;
2699   bits<5> Rn;
2700   bits<6> immr;
2701   bits<6> imms;
2702
2703   let Inst{30-29} = opc;
2704   let Inst{28-23} = 0b100110;
2705   let Inst{21-16} = immr;
2706   let Inst{15-10} = imms;
2707   let Inst{9-5}   = Rn;
2708   let Inst{4-0}   = Rd;
2709 }
2710
2711 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2712   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2713     let Inst{31} = 0;
2714     let Inst{22} = 0;
2715     // imms<5> and immr<5> must be zero, else ReservedValue().
2716     let Inst{21} = 0;
2717     let Inst{15} = 0;
2718   }
2719   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2720     let Inst{31} = 1;
2721     let Inst{22} = 1;
2722   }
2723 }
2724
2725 //---
2726 // Logical
2727 //---
2728
2729 // Logical (immediate)
2730 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2731                      RegisterClass sregtype, Operand imm_type, string asm,
2732                      list<dag> pattern>
2733     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2734          asm, "\t$Rd, $Rn, $imm", "", pattern>,
2735       Sched<[WriteI, ReadI]> {
2736   bits<5>  Rd;
2737   bits<5>  Rn;
2738   bits<13> imm;
2739   let Inst{30-29} = opc;
2740   let Inst{28-23} = 0b100100;
2741   let Inst{22}    = imm{12};
2742   let Inst{21-16} = imm{11-6};
2743   let Inst{15-10} = imm{5-0};
2744   let Inst{9-5}   = Rn;
2745   let Inst{4-0}   = Rd;
2746
2747   let DecoderMethod = "DecodeLogicalImmInstruction";
2748 }
2749
2750 // Logical (shifted register)
2751 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2752                       logical_shifted_reg shifted_regtype, string asm,
2753                       list<dag> pattern>
2754     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2755         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2756       Sched<[WriteISReg, ReadI, ReadISReg]> {
2757   // The operands are in order to match the 'addr' MI operands, so we
2758   // don't need an encoder method and by-name matching. Just use the default
2759   // in-order handling. Since we're using by-order, make sure the names
2760   // do not match.
2761   bits<5> dst;
2762   bits<5> src1;
2763   bits<5> src2;
2764   bits<8> shift;
2765   let Inst{30-29} = opc;
2766   let Inst{28-24} = 0b01010;
2767   let Inst{23-22} = shift{7-6};
2768   let Inst{21}    = N;
2769   let Inst{20-16} = src2;
2770   let Inst{15-10} = shift{5-0};
2771   let Inst{9-5}   = src1;
2772   let Inst{4-0}   = dst;
2773
2774   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2775 }
2776
2777 // Aliases for register+register logical instructions.
2778 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2779     : InstAlias<asm#"\t$dst, $src1, $src2",
2780                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2781
2782 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2783                       string Alias> {
2784   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2785   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2786                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2787                                                logical_imm32:$imm))]> {
2788     let Inst{31} = 0;
2789     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2790   }
2791   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2792   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2793                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2794                                                logical_imm64:$imm))]> {
2795     let Inst{31} = 1;
2796   }
2797
2798   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2799                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2800                       logical_imm32_not:$imm), 0>;
2801   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2802                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2803                        logical_imm64_not:$imm), 0>;
2804 }
2805
2806 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2807                        string Alias> {
2808   let isCompare = 1, Defs = [NZCV] in {
2809   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2810       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2811     let Inst{31} = 0;
2812     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2813   }
2814   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2815       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2816     let Inst{31} = 1;
2817   }
2818   } // end Defs = [NZCV]
2819
2820   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2821                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2822                       logical_imm32_not:$imm), 0>;
2823   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2824                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2825                        logical_imm64_not:$imm), 0>;
2826 }
2827
2828 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2829     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2830              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2831       Sched<[WriteI, ReadI, ReadI]>;
2832
2833 // Split from LogicalImm as not all instructions have both.
2834 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2835                       SDPatternOperator OpNode> {
2836   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2837   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2838   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2839   }
2840
2841   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2842                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2843                                                  logical_shifted_reg32:$Rm))]> {
2844     let Inst{31} = 0;
2845   }
2846   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2847                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2848                                                  logical_shifted_reg64:$Rm))]> {
2849     let Inst{31} = 1;
2850   }
2851
2852   def : LogicalRegAlias<mnemonic,
2853                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2854   def : LogicalRegAlias<mnemonic,
2855                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2856 }
2857
2858 // Split from LogicalReg to allow setting NZCV Defs
2859 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2860                        SDPatternOperator OpNode = null_frag> {
2861   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2862   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2863   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2864
2865   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2866             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2867     let Inst{31} = 0;
2868   }
2869   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2870             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2871     let Inst{31} = 1;
2872   }
2873   } // Defs = [NZCV]
2874
2875   def : LogicalRegAlias<mnemonic,
2876                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2877   def : LogicalRegAlias<mnemonic,
2878                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2879 }
2880
2881 //---
2882 // Conditionally set flags
2883 //---
2884
2885 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2886 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2887                             string mnemonic, SDNode OpNode>
2888     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2889          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2890          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2891                              (i32 imm:$cond), NZCV))]>,
2892       Sched<[WriteI, ReadI]> {
2893   let Uses = [NZCV];
2894   let Defs = [NZCV];
2895
2896   bits<5> Rn;
2897   bits<5> imm;
2898   bits<4> nzcv;
2899   bits<4> cond;
2900
2901   let Inst{30}    = op;
2902   let Inst{29-21} = 0b111010010;
2903   let Inst{20-16} = imm;
2904   let Inst{15-12} = cond;
2905   let Inst{11-10} = 0b10;
2906   let Inst{9-5}   = Rn;
2907   let Inst{4}     = 0b0;
2908   let Inst{3-0}   = nzcv;
2909 }
2910
2911 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2912 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2913                             SDNode OpNode>
2914     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2915          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2916          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2917                              (i32 imm:$cond), NZCV))]>,
2918       Sched<[WriteI, ReadI, ReadI]> {
2919   let Uses = [NZCV];
2920   let Defs = [NZCV];
2921
2922   bits<5> Rn;
2923   bits<5> Rm;
2924   bits<4> nzcv;
2925   bits<4> cond;
2926
2927   let Inst{30}    = op;
2928   let Inst{29-21} = 0b111010010;
2929   let Inst{20-16} = Rm;
2930   let Inst{15-12} = cond;
2931   let Inst{11-10} = 0b00;
2932   let Inst{9-5}   = Rn;
2933   let Inst{4}     = 0b0;
2934   let Inst{3-0}   = nzcv;
2935 }
2936
2937 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2938   // immediate operand variants
2939   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2940     let Inst{31} = 0;
2941   }
2942   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2943     let Inst{31} = 1;
2944   }
2945   // register operand variants
2946   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2947     let Inst{31} = 0;
2948   }
2949   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2950     let Inst{31} = 1;
2951   }
2952 }
2953
2954 //---
2955 // Conditional select
2956 //---
2957
2958 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2959     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2960          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2961          [(set regtype:$Rd,
2962                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2963       Sched<[WriteI, ReadI, ReadI]> {
2964   let Uses = [NZCV];
2965
2966   bits<5> Rd;
2967   bits<5> Rn;
2968   bits<5> Rm;
2969   bits<4> cond;
2970
2971   let Inst{30}    = op;
2972   let Inst{29-21} = 0b011010100;
2973   let Inst{20-16} = Rm;
2974   let Inst{15-12} = cond;
2975   let Inst{11-10} = op2;
2976   let Inst{9-5}   = Rn;
2977   let Inst{4-0}   = Rd;
2978 }
2979
2980 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2981   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2982     let Inst{31} = 0;
2983   }
2984   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2985     let Inst{31} = 1;
2986   }
2987 }
2988
2989 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2990                        PatFrag frag>
2991     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2992          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2993          [(set regtype:$Rd,
2994                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2995                (i32 imm:$cond), NZCV))]>,
2996       Sched<[WriteI, ReadI, ReadI]> {
2997   let Uses = [NZCV];
2998
2999   bits<5> Rd;
3000   bits<5> Rn;
3001   bits<5> Rm;
3002   bits<4> cond;
3003
3004   let Inst{30}    = op;
3005   let Inst{29-21} = 0b011010100;
3006   let Inst{20-16} = Rm;
3007   let Inst{15-12} = cond;
3008   let Inst{11-10} = op2;
3009   let Inst{9-5}   = Rn;
3010   let Inst{4-0}   = Rd;
3011 }
3012
3013 def inv_cond_XFORM : SDNodeXForm<imm, [{
3014   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
3015   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
3016                                    MVT::i32);
3017 }]>;
3018
3019 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
3020   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
3021     let Inst{31} = 0;
3022   }
3023   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
3024     let Inst{31} = 1;
3025   }
3026
3027   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
3028             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
3029                                            (inv_cond_XFORM imm:$cond))>;
3030
3031   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
3032             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
3033                                            (inv_cond_XFORM imm:$cond))>;
3034 }
3035
3036 //---
3037 // Special Mask Value
3038 //---
3039 def maski8_or_more : Operand<i32>,
3040   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
3041 }
3042 def maski16_or_more : Operand<i32>,
3043   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
3044 }
3045
3046
3047 //---
3048 // Load/store
3049 //---
3050
3051 // (unsigned immediate)
3052 // Indexed for 8-bit registers. offset is in range [0,4095].
3053 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
3054 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
3055 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
3056 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
3057 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
3058
3059 def gi_am_indexed8 :
3060     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
3061     GIComplexPatternEquiv<am_indexed8>;
3062 def gi_am_indexed16 :
3063     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
3064     GIComplexPatternEquiv<am_indexed16>;
3065 def gi_am_indexed32 :
3066     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
3067     GIComplexPatternEquiv<am_indexed32>;
3068 def gi_am_indexed64 :
3069     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
3070     GIComplexPatternEquiv<am_indexed64>;
3071 def gi_am_indexed128 :
3072     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
3073     GIComplexPatternEquiv<am_indexed128>;
3074
3075 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
3076   let Name = "UImm12Offset" # Scale;
3077   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
3078   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
3079   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
3080 }
3081
3082 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
3083 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
3084 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
3085 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
3086 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
3087
3088 class uimm12_scaled<int Scale> : Operand<i64> {
3089   let ParserMatchClass
3090    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
3091   let EncoderMethod
3092    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
3093   let PrintMethod = "printUImm12Offset<" # Scale # ">";
3094 }
3095
3096 def uimm12s1 : uimm12_scaled<1>;
3097 def uimm12s2 : uimm12_scaled<2>;
3098 def uimm12s4 : uimm12_scaled<4>;
3099 def uimm12s8 : uimm12_scaled<8>;
3100 def uimm12s16 : uimm12_scaled<16>;
3101
3102 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3103                       string asm, list<dag> pattern>
3104     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3105   bits<5> Rt;
3106
3107   bits<5> Rn;
3108   bits<12> offset;
3109
3110   let Inst{31-30} = sz;
3111   let Inst{29-27} = 0b111;
3112   let Inst{26}    = V;
3113   let Inst{25-24} = 0b01;
3114   let Inst{23-22} = opc;
3115   let Inst{21-10} = offset;
3116   let Inst{9-5}   = Rn;
3117   let Inst{4-0}   = Rt;
3118
3119   let DecoderMethod = "DecodeUnsignedLdStInstruction";
3120 }
3121
3122 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3123                   Operand indextype, string asm, list<dag> pattern> {
3124   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3125   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
3126                            (ins GPR64sp:$Rn, indextype:$offset),
3127                            asm, pattern>,
3128            Sched<[WriteLD]>;
3129
3130   def : InstAlias<asm # "\t$Rt, [$Rn]",
3131                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3132 }
3133
3134 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3135              Operand indextype, string asm, list<dag> pattern> {
3136   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3137   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3138                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3139                            asm, pattern>,
3140            Sched<[WriteST]>;
3141
3142   def : InstAlias<asm # "\t$Rt, [$Rn]",
3143                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3144 }
3145
3146 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
3147 // substitute zero-registers automatically.
3148 //
3149 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
3150 //       into StoreUI.
3151 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3152              Operand indextype, string asm, list<dag> pattern> {
3153   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3154   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3155                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3156                            asm, pattern>,
3157            Sched<[WriteST]>;
3158
3159   def : InstAlias<asm # "\t$Rt, [$Rn]",
3160                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3161 }
3162
3163 def PrefetchOperand : AsmOperandClass {
3164   let Name = "Prefetch";
3165   let ParserMethod = "tryParsePrefetch";
3166 }
3167 def prfop : Operand<i32> {
3168   let PrintMethod = "printPrefetchOp";
3169   let ParserMatchClass = PrefetchOperand;
3170 }
3171
3172 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3173 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
3174     : BaseLoadStoreUI<sz, V, opc,
3175                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
3176                       asm, pat>,
3177       Sched<[WriteLD]>;
3178
3179 //---
3180 // Load literal
3181 //---
3182
3183 // Load literal address: 19-bit immediate. The low two bits of the target
3184 // offset are implied zero and so are not part of the immediate.
3185 def am_ldrlit : Operand<iPTR> {
3186   let EncoderMethod = "getLoadLiteralOpValue";
3187   let DecoderMethod = "DecodePCRelLabel19";
3188   let PrintMethod = "printAlignedLabel";
3189   let ParserMatchClass = PCRelLabel19Operand;
3190   let OperandType = "OPERAND_PCREL";
3191 }
3192
3193 let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
3194 class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
3195     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
3196         asm, "\t$Rt, $label", "", pat>,
3197       Sched<[WriteLD]> {
3198   bits<5> Rt;
3199   bits<19> label;
3200   let Inst{31-30} = opc;
3201   let Inst{29-27} = 0b011;
3202   let Inst{26}    = V;
3203   let Inst{25-24} = 0b00;
3204   let Inst{23-5}  = label;
3205   let Inst{4-0}   = Rt;
3206 }
3207
3208 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3209 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
3210     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
3211         asm, "\t$Rt, $label", "", pat>,
3212       Sched<[WriteLD]> {
3213   bits<5> Rt;
3214   bits<19> label;
3215   let Inst{31-30} = opc;
3216   let Inst{29-27} = 0b011;
3217   let Inst{26}    = V;
3218   let Inst{25-24} = 0b00;
3219   let Inst{23-5}  = label;
3220   let Inst{4-0}   = Rt;
3221 }
3222
3223 //---
3224 // Load/store register offset
3225 //---
3226
3227 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
3228 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
3229 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
3230 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
3231 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
3232
3233 def gi_ro_Xindexed8 :
3234     GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">,
3235     GIComplexPatternEquiv<ro_Xindexed8>;
3236 def gi_ro_Xindexed16 :
3237     GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">,
3238     GIComplexPatternEquiv<ro_Xindexed16>;
3239 def gi_ro_Xindexed32 :
3240     GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">,
3241     GIComplexPatternEquiv<ro_Xindexed32>;
3242 def gi_ro_Xindexed64 :
3243     GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">,
3244     GIComplexPatternEquiv<ro_Xindexed64>;
3245 def gi_ro_Xindexed128 :
3246     GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">,
3247     GIComplexPatternEquiv<ro_Xindexed128>;
3248
3249 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
3250 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
3251 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
3252 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
3253 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
3254
3255 def gi_ro_Windexed8 :
3256     GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">,
3257     GIComplexPatternEquiv<ro_Windexed8>;
3258 def gi_ro_Windexed16 :
3259     GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">,
3260     GIComplexPatternEquiv<ro_Windexed16>;
3261 def gi_ro_Windexed32 :
3262     GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">,
3263     GIComplexPatternEquiv<ro_Windexed32>;
3264 def gi_ro_Windexed64 :
3265     GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">,
3266     GIComplexPatternEquiv<ro_Windexed64>;
3267 def gi_ro_Windexed128 :
3268     GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">,
3269     GIComplexPatternEquiv<ro_Windexed128>;
3270
3271 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
3272   let Name = "Mem" # Reg # "Extend" # Width;
3273   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
3274   let RenderMethod = "addMemExtendOperands";
3275   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
3276 }
3277
3278 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
3279   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3280   // the trivial shift.
3281   let RenderMethod = "addMemExtend8Operands";
3282 }
3283 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
3284 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
3285 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
3286 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
3287
3288 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
3289   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3290   // the trivial shift.
3291   let RenderMethod = "addMemExtend8Operands";
3292 }
3293 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
3294 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
3295 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
3296 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
3297
3298 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
3299         : Operand<i32> {
3300   let ParserMatchClass = ParserClass;
3301   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
3302   let DecoderMethod = "DecodeMemExtend";
3303   let EncoderMethod = "getMemExtendOpValue";
3304   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
3305 }
3306
3307 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
3308 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
3309 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
3310 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
3311 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
3312
3313 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
3314 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
3315 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
3316 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
3317 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
3318
3319 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
3320                   Operand wextend, Operand xextend>  {
3321   // CodeGen-level pattern covering the entire addressing mode.
3322   ComplexPattern Wpat = windex;
3323   ComplexPattern Xpat = xindex;
3324
3325   // Asm-level Operand covering the valid "uxtw #3" style syntax.
3326   Operand Wext = wextend;
3327   Operand Xext = xextend;
3328 }
3329
3330 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
3331 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
3332 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
3333 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
3334 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
3335                        ro_Xextend128>;
3336
3337 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3338                       string asm, dag ins, dag outs, list<dag> pat>
3339     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3340   bits<5> Rt;
3341   bits<5> Rn;
3342   bits<5> Rm;
3343   bits<2> extend;
3344   let Inst{31-30} = sz;
3345   let Inst{29-27} = 0b111;
3346   let Inst{26}    = V;
3347   let Inst{25-24} = 0b00;
3348   let Inst{23-22} = opc;
3349   let Inst{21}    = 1;
3350   let Inst{20-16} = Rm;
3351   let Inst{15}    = extend{1}; // sign extend Rm?
3352   let Inst{14}    = 1;
3353   let Inst{12}    = extend{0}; // do shift?
3354   let Inst{11-10} = 0b10;
3355   let Inst{9-5}   = Rn;
3356   let Inst{4-0}   = Rt;
3357 }
3358
3359 class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST>
3360   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
3361               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3362
3363 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3364                    string asm, ValueType Ty, SDPatternOperator loadop> {
3365   let AddedComplexity = 10 in
3366   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
3367                  (outs regtype:$Rt),
3368                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3369                  [(set (Ty regtype:$Rt),
3370                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3371                                              ro_Wextend8:$extend)))]>,
3372            Sched<[WriteLDIdx, ReadAdrBase]> {
3373     let Inst{13} = 0b0;
3374   }
3375
3376   let AddedComplexity = 10 in
3377   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
3378                  (outs regtype:$Rt),
3379                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3380                  [(set (Ty regtype:$Rt),
3381                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3382                                              ro_Xextend8:$extend)))]>,
3383            Sched<[WriteLDIdx, ReadAdrBase]> {
3384     let Inst{13} = 0b1;
3385   }
3386
3387   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3388 }
3389
3390 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3391                     string asm, ValueType Ty, SDPatternOperator storeop> {
3392   let AddedComplexity = 10 in
3393   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3394                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3395                  [(storeop (Ty regtype:$Rt),
3396                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3397                                          ro_Wextend8:$extend))]>,
3398             Sched<[WriteSTIdx, ReadAdrBase]> {
3399     let Inst{13} = 0b0;
3400   }
3401
3402   let AddedComplexity = 10 in
3403   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3404                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3405                  [(storeop (Ty regtype:$Rt),
3406                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3407                                          ro_Xextend8:$extend))]>,
3408             Sched<[WriteSTIdx, ReadAdrBase]> {
3409     let Inst{13} = 0b1;
3410   }
3411
3412   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3413 }
3414
3415 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3416                       string asm, dag ins, dag outs, list<dag> pat>
3417     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3418   bits<5> Rt;
3419   bits<5> Rn;
3420   bits<5> Rm;
3421   bits<2> extend;
3422   let Inst{31-30} = sz;
3423   let Inst{29-27} = 0b111;
3424   let Inst{26}    = V;
3425   let Inst{25-24} = 0b00;
3426   let Inst{23-22} = opc;
3427   let Inst{21}    = 1;
3428   let Inst{20-16} = Rm;
3429   let Inst{15}    = extend{1}; // sign extend Rm?
3430   let Inst{14}    = 1;
3431   let Inst{12}    = extend{0}; // do shift?
3432   let Inst{11-10} = 0b10;
3433   let Inst{9-5}   = Rn;
3434   let Inst{4-0}   = Rt;
3435 }
3436
3437 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3438                     string asm, ValueType Ty, SDPatternOperator loadop> {
3439   let AddedComplexity = 10 in
3440   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3441                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3442                  [(set (Ty regtype:$Rt),
3443                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3444                                               ro_Wextend16:$extend)))]>,
3445             Sched<[WriteLDIdx, ReadAdrBase]> {
3446     let Inst{13} = 0b0;
3447   }
3448
3449   let AddedComplexity = 10 in
3450   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3451                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3452                  [(set (Ty regtype:$Rt),
3453                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3454                                              ro_Xextend16:$extend)))]>,
3455             Sched<[WriteLDIdx, ReadAdrBase]> {
3456     let Inst{13} = 0b1;
3457   }
3458
3459   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3460 }
3461
3462 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3463                      string asm, ValueType Ty, SDPatternOperator storeop> {
3464   let AddedComplexity = 10 in
3465   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3466                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3467                 [(storeop (Ty regtype:$Rt),
3468                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3469                                          ro_Wextend16:$extend))]>,
3470            Sched<[WriteSTIdx, ReadAdrBase]> {
3471     let Inst{13} = 0b0;
3472   }
3473
3474   let AddedComplexity = 10 in
3475   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3476                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3477                 [(storeop (Ty regtype:$Rt),
3478                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3479                                          ro_Xextend16:$extend))]>,
3480            Sched<[WriteSTIdx, ReadAdrBase]> {
3481     let Inst{13} = 0b1;
3482   }
3483
3484   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3485 }
3486
3487 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3488                       string asm, dag ins, dag outs, list<dag> pat>
3489     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3490   bits<5> Rt;
3491   bits<5> Rn;
3492   bits<5> Rm;
3493   bits<2> extend;
3494   let Inst{31-30} = sz;
3495   let Inst{29-27} = 0b111;
3496   let Inst{26}    = V;
3497   let Inst{25-24} = 0b00;
3498   let Inst{23-22} = opc;
3499   let Inst{21}    = 1;
3500   let Inst{20-16} = Rm;
3501   let Inst{15}    = extend{1}; // sign extend Rm?
3502   let Inst{14}    = 1;
3503   let Inst{12}    = extend{0}; // do shift?
3504   let Inst{11-10} = 0b10;
3505   let Inst{9-5}   = Rn;
3506   let Inst{4-0}   = Rt;
3507 }
3508
3509 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3510                     string asm, ValueType Ty, SDPatternOperator loadop> {
3511   let AddedComplexity = 10 in
3512   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3513                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3514                  [(set (Ty regtype:$Rt),
3515                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3516                                               ro_Wextend32:$extend)))]>,
3517            Sched<[WriteLDIdx, ReadAdrBase]> {
3518     let Inst{13} = 0b0;
3519   }
3520
3521   let AddedComplexity = 10 in
3522   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3523                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3524                  [(set (Ty regtype:$Rt),
3525                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3526                                               ro_Xextend32:$extend)))]>,
3527            Sched<[WriteLDIdx, ReadAdrBase]> {
3528     let Inst{13} = 0b1;
3529   }
3530
3531   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3532 }
3533
3534 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3535                      string asm, ValueType Ty, SDPatternOperator storeop> {
3536   let AddedComplexity = 10 in
3537   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3538                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3539                 [(storeop (Ty regtype:$Rt),
3540                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3541                                          ro_Wextend32:$extend))]>,
3542             Sched<[WriteSTIdx, ReadAdrBase]> {
3543     let Inst{13} = 0b0;
3544   }
3545
3546   let AddedComplexity = 10 in
3547   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3548                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3549                 [(storeop (Ty regtype:$Rt),
3550                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3551                                         ro_Xextend32:$extend))]>,
3552             Sched<[WriteSTIdx, ReadAdrBase]> {
3553     let Inst{13} = 0b1;
3554   }
3555
3556   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3557 }
3558
3559 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3560                       string asm, dag ins, dag outs, list<dag> pat>
3561     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3562   bits<5> Rt;
3563   bits<5> Rn;
3564   bits<5> Rm;
3565   bits<2> extend;
3566   let Inst{31-30} = sz;
3567   let Inst{29-27} = 0b111;
3568   let Inst{26}    = V;
3569   let Inst{25-24} = 0b00;
3570   let Inst{23-22} = opc;
3571   let Inst{21}    = 1;
3572   let Inst{20-16} = Rm;
3573   let Inst{15}    = extend{1}; // sign extend Rm?
3574   let Inst{14}    = 1;
3575   let Inst{12}    = extend{0}; // do shift?
3576   let Inst{11-10} = 0b10;
3577   let Inst{9-5}   = Rn;
3578   let Inst{4-0}   = Rt;
3579 }
3580
3581 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3582                     string asm, ValueType Ty, SDPatternOperator loadop> {
3583   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3584   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3585                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3586                 [(set (Ty regtype:$Rt),
3587                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3588                                              ro_Wextend64:$extend)))]>,
3589            Sched<[WriteLDIdx, ReadAdrBase]> {
3590     let Inst{13} = 0b0;
3591   }
3592
3593   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3594   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3595                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3596                  [(set (Ty regtype:$Rt),
3597                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3598                                               ro_Xextend64:$extend)))]>,
3599            Sched<[WriteLDIdx, ReadAdrBase]> {
3600     let Inst{13} = 0b1;
3601   }
3602
3603   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3604 }
3605
3606 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3607                      string asm, ValueType Ty, SDPatternOperator storeop> {
3608   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3609   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3610                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3611                 [(storeop (Ty regtype:$Rt),
3612                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3613                                          ro_Wextend64:$extend))]>,
3614             Sched<[WriteSTIdx, ReadAdrBase]> {
3615     let Inst{13} = 0b0;
3616   }
3617
3618   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3619   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3620                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3621                 [(storeop (Ty regtype:$Rt),
3622                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3623                                          ro_Xextend64:$extend))]>,
3624             Sched<[WriteSTIdx, ReadAdrBase]> {
3625     let Inst{13} = 0b1;
3626   }
3627
3628   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3629 }
3630
3631 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3632                       string asm, dag ins, dag outs, list<dag> pat>
3633     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3634   bits<5> Rt;
3635   bits<5> Rn;
3636   bits<5> Rm;
3637   bits<2> extend;
3638   let Inst{31-30} = sz;
3639   let Inst{29-27} = 0b111;
3640   let Inst{26}    = V;
3641   let Inst{25-24} = 0b00;
3642   let Inst{23-22} = opc;
3643   let Inst{21}    = 1;
3644   let Inst{20-16} = Rm;
3645   let Inst{15}    = extend{1}; // sign extend Rm?
3646   let Inst{14}    = 1;
3647   let Inst{12}    = extend{0}; // do shift?
3648   let Inst{11-10} = 0b10;
3649   let Inst{9-5}   = Rn;
3650   let Inst{4-0}   = Rt;
3651 }
3652
3653 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3654                      string asm, ValueType Ty, SDPatternOperator loadop> {
3655   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3656   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3657                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3658                  [(set (Ty regtype:$Rt),
3659                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
3660                                                ro_Wextend128:$extend)))]>,
3661             Sched<[WriteLDIdx, ReadAdrBase]> {
3662     let Inst{13} = 0b0;
3663   }
3664
3665   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3666   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3667                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3668                  [(set (Ty regtype:$Rt),
3669                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
3670                                                ro_Xextend128:$extend)))]>,
3671             Sched<[WriteLDIdx, ReadAdrBase]> {
3672     let Inst{13} = 0b1;
3673   }
3674
3675   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3676 }
3677
3678 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3679                       string asm, ValueType Ty, SDPatternOperator storeop> {
3680   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3681   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3682                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3683                 []>,
3684             Sched<[WriteSTIdx, ReadAdrBase]> {
3685     let Inst{13} = 0b0;
3686   }
3687
3688   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3689   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3690                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3691                 []>,
3692             Sched<[WriteSTIdx, ReadAdrBase]> {
3693     let Inst{13} = 0b1;
3694   }
3695
3696   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3697 }
3698
3699 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3700 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
3701                      string asm, list<dag> pat>
3702     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
3703       Sched<[WriteLD]> {
3704   bits<5> Rt;
3705   bits<5> Rn;
3706   bits<5> Rm;
3707   bits<2> extend;
3708   let Inst{31-30} = sz;
3709   let Inst{29-27} = 0b111;
3710   let Inst{26}    = V;
3711   let Inst{25-24} = 0b00;
3712   let Inst{23-22} = opc;
3713   let Inst{21}    = 1;
3714   let Inst{20-16} = Rm;
3715   let Inst{15}    = extend{1}; // sign extend Rm?
3716   let Inst{14}    = 1;
3717   let Inst{12}    = extend{0}; // do shift?
3718   let Inst{11-10} = 0b10;
3719   let Inst{9-5}   = Rn;
3720   let Inst{4-0}   = Rt;
3721 }
3722
3723 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
3724   def roW : BasePrefetchRO<sz, V, opc, (outs),
3725                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3726                 asm, [(AArch64Prefetch imm:$Rt,
3727                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3728                                                     ro_Wextend64:$extend))]> {
3729     let Inst{13} = 0b0;
3730   }
3731
3732   def roX : BasePrefetchRO<sz, V, opc, (outs),
3733                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3734                 asm,  [(AArch64Prefetch imm:$Rt,
3735                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3736                                                      ro_Xextend64:$extend))]> {
3737     let Inst{13} = 0b1;
3738   }
3739
3740   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3741                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3742                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3743 }
3744
3745 //---
3746 // Load/store unscaled immediate
3747 //---
3748
3749 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3750 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3751 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3752 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3753 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3754
3755 def gi_am_unscaled8 :
3756     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
3757     GIComplexPatternEquiv<am_unscaled8>;
3758 def gi_am_unscaled16 :
3759     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
3760     GIComplexPatternEquiv<am_unscaled16>;
3761 def gi_am_unscaled32 :
3762     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
3763     GIComplexPatternEquiv<am_unscaled32>;
3764 def gi_am_unscaled64 :
3765     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
3766     GIComplexPatternEquiv<am_unscaled64>;
3767 def gi_am_unscaled128 :
3768     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
3769     GIComplexPatternEquiv<am_unscaled128>;
3770
3771
3772 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3773                            string asm, list<dag> pattern>
3774     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3775   bits<5> Rt;
3776   bits<5> Rn;
3777   bits<9> offset;
3778   let Inst{31-30} = sz;
3779   let Inst{29-27} = 0b111;
3780   let Inst{26}    = V;
3781   let Inst{25-24} = 0b00;
3782   let Inst{23-22} = opc;
3783   let Inst{21}    = 0;
3784   let Inst{20-12} = offset;
3785   let Inst{11-10} = 0b00;
3786   let Inst{9-5}   = Rn;
3787   let Inst{4-0}   = Rt;
3788
3789   let DecoderMethod = "DecodeSignedLdStInstruction";
3790 }
3791
3792 // Armv8.4 LDAPR & STLR with Immediate Offset instruction
3793 multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3794                               RegisterOperand regtype > {
3795   def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),
3796                                (ins GPR64sp:$Rn, simm9:$offset), asm, []>,
3797           Sched<[WriteST]> {
3798     let Inst{29} = 0;
3799     let Inst{24} = 1;
3800   }
3801   def : InstAlias<asm # "\t$Rt, [$Rn]",
3802                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3803 }
3804
3805 multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3806                                RegisterOperand regtype > {
3807   def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),
3808                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3809                                asm, []>,
3810           Sched<[WriteST]> {
3811     let Inst{29} = 0;
3812     let Inst{24} = 1;
3813   }
3814   def : InstAlias<asm # "\t$Rt, [$Rn]",
3815                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3816 }
3817
3818 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3819                    string asm, list<dag> pattern> {
3820   let AddedComplexity = 1 in // try this before LoadUI
3821   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3822                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3823           Sched<[WriteLD]>;
3824
3825   def : InstAlias<asm # "\t$Rt, [$Rn]",
3826                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3827 }
3828
3829 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3830                          string asm, list<dag> pattern> {
3831   let AddedComplexity = 1 in // try this before StoreUI
3832   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3833                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3834                                asm, pattern>,
3835           Sched<[WriteST]>;
3836
3837   def : InstAlias<asm # "\t$Rt, [$Rn]",
3838                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3839 }
3840
3841 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3842                             list<dag> pat> {
3843   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3844   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3845                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3846                                asm, pat>,
3847           Sched<[WriteLD]>;
3848
3849   def : InstAlias<asm # "\t$Rt, [$Rn]",
3850                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3851 }
3852
3853 //---
3854 // Load/store unscaled immediate, unprivileged
3855 //---
3856
3857 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3858                                 dag oops, dag iops, string asm>
3859     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3860   bits<5> Rt;
3861   bits<5> Rn;
3862   bits<9> offset;
3863   let Inst{31-30} = sz;
3864   let Inst{29-27} = 0b111;
3865   let Inst{26}    = V;
3866   let Inst{25-24} = 0b00;
3867   let Inst{23-22} = opc;
3868   let Inst{21}    = 0;
3869   let Inst{20-12} = offset;
3870   let Inst{11-10} = 0b10;
3871   let Inst{9-5}   = Rn;
3872   let Inst{4-0}   = Rt;
3873
3874   let DecoderMethod = "DecodeSignedLdStInstruction";
3875 }
3876
3877 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3878                             RegisterClass regtype, string asm> {
3879   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3880   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3881                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
3882           Sched<[WriteLD]>;
3883
3884   def : InstAlias<asm # "\t$Rt, [$Rn]",
3885                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3886 }
3887
3888 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3889                              RegisterClass regtype, string asm> {
3890   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3891   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3892                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3893                                  asm>,
3894           Sched<[WriteST]>;
3895
3896   def : InstAlias<asm # "\t$Rt, [$Rn]",
3897                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3898 }
3899
3900 //---
3901 // Load/store pre-indexed
3902 //---
3903
3904 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3905                           string asm, string cstr, list<dag> pat>
3906     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3907   bits<5> Rt;
3908   bits<5> Rn;
3909   bits<9> offset;
3910   let Inst{31-30} = sz;
3911   let Inst{29-27} = 0b111;
3912   let Inst{26}    = V;
3913   let Inst{25-24} = 0;
3914   let Inst{23-22} = opc;
3915   let Inst{21}    = 0;
3916   let Inst{20-12} = offset;
3917   let Inst{11-10} = 0b11;
3918   let Inst{9-5}   = Rn;
3919   let Inst{4-0}   = Rt;
3920
3921   let DecoderMethod = "DecodeSignedLdStInstruction";
3922 }
3923
3924 let hasSideEffects = 0 in {
3925 let mayStore = 0, mayLoad = 1 in
3926 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3927              string asm>
3928     : BaseLoadStorePreIdx<sz, V, opc,
3929                      (outs GPR64sp:$wback, regtype:$Rt),
3930                      (ins GPR64sp:$Rn, simm9:$offset), asm,
3931                      "$Rn = $wback,@earlyclobber $wback", []>,
3932       Sched<[WriteLD, WriteAdr]>;
3933
3934 let mayStore = 1, mayLoad = 0 in
3935 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3936                   string asm, SDPatternOperator storeop, ValueType Ty>
3937     : BaseLoadStorePreIdx<sz, V, opc,
3938                       (outs GPR64sp:$wback),
3939                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3940                       asm, "$Rn = $wback,@earlyclobber $wback",
3941       [(set GPR64sp:$wback,
3942             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3943       Sched<[WriteAdr, WriteST]>;
3944 } // hasSideEffects = 0
3945
3946 //---
3947 // Load/store post-indexed
3948 //---
3949
3950 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3951                           string asm, string cstr, list<dag> pat>
3952     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3953   bits<5> Rt;
3954   bits<5> Rn;
3955   bits<9> offset;
3956   let Inst{31-30} = sz;
3957   let Inst{29-27} = 0b111;
3958   let Inst{26}    = V;
3959   let Inst{25-24} = 0b00;
3960   let Inst{23-22} = opc;
3961   let Inst{21}    = 0b0;
3962   let Inst{20-12} = offset;
3963   let Inst{11-10} = 0b01;
3964   let Inst{9-5}   = Rn;
3965   let Inst{4-0}   = Rt;
3966
3967   let DecoderMethod = "DecodeSignedLdStInstruction";
3968 }
3969
3970 let hasSideEffects = 0 in {
3971 let mayStore = 0, mayLoad = 1 in
3972 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3973              string asm>
3974     : BaseLoadStorePostIdx<sz, V, opc,
3975                       (outs GPR64sp:$wback, regtype:$Rt),
3976                       (ins GPR64sp:$Rn, simm9:$offset),
3977                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
3978       Sched<[WriteLD, WriteAdr]>;
3979
3980 let mayStore = 1, mayLoad = 0 in
3981 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3982                    string asm, SDPatternOperator storeop, ValueType Ty>
3983     : BaseLoadStorePostIdx<sz, V, opc,
3984                       (outs GPR64sp:$wback),
3985                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3986                        asm, "$Rn = $wback,@earlyclobber $wback",
3987       [(set GPR64sp:$wback,
3988             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3989     Sched<[WriteAdr, WriteST]>;
3990 } // hasSideEffects = 0
3991
3992
3993 //---
3994 // Load/store pair
3995 //---
3996
3997 // (indexed, offset)
3998
3999 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
4000                               string asm>
4001     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4002   bits<5> Rt;
4003   bits<5> Rt2;
4004   bits<5> Rn;
4005   bits<7> offset;
4006   let Inst{31-30} = opc;
4007   let Inst{29-27} = 0b101;
4008   let Inst{26}    = V;
4009   let Inst{25-23} = 0b010;
4010   let Inst{22}    = L;
4011   let Inst{21-15} = offset;
4012   let Inst{14-10} = Rt2;
4013   let Inst{9-5}   = Rn;
4014   let Inst{4-0}   = Rt;
4015
4016   let DecoderMethod = "DecodePairLdStInstruction";
4017 }
4018
4019 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4020                           Operand indextype, string asm> {
4021   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4022   def i : BaseLoadStorePairOffset<opc, V, 1,
4023                                   (outs regtype:$Rt, regtype:$Rt2),
4024                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
4025           Sched<[WriteLD, WriteLDHi]>;
4026
4027   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4028                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4029                                                   GPR64sp:$Rn, 0)>;
4030 }
4031
4032
4033 multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4034                            Operand indextype, string asm> {
4035   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
4036   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
4037                                   (ins regtype:$Rt, regtype:$Rt2,
4038                                        GPR64sp:$Rn, indextype:$offset),
4039                                   asm>,
4040           Sched<[WriteSTP]>;
4041
4042   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4043                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4044                                                   GPR64sp:$Rn, 0)>;
4045 }
4046
4047 // (pre-indexed)
4048 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4049                               string asm>
4050     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
4051   bits<5> Rt;
4052   bits<5> Rt2;
4053   bits<5> Rn;
4054   bits<7> offset;
4055   let Inst{31-30} = opc;
4056   let Inst{29-27} = 0b101;
4057   let Inst{26}    = V;
4058   let Inst{25-23} = 0b011;
4059   let Inst{22}    = L;
4060   let Inst{21-15} = offset;
4061   let Inst{14-10} = Rt2;
4062   let Inst{9-5}   = Rn;
4063   let Inst{4-0}   = Rt;
4064
4065   let DecoderMethod = "DecodePairLdStInstruction";
4066 }
4067
4068 let hasSideEffects = 0 in {
4069 let mayStore = 0, mayLoad = 1 in
4070 class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4071                      Operand indextype, string asm>
4072     : BaseLoadStorePairPreIdx<opc, V, 1,
4073                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4074                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
4075       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
4076
4077 let mayStore = 1, mayLoad = 0 in
4078 class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4079                       Operand indextype, string asm>
4080     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
4081                              (ins regtype:$Rt, regtype:$Rt2,
4082                                   GPR64sp:$Rn, indextype:$offset),
4083                              asm>,
4084       Sched<[WriteAdr, WriteSTP]>;
4085 } // hasSideEffects = 0
4086
4087 // (post-indexed)
4088
4089 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4090                               string asm>
4091     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
4092   bits<5> Rt;
4093   bits<5> Rt2;
4094   bits<5> Rn;
4095   bits<7> offset;
4096   let Inst{31-30} = opc;
4097   let Inst{29-27} = 0b101;
4098   let Inst{26}    = V;
4099   let Inst{25-23} = 0b001;
4100   let Inst{22}    = L;
4101   let Inst{21-15} = offset;
4102   let Inst{14-10} = Rt2;
4103   let Inst{9-5}   = Rn;
4104   let Inst{4-0}   = Rt;
4105
4106   let DecoderMethod = "DecodePairLdStInstruction";
4107 }
4108
4109 let hasSideEffects = 0 in {
4110 let mayStore = 0, mayLoad = 1 in
4111 class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4112                       Operand idxtype, string asm>
4113     : BaseLoadStorePairPostIdx<opc, V, 1,
4114                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4115                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
4116       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
4117
4118 let mayStore = 1, mayLoad = 0 in
4119 class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4120                        Operand idxtype, string asm>
4121     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
4122                              (ins regtype:$Rt, regtype:$Rt2,
4123                                   GPR64sp:$Rn, idxtype:$offset),
4124                              asm>,
4125       Sched<[WriteAdr, WriteSTP]>;
4126 } // hasSideEffects = 0
4127
4128 //  (no-allocate)
4129
4130 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
4131                               string asm>
4132     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4133   bits<5> Rt;
4134   bits<5> Rt2;
4135   bits<5> Rn;
4136   bits<7> offset;
4137   let Inst{31-30} = opc;
4138   let Inst{29-27} = 0b101;
4139   let Inst{26}    = V;
4140   let Inst{25-23} = 0b000;
4141   let Inst{22}    = L;
4142   let Inst{21-15} = offset;
4143   let Inst{14-10} = Rt2;
4144   let Inst{9-5}   = Rn;
4145   let Inst{4-0}   = Rt;
4146
4147   let DecoderMethod = "DecodePairLdStInstruction";
4148 }
4149
4150 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
4151                            Operand indextype, string asm> {
4152   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4153   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
4154                                    (outs regtype:$Rt, regtype:$Rt2),
4155                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
4156           Sched<[WriteLD, WriteLDHi]>;
4157
4158
4159   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4160                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4161                                                   GPR64sp:$Rn, 0)>;
4162 }
4163
4164 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
4165                       Operand indextype, string asm> {
4166   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
4167   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
4168                                    (ins regtype:$Rt, regtype:$Rt2,
4169                                         GPR64sp:$Rn, indextype:$offset),
4170                                    asm>,
4171           Sched<[WriteSTP]>;
4172
4173   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4174                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4175                                                   GPR64sp:$Rn, 0)>;
4176 }
4177
4178 //---
4179 // Load/store exclusive
4180 //---
4181
4182 // True exclusive operations write to and/or read from the system's exclusive
4183 // monitors, which as far as a compiler is concerned can be modelled as a
4184 // random shared memory address. Hence LoadExclusive mayStore.
4185 //
4186 // Since these instructions have the undefined register bits set to 1 in
4187 // their canonical form, we need a post encoder method to set those bits
4188 // to 1 when encoding these instructions. We do this using the
4189 // fixLoadStoreExclusive function. This function has template parameters:
4190 //
4191 // fixLoadStoreExclusive<int hasRs, int hasRt2>
4192 //
4193 // hasRs indicates that the instruction uses the Rs field, so we won't set
4194 // it to 1 (and the same for Rt2). We don't need template parameters for
4195 // the other register fields since Rt and Rn are always used.
4196 //
4197 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
4198 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4199                              dag oops, dag iops, string asm, string operands>
4200     : I<oops, iops, asm, operands, "", []> {
4201   let Inst{31-30} = sz;
4202   let Inst{29-24} = 0b001000;
4203   let Inst{23}    = o2;
4204   let Inst{22}    = L;
4205   let Inst{21}    = o1;
4206   let Inst{15}    = o0;
4207
4208   let DecoderMethod = "DecodeExclusiveLdStInstruction";
4209 }
4210
4211 // Neither Rs nor Rt2 operands.
4212 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4213                                dag oops, dag iops, string asm, string operands>
4214     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
4215   bits<5> Rt;
4216   bits<5> Rn;
4217   let Inst{20-16} = 0b11111;
4218   let Unpredictable{20-16} = 0b11111;
4219   let Inst{14-10} = 0b11111;
4220   let Unpredictable{14-10} = 0b11111;
4221   let Inst{9-5} = Rn;
4222   let Inst{4-0} = Rt;
4223
4224   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
4225 }
4226
4227 // Simple load acquires don't set the exclusive monitor
4228 let mayLoad = 1, mayStore = 0 in
4229 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4230                   RegisterClass regtype, string asm>
4231     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4232                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4233       Sched<[WriteLD]>;
4234
4235 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4236                     RegisterClass regtype, string asm>
4237     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4238                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4239       Sched<[WriteLD]>;
4240
4241 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4242                        RegisterClass regtype, string asm>
4243     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4244                              (outs regtype:$Rt, regtype:$Rt2),
4245                              (ins GPR64sp0:$Rn), asm,
4246                              "\t$Rt, $Rt2, [$Rn]">,
4247       Sched<[WriteLD, WriteLDHi]> {
4248   bits<5> Rt;
4249   bits<5> Rt2;
4250   bits<5> Rn;
4251   let Inst{14-10} = Rt2;
4252   let Inst{9-5} = Rn;
4253   let Inst{4-0} = Rt;
4254
4255   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
4256 }
4257
4258 // Simple store release operations do not check the exclusive monitor.
4259 let mayLoad = 0, mayStore = 1 in
4260 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4261                    RegisterClass regtype, string asm>
4262     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
4263                                (ins regtype:$Rt, GPR64sp0:$Rn),
4264                                asm, "\t$Rt, [$Rn]">,
4265       Sched<[WriteST]>;
4266
4267 let mayLoad = 1, mayStore = 1 in
4268 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4269                      RegisterClass regtype, string asm>
4270     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
4271                              (ins regtype:$Rt, GPR64sp0:$Rn),
4272                              asm, "\t$Ws, $Rt, [$Rn]">,
4273       Sched<[WriteSTX]> {
4274   bits<5> Ws;
4275   bits<5> Rt;
4276   bits<5> Rn;
4277   let Inst{20-16} = Ws;
4278   let Inst{9-5} = Rn;
4279   let Inst{4-0} = Rt;
4280
4281   let Constraints = "@earlyclobber $Ws";
4282   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
4283 }
4284
4285 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4286                          RegisterClass regtype, string asm>
4287     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4288                              (outs GPR32:$Ws),
4289                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
4290                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
4291       Sched<[WriteSTX]> {
4292   bits<5> Ws;
4293   bits<5> Rt;
4294   bits<5> Rt2;
4295   bits<5> Rn;
4296   let Inst{20-16} = Ws;
4297   let Inst{14-10} = Rt2;
4298   let Inst{9-5} = Rn;
4299   let Inst{4-0} = Rt;
4300
4301   let Constraints = "@earlyclobber $Ws";
4302 }
4303
4304 // Armv8.5-A Memory Tagging Extension
4305 class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn,
4306                  string asm_opnds, string cstr, dag oops, dag iops>
4307     : I<oops, iops, asm_insn, asm_opnds, cstr, []>,
4308       Sched<[]> {
4309   bits<5> Rn;
4310
4311   let Inst{31-24} = 0b11011001;
4312   let Inst{23-22} = opc1;
4313   let Inst{21}    = 1;
4314   // Inst{20-12} defined by subclass
4315   let Inst{11-10} = opc2;
4316   let Inst{9-5}   = Rn;
4317   // Inst{4-0} defined by subclass
4318 }
4319
4320 class MemTagVector<bit Load, string asm_insn, string asm_opnds,
4321                    dag oops, dag iops>
4322     : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,
4323                   "", oops, iops> {
4324   bits<5> Rt;
4325
4326   let Inst{20-12} = 0b000000000;
4327   let Inst{4-0}   = Rt;
4328
4329   let mayLoad = Load;
4330 }
4331
4332 class MemTagLoad<string asm_insn, string asm_opnds>
4333     : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback",
4334                  (outs GPR64:$wback),
4335                  (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> {
4336   bits<5> Rt;
4337   bits<9> offset;
4338
4339   let Inst{20-12} = offset;
4340   let Inst{4-0}   = Rt;
4341
4342   let mayLoad = 1;
4343 }
4344
4345 class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn,
4346                      string asm_opnds, string cstr, dag oops, dag iops>
4347     : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> {
4348   bits<5> Rt;
4349   bits<9> offset;
4350
4351   let Inst{20-12} = offset;
4352   let Inst{4-0}   = Rt;
4353
4354   let mayStore = 1;
4355 }
4356
4357 multiclass MemTagStore<bits<2> opc1, string insn> {
4358   def Offset :
4359     BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",
4360                     (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4361   def PreIndex :
4362     BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",
4363                     "$Rn = $wback",
4364                     (outs GPR64sp:$wback),
4365                     (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4366   def PostIndex :
4367     BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",
4368                     "$Rn = $wback",
4369                     (outs GPR64sp:$wback),
4370                     (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4371
4372   def : InstAlias<insn # "\t$Rt, [$Rn]",
4373                   (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>;
4374 }
4375
4376 //---
4377 // Exception generation
4378 //---
4379
4380 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
4381 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
4382     : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>,
4383       Sched<[WriteSys]> {
4384   bits<16> imm;
4385   let Inst{31-24} = 0b11010100;
4386   let Inst{23-21} = op1;
4387   let Inst{20-5}  = imm;
4388   let Inst{4-2}   = 0b000;
4389   let Inst{1-0}   = ll;
4390 }
4391
4392 //---
4393 // UDF : Permanently UNDEFINED instructions.  Format: Opc = 0x0000, 16 bit imm.
4394 //--
4395 let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in {
4396 class UDFType<bits<16> opc, string asm>
4397   : I<(outs), (ins uimm16:$imm),
4398        asm, "\t$imm", "", []>,
4399     Sched<[]> {
4400   bits<16> imm;
4401   let Inst{31-16} = opc;
4402   let Inst{15-0} = imm;
4403 }
4404 }
4405 let Predicates = [HasFPARMv8] in {
4406
4407 //---
4408 // Floating point to integer conversion
4409 //---
4410
4411 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
4412                       RegisterClass srcType, RegisterClass dstType,
4413                       string asm, list<dag> pattern>
4414     : I<(outs dstType:$Rd), (ins srcType:$Rn),
4415          asm, "\t$Rd, $Rn", "", pattern>,
4416       Sched<[WriteFCvt]> {
4417   bits<5> Rd;
4418   bits<5> Rn;
4419   let Inst{30-29} = 0b00;
4420   let Inst{28-24} = 0b11110;
4421   let Inst{23-22} = type;
4422   let Inst{21}    = 1;
4423   let Inst{20-19} = rmode;
4424   let Inst{18-16} = opcode;
4425   let Inst{15-10} = 0;
4426   let Inst{9-5}   = Rn;
4427   let Inst{4-0}   = Rd;
4428 }
4429
4430 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4431 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
4432                       RegisterClass srcType, RegisterClass dstType,
4433                       Operand immType, string asm, list<dag> pattern>
4434     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4435          asm, "\t$Rd, $Rn, $scale", "", pattern>,
4436       Sched<[WriteFCvt]> {
4437   bits<5> Rd;
4438   bits<5> Rn;
4439   bits<6> scale;
4440   let Inst{30-29} = 0b00;
4441   let Inst{28-24} = 0b11110;
4442   let Inst{23-22} = type;
4443   let Inst{21}    = 0;
4444   let Inst{20-19} = rmode;
4445   let Inst{18-16} = opcode;
4446   let Inst{15-10} = scale;
4447   let Inst{9-5}   = Rn;
4448   let Inst{4-0}   = Rd;
4449 }
4450
4451 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
4452            SDPatternOperator OpN> {
4453   // Unscaled half-precision to 32-bit
4454   def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
4455                                      [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4456     let Inst{31} = 0; // 32-bit GPR flag
4457     let Predicates = [HasFullFP16];
4458   }
4459
4460   // Unscaled half-precision to 64-bit
4461   def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
4462                                      [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4463     let Inst{31} = 1; // 64-bit GPR flag
4464     let Predicates = [HasFullFP16];
4465   }
4466
4467   // Unscaled single-precision to 32-bit
4468   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
4469                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
4470     let Inst{31} = 0; // 32-bit GPR flag
4471   }
4472
4473   // Unscaled single-precision to 64-bit
4474   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
4475                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
4476     let Inst{31} = 1; // 64-bit GPR flag
4477   }
4478
4479   // Unscaled double-precision to 32-bit
4480   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
4481                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4482     let Inst{31} = 0; // 32-bit GPR flag
4483   }
4484
4485   // Unscaled double-precision to 64-bit
4486   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
4487                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4488     let Inst{31} = 1; // 64-bit GPR flag
4489   }
4490 }
4491
4492 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
4493                              SDPatternOperator OpN> {
4494   // Scaled half-precision to 32-bit
4495   def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
4496                               fixedpoint_f16_i32, asm,
4497               [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn),
4498                                           fixedpoint_f16_i32:$scale)))]> {
4499     let Inst{31} = 0; // 32-bit GPR flag
4500     let scale{5} = 1;
4501     let Predicates = [HasFullFP16];
4502   }
4503
4504   // Scaled half-precision to 64-bit
4505   def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
4506                               fixedpoint_f16_i64, asm,
4507               [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn),
4508                                           fixedpoint_f16_i64:$scale)))]> {
4509     let Inst{31} = 1; // 64-bit GPR flag
4510     let Predicates = [HasFullFP16];
4511   }
4512
4513   // Scaled single-precision to 32-bit
4514   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
4515                               fixedpoint_f32_i32, asm,
4516               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
4517                                           fixedpoint_f32_i32:$scale)))]> {
4518     let Inst{31} = 0; // 32-bit GPR flag
4519     let scale{5} = 1;
4520   }
4521
4522   // Scaled single-precision to 64-bit
4523   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
4524                               fixedpoint_f32_i64, asm,
4525               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
4526                                           fixedpoint_f32_i64:$scale)))]> {
4527     let Inst{31} = 1; // 64-bit GPR flag
4528   }
4529
4530   // Scaled double-precision to 32-bit
4531   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
4532                               fixedpoint_f64_i32, asm,
4533               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
4534                                           fixedpoint_f64_i32:$scale)))]> {
4535     let Inst{31} = 0; // 32-bit GPR flag
4536     let scale{5} = 1;
4537   }
4538
4539   // Scaled double-precision to 64-bit
4540   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
4541                               fixedpoint_f64_i64, asm,
4542               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
4543                                           fixedpoint_f64_i64:$scale)))]> {
4544     let Inst{31} = 1; // 64-bit GPR flag
4545   }
4546 }
4547
4548 //---
4549 // Integer to floating point conversion
4550 //---
4551
4552 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
4553 class BaseIntegerToFP<bit isUnsigned,
4554                       RegisterClass srcType, RegisterClass dstType,
4555                       Operand immType, string asm, list<dag> pattern>
4556     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4557          asm, "\t$Rd, $Rn, $scale", "", pattern>,
4558       Sched<[WriteFCvt]> {
4559   bits<5> Rd;
4560   bits<5> Rn;
4561   bits<6> scale;
4562   let Inst{30-24} = 0b0011110;
4563   let Inst{21-17} = 0b00001;
4564   let Inst{16}    = isUnsigned;
4565   let Inst{15-10} = scale;
4566   let Inst{9-5}   = Rn;
4567   let Inst{4-0}   = Rd;
4568 }
4569
4570 class BaseIntegerToFPUnscaled<bit isUnsigned,
4571                       RegisterClass srcType, RegisterClass dstType,
4572                       ValueType dvt, string asm, SDNode node>
4573     : I<(outs dstType:$Rd), (ins srcType:$Rn),
4574          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
4575       Sched<[WriteFCvt]> {
4576   bits<5> Rd;
4577   bits<5> Rn;
4578   bits<6> scale;
4579   let Inst{30-24} = 0b0011110;
4580   let Inst{21-17} = 0b10001;
4581   let Inst{16}    = isUnsigned;
4582   let Inst{15-10} = 0b000000;
4583   let Inst{9-5}   = Rn;
4584   let Inst{4-0}   = Rd;
4585 }
4586
4587 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
4588   // Unscaled
4589   def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
4590     let Inst{31} = 0; // 32-bit GPR flag
4591     let Inst{23-22} = 0b11; // 16-bit FPR flag
4592     let Predicates = [HasFullFP16];
4593   }
4594
4595   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
4596     let Inst{31} = 0; // 32-bit GPR flag
4597     let Inst{23-22} = 0b00; // 32-bit FPR flag
4598   }
4599
4600   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
4601     let Inst{31} = 0; // 32-bit GPR flag
4602     let Inst{23-22} = 0b01; // 64-bit FPR flag
4603   }
4604
4605   def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
4606     let Inst{31} = 1; // 64-bit GPR flag
4607     let Inst{23-22} = 0b11; // 16-bit FPR flag
4608     let Predicates = [HasFullFP16];
4609   }
4610
4611   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
4612     let Inst{31} = 1; // 64-bit GPR flag
4613     let Inst{23-22} = 0b00; // 32-bit FPR flag
4614   }
4615
4616   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
4617     let Inst{31} = 1; // 64-bit GPR flag
4618     let Inst{23-22} = 0b01; // 64-bit FPR flag
4619   }
4620
4621   // Scaled
4622   def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
4623                              [(set (f16 FPR16:$Rd),
4624                                    (fdiv (node GPR32:$Rn),
4625                                          fixedpoint_f16_i32:$scale))]> {
4626     let Inst{31} = 0; // 32-bit GPR flag
4627     let Inst{23-22} = 0b11; // 16-bit FPR flag
4628     let scale{5} = 1;
4629     let Predicates = [HasFullFP16];
4630   }
4631
4632   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
4633                              [(set FPR32:$Rd,
4634                                    (fdiv (node GPR32:$Rn),
4635                                          fixedpoint_f32_i32:$scale))]> {
4636     let Inst{31} = 0; // 32-bit GPR flag
4637     let Inst{23-22} = 0b00; // 32-bit FPR flag
4638     let scale{5} = 1;
4639   }
4640
4641   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
4642                              [(set FPR64:$Rd,
4643                                    (fdiv (node GPR32:$Rn),
4644                                          fixedpoint_f64_i32:$scale))]> {
4645     let Inst{31} = 0; // 32-bit GPR flag
4646     let Inst{23-22} = 0b01; // 64-bit FPR flag
4647     let scale{5} = 1;
4648   }
4649
4650   def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
4651                              [(set (f16 FPR16:$Rd),
4652                                    (fdiv (node GPR64:$Rn),
4653                                          fixedpoint_f16_i64:$scale))]> {
4654     let Inst{31} = 1; // 64-bit GPR flag
4655     let Inst{23-22} = 0b11; // 16-bit FPR flag
4656     let Predicates = [HasFullFP16];
4657   }
4658
4659   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
4660                              [(set FPR32:$Rd,
4661                                    (fdiv (node GPR64:$Rn),
4662                                          fixedpoint_f32_i64:$scale))]> {
4663     let Inst{31} = 1; // 64-bit GPR flag
4664     let Inst{23-22} = 0b00; // 32-bit FPR flag
4665   }
4666
4667   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
4668                              [(set FPR64:$Rd,
4669                                    (fdiv (node GPR64:$Rn),
4670                                          fixedpoint_f64_i64:$scale))]> {
4671     let Inst{31} = 1; // 64-bit GPR flag
4672     let Inst{23-22} = 0b01; // 64-bit FPR flag
4673   }
4674 }
4675
4676 //---
4677 // Unscaled integer <-> floating point conversion (i.e. FMOV)
4678 //---
4679
4680 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4681 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
4682                       RegisterClass srcType, RegisterClass dstType,
4683                       string asm>
4684     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
4685         // We use COPY_TO_REGCLASS for these bitconvert operations.
4686         // copyPhysReg() expands the resultant COPY instructions after
4687         // regalloc is done. This gives greater freedom for the allocator
4688         // and related passes (coalescing, copy propagation, et. al.) to
4689         // be more effective.
4690         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
4691       Sched<[WriteFCopy]> {
4692   bits<5> Rd;
4693   bits<5> Rn;
4694   let Inst{30-24} = 0b0011110;
4695   let Inst{21}    = 1;
4696   let Inst{20-19} = rmode;
4697   let Inst{18-16} = opcode;
4698   let Inst{15-10} = 0b000000;
4699   let Inst{9-5}   = Rn;
4700   let Inst{4-0}   = Rd;
4701 }
4702
4703 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4704 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
4705                      RegisterClass srcType, RegisterOperand dstType, string asm,
4706                      string kind>
4707     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4708         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
4709       Sched<[WriteFCopy]> {
4710   bits<5> Rd;
4711   bits<5> Rn;
4712   let Inst{30-23} = 0b00111101;
4713   let Inst{21}    = 1;
4714   let Inst{20-19} = rmode;
4715   let Inst{18-16} = opcode;
4716   let Inst{15-10} = 0b000000;
4717   let Inst{9-5}   = Rn;
4718   let Inst{4-0}   = Rd;
4719
4720   let DecoderMethod =  "DecodeFMOVLaneInstruction";
4721 }
4722
4723 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4724 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
4725                      RegisterOperand srcType, RegisterClass dstType, string asm,
4726                      string kind>
4727     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4728         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
4729       Sched<[WriteFCopy]> {
4730   bits<5> Rd;
4731   bits<5> Rn;
4732   let Inst{30-23} = 0b00111101;
4733   let Inst{21}    = 1;
4734   let Inst{20-19} = rmode;
4735   let Inst{18-16} = opcode;
4736   let Inst{15-10} = 0b000000;
4737   let Inst{9-5}   = Rn;
4738   let Inst{4-0}   = Rd;
4739
4740   let DecoderMethod =  "DecodeFMOVLaneInstruction";
4741 }
4742
4743
4744 multiclass UnscaledConversion<string asm> {
4745   def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
4746     let Inst{31} = 0; // 32-bit GPR flag
4747     let Inst{23-22} = 0b11; // 16-bit FPR flag
4748     let Predicates = [HasFullFP16];
4749   }
4750
4751   def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
4752     let Inst{31} = 1; // 64-bit GPR flag
4753     let Inst{23-22} = 0b11; // 16-bit FPR flag
4754     let Predicates = [HasFullFP16];
4755   }
4756
4757   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
4758     let Inst{31} = 0; // 32-bit GPR flag
4759     let Inst{23-22} = 0b00; // 32-bit FPR flag
4760   }
4761
4762   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
4763     let Inst{31} = 1; // 64-bit GPR flag
4764     let Inst{23-22} = 0b01; // 64-bit FPR flag
4765   }
4766
4767   def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
4768     let Inst{31} = 0; // 32-bit GPR flag
4769     let Inst{23-22} = 0b11; // 16-bit FPR flag
4770     let Predicates = [HasFullFP16];
4771   }
4772
4773   def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
4774     let Inst{31} = 1; // 64-bit GPR flag
4775     let Inst{23-22} = 0b11; // 16-bit FPR flag
4776     let Predicates = [HasFullFP16];
4777   }
4778
4779   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
4780     let Inst{31} = 0; // 32-bit GPR flag
4781     let Inst{23-22} = 0b00; // 32-bit FPR flag
4782   }
4783
4784   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
4785     let Inst{31} = 1; // 64-bit GPR flag
4786     let Inst{23-22} = 0b01; // 64-bit FPR flag
4787   }
4788
4789   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
4790                                              asm, ".d"> {
4791     let Inst{31} = 1;
4792     let Inst{22} = 0;
4793   }
4794
4795   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
4796                                                asm, ".d"> {
4797     let Inst{31} = 1;
4798     let Inst{22} = 0;
4799   }
4800 }
4801
4802 //---
4803 // Floating point conversion
4804 //---
4805
4806 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
4807                        RegisterClass srcType, string asm, list<dag> pattern>
4808     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
4809       Sched<[WriteFCvt]> {
4810   bits<5> Rd;
4811   bits<5> Rn;
4812   let Inst{31-24} = 0b00011110;
4813   let Inst{23-22} = type;
4814   let Inst{21-17} = 0b10001;
4815   let Inst{16-15} = opcode;
4816   let Inst{14-10} = 0b10000;
4817   let Inst{9-5}   = Rn;
4818   let Inst{4-0}   = Rd;
4819 }
4820
4821 multiclass FPConversion<string asm> {
4822   // Double-precision to Half-precision
4823   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4824                              [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>;
4825
4826   // Double-precision to Single-precision
4827   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4828                              [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;
4829
4830   // Half-precision to Double-precision
4831   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
4832                              [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
4833
4834   // Half-precision to Single-precision
4835   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
4836                              [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
4837
4838   // Single-precision to Double-precision
4839   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
4840                              [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
4841
4842   // Single-precision to Half-precision
4843   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4844                              [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>;
4845 }
4846
4847 //---
4848 // Single operand floating point data processing
4849 //---
4850
4851 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4852 class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype,
4853                               ValueType vt, string asm, SDPatternOperator node>
4854     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
4855          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
4856       Sched<[WriteF]> {
4857   bits<5> Rd;
4858   bits<5> Rn;
4859   let Inst{31-24} = 0b00011110;
4860   let Inst{21}    = 0b1;
4861   let Inst{20-15} = opcode;
4862   let Inst{14-10} = 0b10000;
4863   let Inst{9-5}   = Rn;
4864   let Inst{4-0}   = Rd;
4865 }
4866
4867 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4868                                SDPatternOperator node = null_frag> {
4869
4870   def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> {
4871     let Inst{23-22} = 0b11; // 16-bit size flag
4872     let Predicates = [HasFullFP16];
4873   }
4874
4875   def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {
4876     let Inst{23-22} = 0b00; // 32-bit size flag
4877   }
4878
4879   def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {
4880     let Inst{23-22} = 0b01; // 64-bit size flag
4881   }
4882 }
4883
4884 multiclass SingleOperandFPNo16<bits<6> opcode, string asm,
4885                   SDPatternOperator node = null_frag>{
4886
4887   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4888     let Inst{23-22} = 0b00; // 32-bit registers
4889   }
4890
4891   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4892     let Inst{23-22} = 0b01; // 64-bit registers
4893   }
4894 }
4895
4896 // FRInt[32|64][Z|N] instructions
4897 multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> :
4898       SingleOperandFPNo16<{0b0100,opcode}, asm, node>;
4899
4900 //---
4901 // Two operand floating point data processing
4902 //---
4903
4904 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4905 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4906                            string asm, list<dag> pat>
4907     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4908          asm, "\t$Rd, $Rn, $Rm", "", pat>,
4909       Sched<[WriteF]> {
4910   bits<5> Rd;
4911   bits<5> Rn;
4912   bits<5> Rm;
4913   let Inst{31-24} = 0b00011110;
4914   let Inst{21}    = 1;
4915   let Inst{20-16} = Rm;
4916   let Inst{15-12} = opcode;
4917   let Inst{11-10} = 0b10;
4918   let Inst{9-5}   = Rn;
4919   let Inst{4-0}   = Rd;
4920 }
4921
4922 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4923                             SDPatternOperator node = null_frag> {
4924   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4925                          [(set (f16 FPR16:$Rd),
4926                                (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4927     let Inst{23-22} = 0b11; // 16-bit size flag
4928     let Predicates = [HasFullFP16];
4929   }
4930
4931   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4932                          [(set (f32 FPR32:$Rd),
4933                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4934     let Inst{23-22} = 0b00; // 32-bit size flag
4935   }
4936
4937   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4938                          [(set (f64 FPR64:$Rd),
4939                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4940     let Inst{23-22} = 0b01; // 64-bit size flag
4941   }
4942 }
4943
4944 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4945   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4946                   [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> {
4947     let Inst{23-22} = 0b11; // 16-bit size flag
4948     let Predicates = [HasFullFP16];
4949   }
4950
4951   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4952                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4953     let Inst{23-22} = 0b00; // 32-bit size flag
4954   }
4955
4956   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4957                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4958     let Inst{23-22} = 0b01; // 64-bit size flag
4959   }
4960 }
4961
4962
4963 //---
4964 // Three operand floating point data processing
4965 //---
4966
4967 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4968                              RegisterClass regtype, string asm, list<dag> pat>
4969     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4970          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4971       Sched<[WriteFMul]> {
4972   bits<5> Rd;
4973   bits<5> Rn;
4974   bits<5> Rm;
4975   bits<5> Ra;
4976   let Inst{31-24} = 0b00011111;
4977   let Inst{21}    = isNegated;
4978   let Inst{20-16} = Rm;
4979   let Inst{15}    = isSub;
4980   let Inst{14-10} = Ra;
4981   let Inst{9-5}   = Rn;
4982   let Inst{4-0}   = Rd;
4983 }
4984
4985 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4986                               SDPatternOperator node> {
4987   def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4988             [(set (f16 FPR16:$Rd),
4989                   (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4990     let Inst{23-22} = 0b11; // 16-bit size flag
4991     let Predicates = [HasFullFP16];
4992   }
4993
4994   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4995             [(set FPR32:$Rd,
4996                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4997     let Inst{23-22} = 0b00; // 32-bit size flag
4998   }
4999
5000   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
5001             [(set FPR64:$Rd,
5002                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
5003     let Inst{23-22} = 0b01; // 64-bit size flag
5004   }
5005 }
5006
5007 //---
5008 // Floating point data comparisons
5009 //---
5010
5011 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5012 class BaseOneOperandFPComparison<bit signalAllNans,
5013                                  RegisterClass regtype, string asm,
5014                                  list<dag> pat>
5015     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
5016       Sched<[WriteFCmp]> {
5017   bits<5> Rn;
5018   let Inst{31-24} = 0b00011110;
5019   let Inst{21}    = 1;
5020
5021   let Inst{15-10} = 0b001000;
5022   let Inst{9-5}   = Rn;
5023   let Inst{4}     = signalAllNans;
5024   let Inst{3-0}   = 0b1000;
5025
5026   // Rm should be 0b00000 canonically, but we need to accept any value.
5027   let PostEncoderMethod = "fixOneOperandFPComparison";
5028 }
5029
5030 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5031 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
5032                                 string asm, list<dag> pat>
5033     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
5034       Sched<[WriteFCmp]> {
5035   bits<5> Rm;
5036   bits<5> Rn;
5037   let Inst{31-24} = 0b00011110;
5038   let Inst{21}    = 1;
5039   let Inst{20-16} = Rm;
5040   let Inst{15-10} = 0b001000;
5041   let Inst{9-5}   = Rn;
5042   let Inst{4}     = signalAllNans;
5043   let Inst{3-0}   = 0b0000;
5044 }
5045
5046 multiclass FPComparison<bit signalAllNans, string asm,
5047                         SDPatternOperator OpNode = null_frag> {
5048   let Defs = [NZCV] in {
5049   def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
5050       [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> {
5051     let Inst{23-22} = 0b11;
5052     let Predicates = [HasFullFP16];
5053   }
5054
5055   def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
5056       [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
5057     let Inst{23-22} = 0b11;
5058     let Predicates = [HasFullFP16];
5059   }
5060
5061   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
5062       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
5063     let Inst{23-22} = 0b00;
5064   }
5065
5066   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
5067       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
5068     let Inst{23-22} = 0b00;
5069   }
5070
5071   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
5072       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
5073     let Inst{23-22} = 0b01;
5074   }
5075
5076   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
5077       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
5078     let Inst{23-22} = 0b01;
5079   }
5080   } // Defs = [NZCV]
5081 }
5082
5083 //---
5084 // Floating point conditional comparisons
5085 //---
5086
5087 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5088 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
5089                            string mnemonic, list<dag> pat>
5090     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
5091          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
5092       Sched<[WriteFCmp]> {
5093   let Uses = [NZCV];
5094   let Defs = [NZCV];
5095
5096   bits<5> Rn;
5097   bits<5> Rm;
5098   bits<4> nzcv;
5099   bits<4> cond;
5100
5101   let Inst{31-24} = 0b00011110;
5102   let Inst{21}    = 1;
5103   let Inst{20-16} = Rm;
5104   let Inst{15-12} = cond;
5105   let Inst{11-10} = 0b01;
5106   let Inst{9-5}   = Rn;
5107   let Inst{4}     = signalAllNans;
5108   let Inst{3-0}   = nzcv;
5109 }
5110
5111 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
5112                             SDPatternOperator OpNode = null_frag> {
5113   def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,
5114       [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),
5115                           (i32 imm:$cond), NZCV))]> {
5116     let Inst{23-22} = 0b11;
5117     let Predicates = [HasFullFP16];
5118   }
5119
5120   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
5121       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
5122                           (i32 imm:$cond), NZCV))]> {
5123     let Inst{23-22} = 0b00;
5124   }
5125
5126   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
5127       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
5128                           (i32 imm:$cond), NZCV))]> {
5129     let Inst{23-22} = 0b01;
5130   }
5131 }
5132
5133 //---
5134 // Floating point conditional select
5135 //---
5136
5137 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
5138     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
5139          asm, "\t$Rd, $Rn, $Rm, $cond", "",
5140          [(set regtype:$Rd,
5141                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
5142                           (i32 imm:$cond), NZCV))]>,
5143       Sched<[WriteF]> {
5144   bits<5> Rd;
5145   bits<5> Rn;
5146   bits<5> Rm;
5147   bits<4> cond;
5148
5149   let Inst{31-24} = 0b00011110;
5150   let Inst{21}    = 1;
5151   let Inst{20-16} = Rm;
5152   let Inst{15-12} = cond;
5153   let Inst{11-10} = 0b11;
5154   let Inst{9-5}   = Rn;
5155   let Inst{4-0}   = Rd;
5156 }
5157
5158 multiclass FPCondSelect<string asm> {
5159   let Uses = [NZCV] in {
5160   def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
5161     let Inst{23-22} = 0b11;
5162     let Predicates = [HasFullFP16];
5163   }
5164
5165   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
5166     let Inst{23-22} = 0b00;
5167   }
5168
5169   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
5170     let Inst{23-22} = 0b01;
5171   }
5172   } // Uses = [NZCV]
5173 }
5174
5175 //---
5176 // Floating move immediate
5177 //---
5178
5179 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
5180   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
5181       [(set regtype:$Rd, fpimmtype:$imm)]>,
5182     Sched<[WriteFImm]> {
5183   bits<5> Rd;
5184   bits<8> imm;
5185   let Inst{31-24} = 0b00011110;
5186   let Inst{21}    = 1;
5187   let Inst{20-13} = imm;
5188   let Inst{12-5}  = 0b10000000;
5189   let Inst{4-0}   = Rd;
5190 }
5191
5192 multiclass FPMoveImmediate<string asm> {
5193   def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
5194     let Inst{23-22} = 0b11;
5195     let Predicates = [HasFullFP16];
5196   }
5197
5198   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
5199     let Inst{23-22} = 0b00;
5200   }
5201
5202   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
5203     let Inst{23-22} = 0b01;
5204   }
5205 }
5206 } // end of 'let Predicates = [HasFPARMv8]'
5207
5208 //----------------------------------------------------------------------------
5209 // AdvSIMD
5210 //----------------------------------------------------------------------------
5211
5212 let Predicates = [HasNEON] in {
5213
5214 //----------------------------------------------------------------------------
5215 // AdvSIMD three register vector instructions
5216 //----------------------------------------------------------------------------
5217
5218 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5219 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
5220                         RegisterOperand regtype, string asm, string kind,
5221                         list<dag> pattern>
5222   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5223       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5224       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
5225     Sched<[WriteV]> {
5226   bits<5> Rd;
5227   bits<5> Rn;
5228   bits<5> Rm;
5229   let Inst{31}    = 0;
5230   let Inst{30}    = Q;
5231   let Inst{29}    = U;
5232   let Inst{28-24} = 0b01110;
5233   let Inst{23-21} = size;
5234   let Inst{20-16} = Rm;
5235   let Inst{15-11} = opcode;
5236   let Inst{10}    = 1;
5237   let Inst{9-5}   = Rn;
5238   let Inst{4-0}   = Rd;
5239 }
5240
5241 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5242 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
5243                         RegisterOperand regtype, string asm, string kind,
5244                         list<dag> pattern>
5245   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
5246       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5247       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5248     Sched<[WriteV]> {
5249   bits<5> Rd;
5250   bits<5> Rn;
5251   bits<5> Rm;
5252   let Inst{31}    = 0;
5253   let Inst{30}    = Q;
5254   let Inst{29}    = U;
5255   let Inst{28-24} = 0b01110;
5256   let Inst{23-21} = size;
5257   let Inst{20-16} = Rm;
5258   let Inst{15-11} = opcode;
5259   let Inst{10}    = 1;
5260   let Inst{9-5}   = Rn;
5261   let Inst{4-0}   = Rd;
5262 }
5263
5264 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5265 class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern>
5266   : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>,
5267     Sched<[WriteV]>;
5268
5269 multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> {
5270   def v8i8  : BaseSIMDThreeSameVectorPseudo<V64,
5271              [(set (v8i8 V64:$dst),
5272                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5273   def v16i8  : BaseSIMDThreeSameVectorPseudo<V128,
5274              [(set (v16i8 V128:$dst),
5275                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5276                            (v16i8 V128:$Rm)))]>;
5277
5278   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5279                            (v4i16 V64:$RHS))),
5280           (!cast<Instruction>(NAME#"v8i8")
5281             V64:$LHS, V64:$MHS, V64:$RHS)>;
5282   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5283                            (v2i32 V64:$RHS))),
5284           (!cast<Instruction>(NAME#"v8i8")
5285             V64:$LHS, V64:$MHS, V64:$RHS)>;
5286   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5287                            (v1i64 V64:$RHS))),
5288           (!cast<Instruction>(NAME#"v8i8")
5289             V64:$LHS, V64:$MHS, V64:$RHS)>;
5290
5291   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5292                            (v8i16 V128:$RHS))),
5293       (!cast<Instruction>(NAME#"v16i8")
5294         V128:$LHS, V128:$MHS, V128:$RHS)>;
5295   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5296                            (v4i32 V128:$RHS))),
5297       (!cast<Instruction>(NAME#"v16i8")
5298         V128:$LHS, V128:$MHS, V128:$RHS)>;
5299   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5300                            (v2i64 V128:$RHS))),
5301       (!cast<Instruction>(NAME#"v16i8")
5302         V128:$LHS, V128:$MHS, V128:$RHS)>;
5303 }
5304
5305 // All operand sizes distinguished in the encoding.
5306 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
5307                                SDPatternOperator OpNode> {
5308   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5309                                       asm, ".8b",
5310          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5311   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5312                                       asm, ".16b",
5313          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5314   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5315                                       asm, ".4h",
5316          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5317   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5318                                       asm, ".8h",
5319          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5320   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5321                                       asm, ".2s",
5322          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5323   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5324                                       asm, ".4s",
5325          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5326   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
5327                                       asm, ".2d",
5328          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5329 }
5330
5331 multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> {
5332   def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)),
5333           (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>;
5334   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5335           (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>;
5336   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5337           (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>;
5338
5339   def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)),
5340           (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>;
5341   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5342           (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>;
5343   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5344           (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>;
5345   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5346           (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>;
5347 }
5348
5349 // As above, but D sized elements unsupported.
5350 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
5351                                   SDPatternOperator OpNode> {
5352   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5353                                       asm, ".8b",
5354         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
5355   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5356                                       asm, ".16b",
5357         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
5358   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5359                                       asm, ".4h",
5360         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
5361   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5362                                       asm, ".8h",
5363         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
5364   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5365                                       asm, ".2s",
5366         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
5367   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5368                                       asm, ".4s",
5369         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
5370 }
5371
5372 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
5373                                   SDPatternOperator OpNode> {
5374   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
5375                                       asm, ".8b",
5376       [(set (v8i8 V64:$dst),
5377             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5378   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
5379                                       asm, ".16b",
5380       [(set (v16i8 V128:$dst),
5381             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5382   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
5383                                       asm, ".4h",
5384       [(set (v4i16 V64:$dst),
5385             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5386   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
5387                                       asm, ".8h",
5388       [(set (v8i16 V128:$dst),
5389             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5390   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
5391                                       asm, ".2s",
5392       [(set (v2i32 V64:$dst),
5393             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5394   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
5395                                       asm, ".4s",
5396       [(set (v4i32 V128:$dst),
5397             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5398 }
5399
5400 // As above, but only B sized elements supported.
5401 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
5402                                 SDPatternOperator OpNode> {
5403   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5404                                       asm, ".8b",
5405     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5406   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5407                                       asm, ".16b",
5408     [(set (v16i8 V128:$Rd),
5409           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5410 }
5411
5412 // As above, but only floating point elements supported.
5413 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
5414                                  string asm, SDPatternOperator OpNode> {
5415   let Predicates = [HasNEON, HasFullFP16] in {
5416   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5417                                       asm, ".4h",
5418         [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5419   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5420                                       asm, ".8h",
5421         [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5422   } // Predicates = [HasNEON, HasFullFP16]
5423   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5424                                       asm, ".2s",
5425         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5426   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5427                                       asm, ".4s",
5428         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5429   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5430                                       asm, ".2d",
5431         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5432 }
5433
5434 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
5435                                     string asm,
5436                                     SDPatternOperator OpNode> {
5437   let Predicates = [HasNEON, HasFullFP16] in {
5438   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5439                                       asm, ".4h",
5440         [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5441   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5442                                       asm, ".8h",
5443         [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5444   } // Predicates = [HasNEON, HasFullFP16]
5445   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5446                                       asm, ".2s",
5447         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5448   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5449                                       asm, ".4s",
5450         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5451   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5452                                       asm, ".2d",
5453         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5454 }
5455
5456 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
5457                                  string asm, SDPatternOperator OpNode> {
5458   let Predicates = [HasNEON, HasFullFP16] in {
5459   def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
5460                                       asm, ".4h",
5461      [(set (v4f16 V64:$dst),
5462            (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5463   def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
5464                                       asm, ".8h",
5465      [(set (v8f16 V128:$dst),
5466            (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5467   } // Predicates = [HasNEON, HasFullFP16]
5468   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
5469                                       asm, ".2s",
5470      [(set (v2f32 V64:$dst),
5471            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5472   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
5473                                       asm, ".4s",
5474      [(set (v4f32 V128:$dst),
5475            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5476   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
5477                                       asm, ".2d",
5478      [(set (v2f64 V128:$dst),
5479            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5480 }
5481
5482 // As above, but D and B sized elements unsupported.
5483 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
5484                                 SDPatternOperator OpNode> {
5485   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5486                                       asm, ".4h",
5487         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5488   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5489                                       asm, ".8h",
5490         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5491   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5492                                       asm, ".2s",
5493         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5494   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5495                                       asm, ".4s",
5496         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5497 }
5498
5499 // Logical three vector ops share opcode bits, and only use B sized elements.
5500 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
5501                                   SDPatternOperator OpNode = null_frag> {
5502   def v8i8  : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
5503                                      asm, ".8b",
5504                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
5505   def v16i8  : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
5506                                      asm, ".16b",
5507                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
5508
5509   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5510           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5511   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5512           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5513   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
5514           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5515
5516   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5517       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5518   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5519       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5520   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5521       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5522 }
5523
5524 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
5525                                   string asm, SDPatternOperator OpNode = null_frag> {
5526   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
5527                                      asm, ".8b",
5528              [(set (v8i8 V64:$dst),
5529                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5530   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
5531                                      asm, ".16b",
5532              [(set (v16i8 V128:$dst),
5533                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5534                            (v16i8 V128:$Rm)))]>;
5535
5536   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5537                            (v4i16 V64:$RHS))),
5538           (!cast<Instruction>(NAME#"v8i8")
5539             V64:$LHS, V64:$MHS, V64:$RHS)>;
5540   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5541                            (v2i32 V64:$RHS))),
5542           (!cast<Instruction>(NAME#"v8i8")
5543             V64:$LHS, V64:$MHS, V64:$RHS)>;
5544   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5545                            (v1i64 V64:$RHS))),
5546           (!cast<Instruction>(NAME#"v8i8")
5547             V64:$LHS, V64:$MHS, V64:$RHS)>;
5548
5549   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5550                            (v8i16 V128:$RHS))),
5551       (!cast<Instruction>(NAME#"v16i8")
5552         V128:$LHS, V128:$MHS, V128:$RHS)>;
5553   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5554                            (v4i32 V128:$RHS))),
5555       (!cast<Instruction>(NAME#"v16i8")
5556         V128:$LHS, V128:$MHS, V128:$RHS)>;
5557   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5558                            (v2i64 V128:$RHS))),
5559       (!cast<Instruction>(NAME#"v16i8")
5560         V128:$LHS, V128:$MHS, V128:$RHS)>;
5561 }
5562
5563 // ARMv8.2-A Dot Product Instructions (Vector): These instructions extract
5564 // bytes from S-sized elements.
5565 class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1,
5566                                  string kind2, RegisterOperand RegType,
5567                                  ValueType AccumType, ValueType InputType,
5568                                  SDPatternOperator OpNode> :
5569         BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1,
5570         [(set (AccumType RegType:$dst),
5571               (OpNode (AccumType RegType:$Rd),
5572                       (InputType RegType:$Rn),
5573                       (InputType RegType:$Rm)))]> {
5574   let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5575 }
5576
5577 multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> {
5578   def v8i8  : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64,
5579                                          v2i32, v8i8, OpNode>;
5580   def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128,
5581                                          v4i32, v16i8, OpNode>;
5582 }
5583
5584 // ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions
5585 // select inputs from 4H vectors and accumulate outputs to a 2S vector (or from
5586 // 8H to 4S, when Q=1).
5587 class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1,
5588                                  string kind2, RegisterOperand RegType,
5589                                  ValueType AccumType, ValueType InputType,
5590                                  SDPatternOperator OpNode> :
5591         BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1,
5592                 [(set (AccumType RegType:$dst),
5593               (OpNode (AccumType RegType:$Rd),
5594                       (InputType RegType:$Rn),
5595                       (InputType RegType:$Rm)))]> {
5596   let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5597   let Inst{13} = b13;
5598 }
5599
5600 multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,
5601                                   SDPatternOperator OpNode> {
5602   def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64,
5603                                          v2f32, v4f16, OpNode>;
5604   def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128,
5605                                          v4f32, v8f16, OpNode>;
5606 }
5607
5608
5609 //----------------------------------------------------------------------------
5610 // AdvSIMD two register vector instructions.
5611 //----------------------------------------------------------------------------
5612
5613 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5614 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5615                             bits<2> size2, RegisterOperand regtype, string asm,
5616                             string dstkind, string srckind, list<dag> pattern>
5617   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5618       "{\t$Rd" # dstkind # ", $Rn" # srckind #
5619       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
5620     Sched<[WriteV]> {
5621   bits<5> Rd;
5622   bits<5> Rn;
5623   let Inst{31}    = 0;
5624   let Inst{30}    = Q;
5625   let Inst{29}    = U;
5626   let Inst{28-24} = 0b01110;
5627   let Inst{23-22} = size;
5628   let Inst{21} = 0b1;
5629   let Inst{20-19} = size2;
5630   let Inst{18-17} = 0b00;
5631   let Inst{16-12} = opcode;
5632   let Inst{11-10} = 0b10;
5633   let Inst{9-5}   = Rn;
5634   let Inst{4-0}   = Rd;
5635 }
5636
5637 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5638 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5639                                 bits<2> size2, RegisterOperand regtype,
5640                                 string asm, string dstkind, string srckind,
5641                                 list<dag> pattern>
5642   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
5643       "{\t$Rd" # dstkind # ", $Rn" # srckind #
5644       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5645     Sched<[WriteV]> {
5646   bits<5> Rd;
5647   bits<5> Rn;
5648   let Inst{31}    = 0;
5649   let Inst{30}    = Q;
5650   let Inst{29}    = U;
5651   let Inst{28-24} = 0b01110;
5652   let Inst{23-22} = size;
5653   let Inst{21} = 0b1;
5654   let Inst{20-19} = size2;
5655   let Inst{18-17} = 0b00;
5656   let Inst{16-12} = opcode;
5657   let Inst{11-10} = 0b10;
5658   let Inst{9-5}   = Rn;
5659   let Inst{4-0}   = Rd;
5660 }
5661
5662 // Supports B, H, and S element sizes.
5663 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
5664                             SDPatternOperator OpNode> {
5665   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5666                                       asm, ".8b", ".8b",
5667                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5668   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5669                                       asm, ".16b", ".16b",
5670                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5671   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5672                                       asm, ".4h", ".4h",
5673                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5674   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5675                                       asm, ".8h", ".8h",
5676                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5677   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5678                                       asm, ".2s", ".2s",
5679                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5680   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5681                                       asm, ".4s", ".4s",
5682                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5683 }
5684
5685 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
5686                             RegisterOperand regtype, string asm, string dstkind,
5687                             string srckind, string amount>
5688   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
5689       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
5690       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
5691     Sched<[WriteV]> {
5692   bits<5> Rd;
5693   bits<5> Rn;
5694   let Inst{31}    = 0;
5695   let Inst{30}    = Q;
5696   let Inst{29-24} = 0b101110;
5697   let Inst{23-22} = size;
5698   let Inst{21-10} = 0b100001001110;
5699   let Inst{9-5}   = Rn;
5700   let Inst{4-0}   = Rd;
5701 }
5702
5703 multiclass SIMDVectorLShiftLongBySizeBHS {
5704   let hasSideEffects = 0 in {
5705   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
5706                                              "shll", ".8h",  ".8b", "8">;
5707   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
5708                                              "shll2", ".8h", ".16b", "8">;
5709   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
5710                                              "shll", ".4s",  ".4h", "16">;
5711   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
5712                                              "shll2", ".4s", ".8h", "16">;
5713   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
5714                                              "shll", ".2d",  ".2s", "32">;
5715   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
5716                                              "shll2", ".2d", ".4s", "32">;
5717   }
5718 }
5719
5720 // Supports all element sizes.
5721 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
5722                              SDPatternOperator OpNode> {
5723   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5724                                       asm, ".4h", ".8b",
5725                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5726   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5727                                       asm, ".8h", ".16b",
5728                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5729   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5730                                       asm, ".2s", ".4h",
5731                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5732   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5733                                       asm, ".4s", ".8h",
5734                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5735   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5736                                       asm, ".1d", ".2s",
5737                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5738   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5739                                       asm, ".2d", ".4s",
5740                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5741 }
5742
5743 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
5744                                  SDPatternOperator OpNode> {
5745   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5746                                           asm, ".4h", ".8b",
5747       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
5748                                       (v8i8 V64:$Rn)))]>;
5749   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5750                                           asm, ".8h", ".16b",
5751       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
5752                                       (v16i8 V128:$Rn)))]>;
5753   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5754                                           asm, ".2s", ".4h",
5755       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
5756                                       (v4i16 V64:$Rn)))]>;
5757   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5758                                           asm, ".4s", ".8h",
5759       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
5760                                       (v8i16 V128:$Rn)))]>;
5761   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5762                                           asm, ".1d", ".2s",
5763       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
5764                                       (v2i32 V64:$Rn)))]>;
5765   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5766                                           asm, ".2d", ".4s",
5767       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
5768                                       (v4i32 V128:$Rn)))]>;
5769 }
5770
5771 // Supports all element sizes, except 1xD.
5772 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
5773                                   SDPatternOperator OpNode> {
5774   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5775                                     asm, ".8b", ".8b",
5776     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
5777   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5778                                     asm, ".16b", ".16b",
5779     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
5780   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5781                                     asm, ".4h", ".4h",
5782     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
5783   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5784                                     asm, ".8h", ".8h",
5785     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
5786   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5787                                     asm, ".2s", ".2s",
5788     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
5789   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5790                                     asm, ".4s", ".4s",
5791     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
5792   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
5793                                     asm, ".2d", ".2d",
5794     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
5795 }
5796
5797 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
5798                              SDPatternOperator OpNode = null_frag> {
5799   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5800                                 asm, ".8b", ".8b",
5801     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5802   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5803                                 asm, ".16b", ".16b",
5804     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5805   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5806                                 asm, ".4h", ".4h",
5807     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5808   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5809                                 asm, ".8h", ".8h",
5810     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5811   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5812                                 asm, ".2s", ".2s",
5813     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5814   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5815                                 asm, ".4s", ".4s",
5816     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5817   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5818                                 asm, ".2d", ".2d",
5819     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5820 }
5821
5822
5823 // Supports only B element sizes.
5824 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5825                           SDPatternOperator OpNode> {
5826   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5827                                 asm, ".8b", ".8b",
5828                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5829   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5830                                 asm, ".16b", ".16b",
5831                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5832
5833 }
5834
5835 // Supports only B and H element sizes.
5836 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5837                                 SDPatternOperator OpNode> {
5838   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5839                                 asm, ".8b", ".8b",
5840                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5841   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5842                                 asm, ".16b", ".16b",
5843                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5844   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5845                                 asm, ".4h", ".4h",
5846                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5847   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5848                                 asm, ".8h", ".8h",
5849                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5850 }
5851
5852 // Supports H, S and D element sizes, uses high bit of the size field
5853 // as an extra opcode bit.
5854 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5855                            SDPatternOperator OpNode> {
5856   let Predicates = [HasNEON, HasFullFP16] in {
5857   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5858                                 asm, ".4h", ".4h",
5859                           [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5860   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5861                                 asm, ".8h", ".8h",
5862                           [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5863   } // Predicates = [HasNEON, HasFullFP16]
5864   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5865                                 asm, ".2s", ".2s",
5866                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5867   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5868                                 asm, ".4s", ".4s",
5869                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5870   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5871                                 asm, ".2d", ".2d",
5872                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5873 }
5874
5875 // Supports only S and D element sizes
5876 multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm,
5877                            SDPatternOperator OpNode = null_frag> {
5878
5879   def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64,
5880                                 asm, ".2s", ".2s",
5881                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5882   def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,
5883                                 asm, ".4s", ".4s",
5884                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5885   def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,
5886                                 asm, ".2d", ".2d",
5887                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5888 }
5889
5890 multiclass FRIntNNTVector<bit U, bit op, string asm,
5891                           SDPatternOperator OpNode = null_frag> :
5892            SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>;
5893
5894 // Supports only S element size.
5895 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5896                            SDPatternOperator OpNode> {
5897   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5898                                 asm, ".2s", ".2s",
5899                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5900   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5901                                 asm, ".4s", ".4s",
5902                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5903 }
5904
5905
5906 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5907                            SDPatternOperator OpNode> {
5908   let Predicates = [HasNEON, HasFullFP16] in {
5909   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5910                                 asm, ".4h", ".4h",
5911                           [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5912   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5913                                 asm, ".8h", ".8h",
5914                           [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5915   } // Predicates = [HasNEON, HasFullFP16]
5916   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5917                                 asm, ".2s", ".2s",
5918                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5919   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5920                                 asm, ".4s", ".4s",
5921                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5922   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5923                                 asm, ".2d", ".2d",
5924                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5925 }
5926
5927 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
5928                            SDPatternOperator OpNode> {
5929   let Predicates = [HasNEON, HasFullFP16] in {
5930   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5931                                 asm, ".4h", ".4h",
5932                           [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5933   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5934                                 asm, ".8h", ".8h",
5935                           [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5936   } // Predicates = [HasNEON, HasFullFP16]
5937   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5938                                 asm, ".2s", ".2s",
5939                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5940   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5941                                 asm, ".4s", ".4s",
5942                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5943   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5944                                 asm, ".2d", ".2d",
5945                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5946 }
5947
5948
5949 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5950                            RegisterOperand inreg, RegisterOperand outreg,
5951                            string asm, string outkind, string inkind,
5952                            list<dag> pattern>
5953   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
5954       "{\t$Rd" # outkind # ", $Rn" # inkind #
5955       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
5956     Sched<[WriteV]> {
5957   bits<5> Rd;
5958   bits<5> Rn;
5959   let Inst{31}    = 0;
5960   let Inst{30}    = Q;
5961   let Inst{29}    = U;
5962   let Inst{28-24} = 0b01110;
5963   let Inst{23-22} = size;
5964   let Inst{21-17} = 0b10000;
5965   let Inst{16-12} = opcode;
5966   let Inst{11-10} = 0b10;
5967   let Inst{9-5}   = Rn;
5968   let Inst{4-0}   = Rd;
5969 }
5970
5971 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5972                            RegisterOperand inreg, RegisterOperand outreg,
5973                            string asm, string outkind, string inkind,
5974                            list<dag> pattern>
5975   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
5976       "{\t$Rd" # outkind # ", $Rn" # inkind #
5977       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5978     Sched<[WriteV]> {
5979   bits<5> Rd;
5980   bits<5> Rn;
5981   let Inst{31}    = 0;
5982   let Inst{30}    = Q;
5983   let Inst{29}    = U;
5984   let Inst{28-24} = 0b01110;
5985   let Inst{23-22} = size;
5986   let Inst{21-17} = 0b10000;
5987   let Inst{16-12} = opcode;
5988   let Inst{11-10} = 0b10;
5989   let Inst{9-5}   = Rn;
5990   let Inst{4-0}   = Rd;
5991 }
5992
5993 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
5994                               SDPatternOperator OpNode> {
5995   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
5996                                       asm, ".8b", ".8h",
5997         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5998   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
5999                                       asm#"2", ".16b", ".8h", []>;
6000   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
6001                                       asm, ".4h", ".4s",
6002         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6003   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
6004                                       asm#"2", ".8h", ".4s", []>;
6005   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
6006                                       asm, ".2s", ".2d",
6007         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
6008   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
6009                                       asm#"2", ".4s", ".2d", []>;
6010
6011   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
6012             (!cast<Instruction>(NAME # "v16i8")
6013                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6014   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
6015             (!cast<Instruction>(NAME # "v8i16")
6016                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6017   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
6018             (!cast<Instruction>(NAME # "v4i32")
6019                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6020 }
6021
6022 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
6023                            bits<5> opcode, RegisterOperand regtype, string asm,
6024                            string kind, string zero, ValueType dty,
6025                            ValueType sty, SDNode OpNode>
6026   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6027       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
6028       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
6029       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
6030     Sched<[WriteV]> {
6031   bits<5> Rd;
6032   bits<5> Rn;
6033   let Inst{31}    = 0;
6034   let Inst{30}    = Q;
6035   let Inst{29}    = U;
6036   let Inst{28-24} = 0b01110;
6037   let Inst{23-22} = size;
6038   let Inst{21} = 0b1;
6039   let Inst{20-19} = size2;
6040   let Inst{18-17} = 0b00;
6041   let Inst{16-12} = opcode;
6042   let Inst{11-10} = 0b10;
6043   let Inst{9-5}   = Rn;
6044   let Inst{4-0}   = Rd;
6045 }
6046
6047 // Comparisons support all element sizes, except 1xD.
6048 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
6049                             SDNode OpNode> {
6050   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
6051                                      asm, ".8b", "0",
6052                                      v8i8, v8i8, OpNode>;
6053   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
6054                                      asm, ".16b", "0",
6055                                      v16i8, v16i8, OpNode>;
6056   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
6057                                      asm, ".4h", "0",
6058                                      v4i16, v4i16, OpNode>;
6059   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
6060                                      asm, ".8h", "0",
6061                                      v8i16, v8i16, OpNode>;
6062   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
6063                                      asm, ".2s", "0",
6064                                      v2i32, v2i32, OpNode>;
6065   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
6066                                      asm, ".4s", "0",
6067                                      v4i32, v4i32, OpNode>;
6068   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
6069                                      asm, ".2d", "0",
6070                                      v2i64, v2i64, OpNode>;
6071 }
6072
6073 // FP Comparisons support only S and D element sizes (and H for v8.2a).
6074 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
6075                               string asm, SDNode OpNode> {
6076
6077   let Predicates = [HasNEON, HasFullFP16] in {
6078   def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
6079                                      asm, ".4h", "0.0",
6080                                      v4i16, v4f16, OpNode>;
6081   def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
6082                                      asm, ".8h", "0.0",
6083                                      v8i16, v8f16, OpNode>;
6084   } // Predicates = [HasNEON, HasFullFP16]
6085   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
6086                                      asm, ".2s", "0.0",
6087                                      v2i32, v2f32, OpNode>;
6088   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
6089                                      asm, ".4s", "0.0",
6090                                      v4i32, v4f32, OpNode>;
6091   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
6092                                      asm, ".2d", "0.0",
6093                                      v2i64, v2f64, OpNode>;
6094
6095   let Predicates = [HasNEON, HasFullFP16] in {
6096   def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
6097                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6098   def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
6099                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6100   }
6101   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
6102                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6103   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
6104                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6105   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
6106                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6107   let Predicates = [HasNEON, HasFullFP16] in {
6108   def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
6109                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6110   def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
6111                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6112   }
6113   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
6114                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6115   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
6116                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6117   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
6118                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6119 }
6120
6121 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6122 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
6123                              RegisterOperand outtype, RegisterOperand intype,
6124                              string asm, string VdTy, string VnTy,
6125                              list<dag> pattern>
6126   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
6127       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
6128     Sched<[WriteV]> {
6129   bits<5> Rd;
6130   bits<5> Rn;
6131   let Inst{31}    = 0;
6132   let Inst{30}    = Q;
6133   let Inst{29}    = U;
6134   let Inst{28-24} = 0b01110;
6135   let Inst{23-22} = size;
6136   let Inst{21-17} = 0b10000;
6137   let Inst{16-12} = opcode;
6138   let Inst{11-10} = 0b10;
6139   let Inst{9-5}   = Rn;
6140   let Inst{4-0}   = Rd;
6141 }
6142
6143 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
6144                              RegisterOperand outtype, RegisterOperand intype,
6145                              string asm, string VdTy, string VnTy,
6146                              list<dag> pattern>
6147   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
6148       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
6149     Sched<[WriteV]> {
6150   bits<5> Rd;
6151   bits<5> Rn;
6152   let Inst{31}    = 0;
6153   let Inst{30}    = Q;
6154   let Inst{29}    = U;
6155   let Inst{28-24} = 0b01110;
6156   let Inst{23-22} = size;
6157   let Inst{21-17} = 0b10000;
6158   let Inst{16-12} = opcode;
6159   let Inst{11-10} = 0b10;
6160   let Inst{9-5}   = Rn;
6161   let Inst{4-0}   = Rd;
6162 }
6163
6164 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
6165   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
6166                                     asm, ".4s", ".4h", []>;
6167   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
6168                                     asm#"2", ".4s", ".8h", []>;
6169   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
6170                                     asm, ".2d", ".2s", []>;
6171   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
6172                                     asm#"2", ".2d", ".4s", []>;
6173 }
6174
6175 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
6176   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
6177                                     asm, ".4h", ".4s", []>;
6178   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
6179                                     asm#"2", ".8h", ".4s", []>;
6180   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6181                                     asm, ".2s", ".2d", []>;
6182   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6183                                     asm#"2", ".4s", ".2d", []>;
6184 }
6185
6186 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
6187                                      Intrinsic OpNode> {
6188   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6189                                      asm, ".2s", ".2d",
6190                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6191   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6192                                     asm#"2", ".4s", ".2d", []>;
6193
6194   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
6195             (!cast<Instruction>(NAME # "v4f32")
6196                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6197 }
6198
6199 //----------------------------------------------------------------------------
6200 // AdvSIMD three register different-size vector instructions.
6201 //----------------------------------------------------------------------------
6202
6203 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6204 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
6205                       RegisterOperand outtype, RegisterOperand intype1,
6206                       RegisterOperand intype2, string asm,
6207                       string outkind, string inkind1, string inkind2,
6208                       list<dag> pattern>
6209   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
6210       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6211       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
6212     Sched<[WriteV]> {
6213   bits<5> Rd;
6214   bits<5> Rn;
6215   bits<5> Rm;
6216   let Inst{31}    = 0;
6217   let Inst{30}    = size{0};
6218   let Inst{29}    = U;
6219   let Inst{28-24} = 0b01110;
6220   let Inst{23-22} = size{2-1};
6221   let Inst{21}    = 1;
6222   let Inst{20-16} = Rm;
6223   let Inst{15-12} = opcode;
6224   let Inst{11-10} = 0b00;
6225   let Inst{9-5}   = Rn;
6226   let Inst{4-0}   = Rd;
6227 }
6228
6229 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6230 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
6231                       RegisterOperand outtype, RegisterOperand intype1,
6232                       RegisterOperand intype2, string asm,
6233                       string outkind, string inkind1, string inkind2,
6234                       list<dag> pattern>
6235   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
6236       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6237       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
6238     Sched<[WriteV]> {
6239   bits<5> Rd;
6240   bits<5> Rn;
6241   bits<5> Rm;
6242   let Inst{31}    = 0;
6243   let Inst{30}    = size{0};
6244   let Inst{29}    = U;
6245   let Inst{28-24} = 0b01110;
6246   let Inst{23-22} = size{2-1};
6247   let Inst{21}    = 1;
6248   let Inst{20-16} = Rm;
6249   let Inst{15-12} = opcode;
6250   let Inst{11-10} = 0b00;
6251   let Inst{9-5}   = Rn;
6252   let Inst{4-0}   = Rd;
6253 }
6254
6255 // FIXME: TableGen doesn't know how to deal with expanded types that also
6256 //        change the element count (in this case, placing the results in
6257 //        the high elements of the result register rather than the low
6258 //        elements). Until that's fixed, we can't code-gen those.
6259 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
6260                                     Intrinsic IntOp> {
6261   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6262                                                   V64, V128, V128,
6263                                                   asm, ".8b", ".8h", ".8h",
6264      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
6265   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6266                                                   V128, V128, V128,
6267                                                   asm#"2", ".16b", ".8h", ".8h",
6268      []>;
6269   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6270                                                   V64, V128, V128,
6271                                                   asm, ".4h", ".4s", ".4s",
6272      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
6273   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6274                                                   V128, V128, V128,
6275                                                   asm#"2", ".8h", ".4s", ".4s",
6276      []>;
6277   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6278                                                   V64, V128, V128,
6279                                                   asm, ".2s", ".2d", ".2d",
6280      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
6281   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6282                                                   V128, V128, V128,
6283                                                   asm#"2", ".4s", ".2d", ".2d",
6284      []>;
6285
6286
6287   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
6288   // a version attached to an instruction.
6289   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
6290                                                    (v8i16 V128:$Rm))),
6291             (!cast<Instruction>(NAME # "v8i16_v16i8")
6292                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6293                 V128:$Rn, V128:$Rm)>;
6294   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
6295                                                     (v4i32 V128:$Rm))),
6296             (!cast<Instruction>(NAME # "v4i32_v8i16")
6297                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6298                 V128:$Rn, V128:$Rm)>;
6299   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
6300                                                     (v2i64 V128:$Rm))),
6301             (!cast<Instruction>(NAME # "v2i64_v4i32")
6302                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6303                 V128:$Rn, V128:$Rm)>;
6304 }
6305
6306 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
6307                                       Intrinsic IntOp> {
6308   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6309                                             V128, V64, V64,
6310                                             asm, ".8h", ".8b", ".8b",
6311       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6312   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6313                                             V128, V128, V128,
6314                                             asm#"2", ".8h", ".16b", ".16b", []>;
6315   let Predicates = [HasAES] in {
6316     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
6317                                               V128, V64, V64,
6318                                               asm, ".1q", ".1d", ".1d", []>;
6319     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
6320                                               V128, V128, V128,
6321                                               asm#"2", ".1q", ".2d", ".2d", []>;
6322   }
6323
6324   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
6325                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
6326       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
6327 }
6328
6329 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
6330                                  SDPatternOperator OpNode> {
6331   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6332                                                   V128, V64, V64,
6333                                                   asm, ".4s", ".4h", ".4h",
6334       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6335   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6336                                                   V128, V128, V128,
6337                                                   asm#"2", ".4s", ".8h", ".8h",
6338       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6339                                       (extract_high_v8i16 V128:$Rm)))]>;
6340   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6341                                                   V128, V64, V64,
6342                                                   asm, ".2d", ".2s", ".2s",
6343       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6344   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6345                                                   V128, V128, V128,
6346                                                   asm#"2", ".2d", ".4s", ".4s",
6347       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6348                                       (extract_high_v4i32 V128:$Rm)))]>;
6349 }
6350
6351 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
6352                                   SDPatternOperator OpNode = null_frag> {
6353   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6354                                                   V128, V64, V64,
6355                                                   asm, ".8h", ".8b", ".8b",
6356       [(set (v8i16 V128:$Rd),
6357             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
6358   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6359                                                  V128, V128, V128,
6360                                                  asm#"2", ".8h", ".16b", ".16b",
6361       [(set (v8i16 V128:$Rd),
6362             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6363                                 (extract_high_v16i8 V128:$Rm)))))]>;
6364   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6365                                                   V128, V64, V64,
6366                                                   asm, ".4s", ".4h", ".4h",
6367       [(set (v4i32 V128:$Rd),
6368             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
6369   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6370                                                   V128, V128, V128,
6371                                                   asm#"2", ".4s", ".8h", ".8h",
6372       [(set (v4i32 V128:$Rd),
6373             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6374                                   (extract_high_v8i16 V128:$Rm)))))]>;
6375   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6376                                                   V128, V64, V64,
6377                                                   asm, ".2d", ".2s", ".2s",
6378       [(set (v2i64 V128:$Rd),
6379             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
6380   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6381                                                   V128, V128, V128,
6382                                                   asm#"2", ".2d", ".4s", ".4s",
6383       [(set (v2i64 V128:$Rd),
6384             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6385                                  (extract_high_v4i32 V128:$Rm)))))]>;
6386 }
6387
6388 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
6389                                           string asm,
6390                                           SDPatternOperator OpNode> {
6391   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6392                                                   V128, V64, V64,
6393                                                   asm, ".8h", ".8b", ".8b",
6394     [(set (v8i16 V128:$dst),
6395           (add (v8i16 V128:$Rd),
6396                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
6397   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6398                                                  V128, V128, V128,
6399                                                  asm#"2", ".8h", ".16b", ".16b",
6400     [(set (v8i16 V128:$dst),
6401           (add (v8i16 V128:$Rd),
6402                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6403                                    (extract_high_v16i8 V128:$Rm))))))]>;
6404   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6405                                                   V128, V64, V64,
6406                                                   asm, ".4s", ".4h", ".4h",
6407     [(set (v4i32 V128:$dst),
6408           (add (v4i32 V128:$Rd),
6409                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
6410   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6411                                                   V128, V128, V128,
6412                                                   asm#"2", ".4s", ".8h", ".8h",
6413     [(set (v4i32 V128:$dst),
6414           (add (v4i32 V128:$Rd),
6415                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6416                                     (extract_high_v8i16 V128:$Rm))))))]>;
6417   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6418                                                   V128, V64, V64,
6419                                                   asm, ".2d", ".2s", ".2s",
6420     [(set (v2i64 V128:$dst),
6421           (add (v2i64 V128:$Rd),
6422                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
6423   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6424                                                   V128, V128, V128,
6425                                                   asm#"2", ".2d", ".4s", ".4s",
6426     [(set (v2i64 V128:$dst),
6427           (add (v2i64 V128:$Rd),
6428                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6429                                     (extract_high_v4i32 V128:$Rm))))))]>;
6430 }
6431
6432 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
6433                                   SDPatternOperator OpNode = null_frag> {
6434   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6435                                                   V128, V64, V64,
6436                                                   asm, ".8h", ".8b", ".8b",
6437       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6438   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6439                                                  V128, V128, V128,
6440                                                  asm#"2", ".8h", ".16b", ".16b",
6441       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
6442                                       (extract_high_v16i8 V128:$Rm)))]>;
6443   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6444                                                   V128, V64, V64,
6445                                                   asm, ".4s", ".4h", ".4h",
6446       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6447   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6448                                                   V128, V128, V128,
6449                                                   asm#"2", ".4s", ".8h", ".8h",
6450       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6451                                       (extract_high_v8i16 V128:$Rm)))]>;
6452   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6453                                                   V128, V64, V64,
6454                                                   asm, ".2d", ".2s", ".2s",
6455       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6456   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6457                                                   V128, V128, V128,
6458                                                   asm#"2", ".2d", ".4s", ".4s",
6459       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6460                                       (extract_high_v4i32 V128:$Rm)))]>;
6461 }
6462
6463 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
6464                                       string asm,
6465                                       SDPatternOperator OpNode> {
6466   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6467                                                   V128, V64, V64,
6468                                                   asm, ".8h", ".8b", ".8b",
6469     [(set (v8i16 V128:$dst),
6470           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6471   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6472                                                  V128, V128, V128,
6473                                                  asm#"2", ".8h", ".16b", ".16b",
6474     [(set (v8i16 V128:$dst),
6475           (OpNode (v8i16 V128:$Rd),
6476                   (extract_high_v16i8 V128:$Rn),
6477                   (extract_high_v16i8 V128:$Rm)))]>;
6478   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6479                                                   V128, V64, V64,
6480                                                   asm, ".4s", ".4h", ".4h",
6481     [(set (v4i32 V128:$dst),
6482           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6483   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6484                                                   V128, V128, V128,
6485                                                   asm#"2", ".4s", ".8h", ".8h",
6486     [(set (v4i32 V128:$dst),
6487           (OpNode (v4i32 V128:$Rd),
6488                   (extract_high_v8i16 V128:$Rn),
6489                   (extract_high_v8i16 V128:$Rm)))]>;
6490   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6491                                                   V128, V64, V64,
6492                                                   asm, ".2d", ".2s", ".2s",
6493     [(set (v2i64 V128:$dst),
6494           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6495   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6496                                                   V128, V128, V128,
6497                                                   asm#"2", ".2d", ".4s", ".4s",
6498     [(set (v2i64 V128:$dst),
6499           (OpNode (v2i64 V128:$Rd),
6500                   (extract_high_v4i32 V128:$Rn),
6501                   (extract_high_v4i32 V128:$Rm)))]>;
6502 }
6503
6504 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
6505                                            SDPatternOperator Accum> {
6506   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6507                                                   V128, V64, V64,
6508                                                   asm, ".4s", ".4h", ".4h",
6509     [(set (v4i32 V128:$dst),
6510           (Accum (v4i32 V128:$Rd),
6511                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6512                                                 (v4i16 V64:$Rm)))))]>;
6513   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6514                                                   V128, V128, V128,
6515                                                   asm#"2", ".4s", ".8h", ".8h",
6516     [(set (v4i32 V128:$dst),
6517           (Accum (v4i32 V128:$Rd),
6518                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
6519                                             (extract_high_v8i16 V128:$Rm)))))]>;
6520   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6521                                                   V128, V64, V64,
6522                                                   asm, ".2d", ".2s", ".2s",
6523     [(set (v2i64 V128:$dst),
6524           (Accum (v2i64 V128:$Rd),
6525                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
6526                                                 (v2i32 V64:$Rm)))))]>;
6527   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6528                                                   V128, V128, V128,
6529                                                   asm#"2", ".2d", ".4s", ".4s",
6530     [(set (v2i64 V128:$dst),
6531           (Accum (v2i64 V128:$Rd),
6532                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
6533                                             (extract_high_v4i32 V128:$Rm)))))]>;
6534 }
6535
6536 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
6537                                   SDPatternOperator OpNode> {
6538   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6539                                                   V128, V128, V64,
6540                                                   asm, ".8h", ".8h", ".8b",
6541        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
6542   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6543                                                   V128, V128, V128,
6544                                                   asm#"2", ".8h", ".8h", ".16b",
6545        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
6546                                        (extract_high_v16i8 V128:$Rm)))]>;
6547   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6548                                                   V128, V128, V64,
6549                                                   asm, ".4s", ".4s", ".4h",
6550        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
6551   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6552                                                   V128, V128, V128,
6553                                                   asm#"2", ".4s", ".4s", ".8h",
6554        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
6555                                        (extract_high_v8i16 V128:$Rm)))]>;
6556   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6557                                                   V128, V128, V64,
6558                                                   asm, ".2d", ".2d", ".2s",
6559        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
6560   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6561                                                   V128, V128, V128,
6562                                                   asm#"2", ".2d", ".2d", ".4s",
6563        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
6564                                        (extract_high_v4i32 V128:$Rm)))]>;
6565 }
6566
6567 //----------------------------------------------------------------------------
6568 // AdvSIMD bitwise extract from vector
6569 //----------------------------------------------------------------------------
6570
6571 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
6572                              string asm, string kind>
6573   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
6574       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
6575       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
6576       [(set (vty regtype:$Rd),
6577             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
6578     Sched<[WriteV]> {
6579   bits<5> Rd;
6580   bits<5> Rn;
6581   bits<5> Rm;
6582   bits<4> imm;
6583   let Inst{31}    = 0;
6584   let Inst{30}    = size;
6585   let Inst{29-21} = 0b101110000;
6586   let Inst{20-16} = Rm;
6587   let Inst{15}    = 0;
6588   let Inst{14-11} = imm;
6589   let Inst{10}    = 0;
6590   let Inst{9-5}   = Rn;
6591   let Inst{4-0}   = Rd;
6592 }
6593
6594
6595 multiclass SIMDBitwiseExtract<string asm> {
6596   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
6597     let imm{3} = 0;
6598   }
6599   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
6600 }
6601
6602 //----------------------------------------------------------------------------
6603 // AdvSIMD zip vector
6604 //----------------------------------------------------------------------------
6605
6606 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
6607                         string asm, string kind, SDNode OpNode, ValueType valty>
6608   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6609       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
6610       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
6611       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
6612     Sched<[WriteV]> {
6613   bits<5> Rd;
6614   bits<5> Rn;
6615   bits<5> Rm;
6616   let Inst{31}    = 0;
6617   let Inst{30}    = size{0};
6618   let Inst{29-24} = 0b001110;
6619   let Inst{23-22} = size{2-1};
6620   let Inst{21}    = 0;
6621   let Inst{20-16} = Rm;
6622   let Inst{15}    = 0;
6623   let Inst{14-12} = opc;
6624   let Inst{11-10} = 0b10;
6625   let Inst{9-5}   = Rn;
6626   let Inst{4-0}   = Rd;
6627 }
6628
6629 multiclass SIMDZipVector<bits<3>opc, string asm,
6630                          SDNode OpNode> {
6631   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
6632       asm, ".8b", OpNode, v8i8>;
6633   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
6634       asm, ".16b", OpNode, v16i8>;
6635   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
6636       asm, ".4h", OpNode, v4i16>;
6637   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
6638       asm, ".8h", OpNode, v8i16>;
6639   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
6640       asm, ".2s", OpNode, v2i32>;
6641   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
6642       asm, ".4s", OpNode, v4i32>;
6643   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
6644       asm, ".2d", OpNode, v2i64>;
6645
6646   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
6647         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
6648   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
6649         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
6650   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
6651         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
6652   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
6653         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
6654   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
6655         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
6656 }
6657
6658 //----------------------------------------------------------------------------
6659 // AdvSIMD three register scalar instructions
6660 //----------------------------------------------------------------------------
6661
6662 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6663 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
6664                         RegisterClass regtype, string asm,
6665                         list<dag> pattern>
6666   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6667       "\t$Rd, $Rn, $Rm", "", pattern>,
6668     Sched<[WriteV]> {
6669   bits<5> Rd;
6670   bits<5> Rn;
6671   bits<5> Rm;
6672   let Inst{31-30} = 0b01;
6673   let Inst{29}    = U;
6674   let Inst{28-24} = 0b11110;
6675   let Inst{23-21} = size;
6676   let Inst{20-16} = Rm;
6677   let Inst{15-11} = opcode;
6678   let Inst{10}    = 1;
6679   let Inst{9-5}   = Rn;
6680   let Inst{4-0}   = Rd;
6681 }
6682
6683 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6684 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
6685                         dag oops, dag iops, string asm,
6686             list<dag> pattern>
6687   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
6688     Sched<[WriteV]> {
6689   bits<5> Rd;
6690   bits<5> Rn;
6691   bits<5> Rm;
6692   let Inst{31-30} = 0b01;
6693   let Inst{29}    = U;
6694   let Inst{28-24} = 0b11110;
6695   let Inst{23-22} = size;
6696   let Inst{21}    = R;
6697   let Inst{20-16} = Rm;
6698   let Inst{15-11} = opcode;
6699   let Inst{10}    = 1;
6700   let Inst{9-5}   = Rn;
6701   let Inst{4-0}   = Rd;
6702 }
6703
6704 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
6705                             SDPatternOperator OpNode> {
6706   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6707     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6708 }
6709
6710 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
6711                                SDPatternOperator OpNode> {
6712   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6713     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6714   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
6715   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6716   def v1i8   : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
6717
6718   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
6719             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
6720   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
6721             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
6722 }
6723
6724 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
6725                              SDPatternOperator OpNode> {
6726   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
6727                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6728   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6729 }
6730
6731 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
6732                                  SDPatternOperator OpNode = null_frag> {
6733   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
6734                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
6735                                      asm, []>;
6736   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
6737                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
6738                                      asm, []>;
6739 }
6740
6741 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
6742                              SDPatternOperator OpNode = null_frag> {
6743   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6744     def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6745       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6746     def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6747       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6748     let Predicates = [HasNEON, HasFullFP16] in {
6749     def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6750       [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>;
6751     } // Predicates = [HasNEON, HasFullFP16]
6752   }
6753
6754   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6755             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6756 }
6757
6758 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
6759                                 SDPatternOperator OpNode = null_frag> {
6760   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6761     def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6762       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6763     def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6764       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
6765     let Predicates = [HasNEON, HasFullFP16] in {
6766     def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6767       []>;
6768     } // Predicates = [HasNEON, HasFullFP16]
6769   }
6770
6771   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6772             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6773 }
6774
6775 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
6776               dag oops, dag iops, string asm, string cstr, list<dag> pat>
6777   : I<oops, iops, asm,
6778       "\t$Rd, $Rn, $Rm", cstr, pat>,
6779     Sched<[WriteV]> {
6780   bits<5> Rd;
6781   bits<5> Rn;
6782   bits<5> Rm;
6783   let Inst{31-30} = 0b01;
6784   let Inst{29}    = U;
6785   let Inst{28-24} = 0b11110;
6786   let Inst{23-22} = size;
6787   let Inst{21}    = 1;
6788   let Inst{20-16} = Rm;
6789   let Inst{15-11} = opcode;
6790   let Inst{10}    = 0;
6791   let Inst{9-5}   = Rn;
6792   let Inst{4-0}   = Rd;
6793 }
6794
6795 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6796 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
6797                                   SDPatternOperator OpNode = null_frag> {
6798   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6799                                       (outs FPR32:$Rd),
6800                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
6801   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6802                                       (outs FPR64:$Rd),
6803                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
6804             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6805 }
6806
6807 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6808 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
6809                                   SDPatternOperator OpNode = null_frag> {
6810   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6811                                       (outs FPR32:$dst),
6812                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
6813                                       asm, "$Rd = $dst", []>;
6814   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6815                                       (outs FPR64:$dst),
6816                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
6817                                       asm, "$Rd = $dst",
6818             [(set (i64 FPR64:$dst),
6819                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6820 }
6821
6822 //----------------------------------------------------------------------------
6823 // AdvSIMD two register scalar instructions
6824 //----------------------------------------------------------------------------
6825
6826 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6827 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6828                         RegisterClass regtype, RegisterClass regtype2,
6829                         string asm, list<dag> pat>
6830   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6831       "\t$Rd, $Rn", "", pat>,
6832     Sched<[WriteV]> {
6833   bits<5> Rd;
6834   bits<5> Rn;
6835   let Inst{31-30} = 0b01;
6836   let Inst{29}    = U;
6837   let Inst{28-24} = 0b11110;
6838   let Inst{23-22} = size;
6839   let Inst{21} = 0b1;
6840   let Inst{20-19} = size2;
6841   let Inst{18-17} = 0b00;
6842   let Inst{16-12} = opcode;
6843   let Inst{11-10} = 0b10;
6844   let Inst{9-5}   = Rn;
6845   let Inst{4-0}   = Rd;
6846 }
6847
6848 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6849 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6850                         RegisterClass regtype, RegisterClass regtype2,
6851                         string asm, list<dag> pat>
6852   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6853       "\t$Rd, $Rn", "$Rd = $dst", pat>,
6854     Sched<[WriteV]> {
6855   bits<5> Rd;
6856   bits<5> Rn;
6857   let Inst{31-30} = 0b01;
6858   let Inst{29}    = U;
6859   let Inst{28-24} = 0b11110;
6860   let Inst{23-22} = size;
6861   let Inst{21-17} = 0b10000;
6862   let Inst{16-12} = opcode;
6863   let Inst{11-10} = 0b10;
6864   let Inst{9-5}   = Rn;
6865   let Inst{4-0}   = Rd;
6866 }
6867
6868
6869 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6870 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6871                         RegisterClass regtype, string asm, string zero>
6872   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6873       "\t$Rd, $Rn, #" # zero, "", []>,
6874     Sched<[WriteV]> {
6875   bits<5> Rd;
6876   bits<5> Rn;
6877   let Inst{31-30} = 0b01;
6878   let Inst{29}    = U;
6879   let Inst{28-24} = 0b11110;
6880   let Inst{23-22} = size;
6881   let Inst{21} = 0b1;
6882   let Inst{20-19} = size2;
6883   let Inst{18-17} = 0b00;
6884   let Inst{16-12} = opcode;
6885   let Inst{11-10} = 0b10;
6886   let Inst{9-5}   = Rn;
6887   let Inst{4-0}   = Rd;
6888 }
6889
6890 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6891   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6892      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6893     Sched<[WriteV]> {
6894   bits<5> Rd;
6895   bits<5> Rn;
6896   let Inst{31-17} = 0b011111100110000;
6897   let Inst{16-12} = opcode;
6898   let Inst{11-10} = 0b10;
6899   let Inst{9-5}   = Rn;
6900   let Inst{4-0}   = Rd;
6901 }
6902
6903 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6904                              SDPatternOperator OpNode> {
6905   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6906
6907   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6908             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6909 }
6910
6911 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6912                               SDPatternOperator OpNode> {
6913   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
6914   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
6915   let Predicates = [HasNEON, HasFullFP16] in {
6916   def v1i16rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
6917   }
6918
6919   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6920                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
6921   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6922                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
6923   let Predicates = [HasNEON, HasFullFP16] in {
6924   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6925                   (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
6926   }
6927
6928   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
6929             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6930 }
6931
6932 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
6933                           SDPatternOperator OpNode = null_frag> {
6934   def v1i64       : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6935     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
6936
6937   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
6938             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
6939 }
6940
6941 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
6942   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
6943   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
6944   let Predicates = [HasNEON, HasFullFP16] in {
6945   def v1f16       : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
6946   }
6947 }
6948
6949 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
6950                               SDPatternOperator OpNode> {
6951   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
6952                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
6953   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
6954                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
6955   let Predicates = [HasNEON, HasFullFP16] in {
6956   def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
6957                                 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>;
6958   }
6959 }
6960
6961 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
6962                              SDPatternOperator OpNode = null_frag> {
6963   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6964     def v1i64  : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6965            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6966     def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
6967            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
6968     def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
6969     def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
6970   }
6971
6972   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
6973             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
6974 }
6975
6976 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
6977                                  Intrinsic OpNode> {
6978   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6979     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
6980         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
6981     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
6982         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
6983     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
6984     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
6985   }
6986
6987   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
6988             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
6989 }
6990
6991
6992
6993 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6994 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
6995                                  SDPatternOperator OpNode = null_frag> {
6996   def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
6997         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6998   def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
6999   def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
7000 }
7001
7002 //----------------------------------------------------------------------------
7003 // AdvSIMD scalar pairwise instructions
7004 //----------------------------------------------------------------------------
7005
7006 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7007 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
7008                         RegisterOperand regtype, RegisterOperand vectype,
7009                         string asm, string kind>
7010   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7011       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
7012     Sched<[WriteV]> {
7013   bits<5> Rd;
7014   bits<5> Rn;
7015   let Inst{31-30} = 0b01;
7016   let Inst{29}    = U;
7017   let Inst{28-24} = 0b11110;
7018   let Inst{23-22} = size;
7019   let Inst{21-17} = 0b11000;
7020   let Inst{16-12} = opcode;
7021   let Inst{11-10} = 0b10;
7022   let Inst{9-5}   = Rn;
7023   let Inst{4-0}   = Rd;
7024 }
7025
7026 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
7027   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
7028                                       asm, ".2d">;
7029 }
7030
7031 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
7032   let Predicates = [HasNEON, HasFullFP16] in {
7033   def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
7034                                       asm, ".2h">;
7035   }
7036   def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
7037                                       asm, ".2s">;
7038   def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
7039                                       asm, ".2d">;
7040 }
7041
7042 //----------------------------------------------------------------------------
7043 // AdvSIMD across lanes instructions
7044 //----------------------------------------------------------------------------
7045
7046 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7047 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
7048                           RegisterClass regtype, RegisterOperand vectype,
7049                           string asm, string kind, list<dag> pattern>
7050   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7051       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
7052     Sched<[WriteV]> {
7053   bits<5> Rd;
7054   bits<5> Rn;
7055   let Inst{31}    = 0;
7056   let Inst{30}    = Q;
7057   let Inst{29}    = U;
7058   let Inst{28-24} = 0b01110;
7059   let Inst{23-22} = size;
7060   let Inst{21-17} = 0b11000;
7061   let Inst{16-12} = opcode;
7062   let Inst{11-10} = 0b10;
7063   let Inst{9-5}   = Rn;
7064   let Inst{4-0}   = Rd;
7065 }
7066
7067 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
7068                               string asm> {
7069   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
7070                                    asm, ".8b", []>;
7071   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
7072                                    asm, ".16b", []>;
7073   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
7074                                    asm, ".4h", []>;
7075   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
7076                                    asm, ".8h", []>;
7077   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
7078                                    asm, ".4s", []>;
7079 }
7080
7081 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
7082   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
7083                                    asm, ".8b", []>;
7084   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
7085                                    asm, ".16b", []>;
7086   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
7087                                    asm, ".4h", []>;
7088   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
7089                                    asm, ".8h", []>;
7090   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
7091                                    asm, ".4s", []>;
7092 }
7093
7094 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
7095                             Intrinsic intOp> {
7096   let Predicates = [HasNEON, HasFullFP16] in {
7097   def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
7098                                    asm, ".4h",
7099         [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>;
7100   def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
7101                                    asm, ".8h",
7102         [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>;
7103   } // Predicates = [HasNEON, HasFullFP16]
7104   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
7105                                    asm, ".4s",
7106         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
7107 }
7108
7109 //----------------------------------------------------------------------------
7110 // AdvSIMD INS/DUP instructions
7111 //----------------------------------------------------------------------------
7112
7113 // FIXME: There has got to be a better way to factor these. ugh.
7114
7115 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
7116                      string operands, string constraints, list<dag> pattern>
7117   : I<outs, ins, asm, operands, constraints, pattern>,
7118     Sched<[WriteV]> {
7119   bits<5> Rd;
7120   bits<5> Rn;
7121   let Inst{31} = 0;
7122   let Inst{30} = Q;
7123   let Inst{29} = op;
7124   let Inst{28-21} = 0b01110000;
7125   let Inst{15} = 0;
7126   let Inst{10} = 1;
7127   let Inst{9-5} = Rn;
7128   let Inst{4-0} = Rd;
7129 }
7130
7131 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
7132                       RegisterOperand vecreg, RegisterClass regtype>
7133   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
7134                    "{\t$Rd" # size # ", $Rn" #
7135                    "|" # size # "\t$Rd, $Rn}", "",
7136                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
7137   let Inst{20-16} = imm5;
7138   let Inst{14-11} = 0b0001;
7139 }
7140
7141 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
7142                          ValueType vectype, ValueType insreg,
7143                          RegisterOperand vecreg, Operand idxtype,
7144                          ValueType elttype, SDNode OpNode>
7145   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
7146                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
7147                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
7148                  [(set (vectype vecreg:$Rd),
7149                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
7150   let Inst{14-11} = 0b0000;
7151 }
7152
7153 class SIMDDup64FromElement
7154   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
7155                        VectorIndexD, i64, AArch64duplane64> {
7156   bits<1> idx;
7157   let Inst{20} = idx;
7158   let Inst{19-16} = 0b1000;
7159 }
7160
7161 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
7162                            RegisterOperand vecreg>
7163   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
7164                        VectorIndexS, i64, AArch64duplane32> {
7165   bits<2> idx;
7166   let Inst{20-19} = idx;
7167   let Inst{18-16} = 0b100;
7168 }
7169
7170 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
7171                            RegisterOperand vecreg>
7172   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
7173                        VectorIndexH, i64, AArch64duplane16> {
7174   bits<3> idx;
7175   let Inst{20-18} = idx;
7176   let Inst{17-16} = 0b10;
7177 }
7178
7179 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
7180                           RegisterOperand vecreg>
7181   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
7182                        VectorIndexB, i64, AArch64duplane8> {
7183   bits<4> idx;
7184   let Inst{20-17} = idx;
7185   let Inst{16} = 1;
7186 }
7187
7188 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
7189                   Operand idxtype, string asm, list<dag> pattern>
7190   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
7191                    "{\t$Rd, $Rn" # size # "$idx" #
7192                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
7193   let Inst{14-11} = imm4;
7194 }
7195
7196 class SIMDSMov<bit Q, string size, RegisterClass regtype,
7197                Operand idxtype>
7198   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
7199 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
7200                Operand idxtype>
7201   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
7202       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
7203
7204 class SIMDMovAlias<string asm, string size, Instruction inst,
7205                    RegisterClass regtype, Operand idxtype>
7206     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
7207                     "|" # size # "\t$dst, $src$idx}",
7208                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
7209
7210 multiclass SMov {
7211   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
7212     bits<4> idx;
7213     let Inst{20-17} = idx;
7214     let Inst{16} = 1;
7215   }
7216   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
7217     bits<4> idx;
7218     let Inst{20-17} = idx;
7219     let Inst{16} = 1;
7220   }
7221   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
7222     bits<3> idx;
7223     let Inst{20-18} = idx;
7224     let Inst{17-16} = 0b10;
7225   }
7226   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
7227     bits<3> idx;
7228     let Inst{20-18} = idx;
7229     let Inst{17-16} = 0b10;
7230   }
7231   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
7232     bits<2> idx;
7233     let Inst{20-19} = idx;
7234     let Inst{18-16} = 0b100;
7235   }
7236 }
7237
7238 multiclass UMov {
7239   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
7240     bits<4> idx;
7241     let Inst{20-17} = idx;
7242     let Inst{16} = 1;
7243   }
7244   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
7245     bits<3> idx;
7246     let Inst{20-18} = idx;
7247     let Inst{17-16} = 0b10;
7248   }
7249   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
7250     bits<2> idx;
7251     let Inst{20-19} = idx;
7252     let Inst{18-16} = 0b100;
7253   }
7254   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
7255     bits<1> idx;
7256     let Inst{20} = idx;
7257     let Inst{19-16} = 0b1000;
7258   }
7259   def : SIMDMovAlias<"mov", ".s",
7260                      !cast<Instruction>(NAME#"vi32"),
7261                      GPR32, VectorIndexS>;
7262   def : SIMDMovAlias<"mov", ".d",
7263                      !cast<Instruction>(NAME#"vi64"),
7264                      GPR64, VectorIndexD>;
7265 }
7266
7267 class SIMDInsFromMain<string size, ValueType vectype,
7268                       RegisterClass regtype, Operand idxtype>
7269   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
7270                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
7271                    "{\t$Rd" # size # "$idx, $Rn" #
7272                    "|" # size # "\t$Rd$idx, $Rn}",
7273                    "$Rd = $dst",
7274             [(set V128:$dst,
7275               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
7276   let Inst{14-11} = 0b0011;
7277 }
7278
7279 class SIMDInsFromElement<string size, ValueType vectype,
7280                          ValueType elttype, Operand idxtype>
7281   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
7282                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
7283                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
7284                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
7285                    "$Rd = $dst",
7286          [(set V128:$dst,
7287                (vector_insert
7288                  (vectype V128:$Rd),
7289                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
7290                  idxtype:$idx))]>;
7291
7292 class SIMDInsMainMovAlias<string size, Instruction inst,
7293                           RegisterClass regtype, Operand idxtype>
7294     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
7295                         "|" # size #"\t$dst$idx, $src}",
7296                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
7297 class SIMDInsElementMovAlias<string size, Instruction inst,
7298                              Operand idxtype>
7299     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2"
7300                       # "|" # size #"\t$dst$idx, $src$idx2}",
7301                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
7302
7303
7304 multiclass SIMDIns {
7305   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
7306     bits<4> idx;
7307     let Inst{20-17} = idx;
7308     let Inst{16} = 1;
7309   }
7310   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
7311     bits<3> idx;
7312     let Inst{20-18} = idx;
7313     let Inst{17-16} = 0b10;
7314   }
7315   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
7316     bits<2> idx;
7317     let Inst{20-19} = idx;
7318     let Inst{18-16} = 0b100;
7319   }
7320   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
7321     bits<1> idx;
7322     let Inst{20} = idx;
7323     let Inst{19-16} = 0b1000;
7324   }
7325
7326   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
7327     bits<4> idx;
7328     bits<4> idx2;
7329     let Inst{20-17} = idx;
7330     let Inst{16} = 1;
7331     let Inst{14-11} = idx2;
7332   }
7333   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
7334     bits<3> idx;
7335     bits<3> idx2;
7336     let Inst{20-18} = idx;
7337     let Inst{17-16} = 0b10;
7338     let Inst{14-12} = idx2;
7339     let Inst{11} = {?};
7340   }
7341   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
7342     bits<2> idx;
7343     bits<2> idx2;
7344     let Inst{20-19} = idx;
7345     let Inst{18-16} = 0b100;
7346     let Inst{14-13} = idx2;
7347     let Inst{12-11} = {?,?};
7348   }
7349   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
7350     bits<1> idx;
7351     bits<1> idx2;
7352     let Inst{20} = idx;
7353     let Inst{19-16} = 0b1000;
7354     let Inst{14} = idx2;
7355     let Inst{13-11} = {?,?,?};
7356   }
7357
7358   // For all forms of the INS instruction, the "mov" mnemonic is the
7359   // preferred alias. Why they didn't just call the instruction "mov" in
7360   // the first place is a very good question indeed...
7361   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
7362                          GPR32, VectorIndexB>;
7363   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
7364                          GPR32, VectorIndexH>;
7365   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
7366                          GPR32, VectorIndexS>;
7367   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
7368                          GPR64, VectorIndexD>;
7369
7370   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
7371                          VectorIndexB>;
7372   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
7373                          VectorIndexH>;
7374   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
7375                          VectorIndexS>;
7376   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
7377                          VectorIndexD>;
7378 }
7379
7380 //----------------------------------------------------------------------------
7381 // AdvSIMD TBL/TBX
7382 //----------------------------------------------------------------------------
7383
7384 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7385 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7386                           RegisterOperand listtype, string asm, string kind>
7387   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
7388        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
7389     Sched<[WriteV]> {
7390   bits<5> Vd;
7391   bits<5> Vn;
7392   bits<5> Vm;
7393   let Inst{31}    = 0;
7394   let Inst{30}    = Q;
7395   let Inst{29-21} = 0b001110000;
7396   let Inst{20-16} = Vm;
7397   let Inst{15}    = 0;
7398   let Inst{14-13} = len;
7399   let Inst{12}    = op;
7400   let Inst{11-10} = 0b00;
7401   let Inst{9-5}   = Vn;
7402   let Inst{4-0}   = Vd;
7403 }
7404
7405 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7406 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7407                           RegisterOperand listtype, string asm, string kind>
7408   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
7409        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
7410     Sched<[WriteV]> {
7411   bits<5> Vd;
7412   bits<5> Vn;
7413   bits<5> Vm;
7414   let Inst{31}    = 0;
7415   let Inst{30}    = Q;
7416   let Inst{29-21} = 0b001110000;
7417   let Inst{20-16} = Vm;
7418   let Inst{15}    = 0;
7419   let Inst{14-13} = len;
7420   let Inst{12}    = op;
7421   let Inst{11-10} = 0b00;
7422   let Inst{9-5}   = Vn;
7423   let Inst{4-0}   = Vd;
7424 }
7425
7426 class SIMDTableLookupAlias<string asm, Instruction inst,
7427                           RegisterOperand vectype, RegisterOperand listtype>
7428     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
7429                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
7430
7431 multiclass SIMDTableLookup<bit op, string asm> {
7432   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
7433                                       asm, ".8b">;
7434   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
7435                                       asm, ".8b">;
7436   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
7437                                       asm, ".8b">;
7438   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
7439                                       asm, ".8b">;
7440   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
7441                                       asm, ".16b">;
7442   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
7443                                       asm, ".16b">;
7444   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
7445                                       asm, ".16b">;
7446   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
7447                                       asm, ".16b">;
7448
7449   def : SIMDTableLookupAlias<asm # ".8b",
7450                          !cast<Instruction>(NAME#"v8i8One"),
7451                          V64, VecListOne128>;
7452   def : SIMDTableLookupAlias<asm # ".8b",
7453                          !cast<Instruction>(NAME#"v8i8Two"),
7454                          V64, VecListTwo128>;
7455   def : SIMDTableLookupAlias<asm # ".8b",
7456                          !cast<Instruction>(NAME#"v8i8Three"),
7457                          V64, VecListThree128>;
7458   def : SIMDTableLookupAlias<asm # ".8b",
7459                          !cast<Instruction>(NAME#"v8i8Four"),
7460                          V64, VecListFour128>;
7461   def : SIMDTableLookupAlias<asm # ".16b",
7462                          !cast<Instruction>(NAME#"v16i8One"),
7463                          V128, VecListOne128>;
7464   def : SIMDTableLookupAlias<asm # ".16b",
7465                          !cast<Instruction>(NAME#"v16i8Two"),
7466                          V128, VecListTwo128>;
7467   def : SIMDTableLookupAlias<asm # ".16b",
7468                          !cast<Instruction>(NAME#"v16i8Three"),
7469                          V128, VecListThree128>;
7470   def : SIMDTableLookupAlias<asm # ".16b",
7471                          !cast<Instruction>(NAME#"v16i8Four"),
7472                          V128, VecListFour128>;
7473 }
7474
7475 multiclass SIMDTableLookupTied<bit op, string asm> {
7476   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
7477                                       asm, ".8b">;
7478   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
7479                                       asm, ".8b">;
7480   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
7481                                       asm, ".8b">;
7482   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
7483                                       asm, ".8b">;
7484   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
7485                                       asm, ".16b">;
7486   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
7487                                       asm, ".16b">;
7488   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
7489                                       asm, ".16b">;
7490   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
7491                                       asm, ".16b">;
7492
7493   def : SIMDTableLookupAlias<asm # ".8b",
7494                          !cast<Instruction>(NAME#"v8i8One"),
7495                          V64, VecListOne128>;
7496   def : SIMDTableLookupAlias<asm # ".8b",
7497                          !cast<Instruction>(NAME#"v8i8Two"),
7498                          V64, VecListTwo128>;
7499   def : SIMDTableLookupAlias<asm # ".8b",
7500                          !cast<Instruction>(NAME#"v8i8Three"),
7501                          V64, VecListThree128>;
7502   def : SIMDTableLookupAlias<asm # ".8b",
7503                          !cast<Instruction>(NAME#"v8i8Four"),
7504                          V64, VecListFour128>;
7505   def : SIMDTableLookupAlias<asm # ".16b",
7506                          !cast<Instruction>(NAME#"v16i8One"),
7507                          V128, VecListOne128>;
7508   def : SIMDTableLookupAlias<asm # ".16b",
7509                          !cast<Instruction>(NAME#"v16i8Two"),
7510                          V128, VecListTwo128>;
7511   def : SIMDTableLookupAlias<asm # ".16b",
7512                          !cast<Instruction>(NAME#"v16i8Three"),
7513                          V128, VecListThree128>;
7514   def : SIMDTableLookupAlias<asm # ".16b",
7515                          !cast<Instruction>(NAME#"v16i8Four"),
7516                          V128, VecListFour128>;
7517 }
7518
7519
7520 //----------------------------------------------------------------------------
7521 // AdvSIMD scalar CPY
7522 //----------------------------------------------------------------------------
7523 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7524 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
7525                         string kind, Operand idxtype>
7526   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
7527        "{\t$dst, $src" # kind # "$idx" #
7528        "|\t$dst, $src$idx}", "", []>,
7529     Sched<[WriteV]> {
7530   bits<5> dst;
7531   bits<5> src;
7532   let Inst{31-21} = 0b01011110000;
7533   let Inst{15-10} = 0b000001;
7534   let Inst{9-5}   = src;
7535   let Inst{4-0}   = dst;
7536 }
7537
7538 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
7539       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
7540     : InstAlias<asm # "{\t$dst, $src" # size # "$index"
7541                     # "|\t$dst, $src$index}",
7542                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
7543
7544
7545 multiclass SIMDScalarCPY<string asm> {
7546   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
7547     bits<4> idx;
7548     let Inst{20-17} = idx;
7549     let Inst{16} = 1;
7550   }
7551   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
7552     bits<3> idx;
7553     let Inst{20-18} = idx;
7554     let Inst{17-16} = 0b10;
7555   }
7556   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
7557     bits<2> idx;
7558     let Inst{20-19} = idx;
7559     let Inst{18-16} = 0b100;
7560   }
7561   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
7562     bits<1> idx;
7563     let Inst{20} = idx;
7564     let Inst{19-16} = 0b1000;
7565   }
7566
7567   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
7568                                                           VectorIndexD:$idx)))),
7569             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
7570
7571   // 'DUP' mnemonic aliases.
7572   def : SIMDScalarCPYAlias<"dup", ".b",
7573                            !cast<Instruction>(NAME#"i8"),
7574                            FPR8, V128, VectorIndexB>;
7575   def : SIMDScalarCPYAlias<"dup", ".h",
7576                            !cast<Instruction>(NAME#"i16"),
7577                            FPR16, V128, VectorIndexH>;
7578   def : SIMDScalarCPYAlias<"dup", ".s",
7579                            !cast<Instruction>(NAME#"i32"),
7580                            FPR32, V128, VectorIndexS>;
7581   def : SIMDScalarCPYAlias<"dup", ".d",
7582                            !cast<Instruction>(NAME#"i64"),
7583                            FPR64, V128, VectorIndexD>;
7584 }
7585
7586 //----------------------------------------------------------------------------
7587 // AdvSIMD modified immediate instructions
7588 //----------------------------------------------------------------------------
7589
7590 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
7591                           string asm, string op_string,
7592                           string cstr, list<dag> pattern>
7593   : I<oops, iops, asm, op_string, cstr, pattern>,
7594     Sched<[WriteV]> {
7595   bits<5> Rd;
7596   bits<8> imm8;
7597   let Inst{31}    = 0;
7598   let Inst{30}    = Q;
7599   let Inst{29}    = op;
7600   let Inst{28-19} = 0b0111100000;
7601   let Inst{18-16} = imm8{7-5};
7602   let Inst{11} = op2;
7603   let Inst{10} = 1;
7604   let Inst{9-5}   = imm8{4-0};
7605   let Inst{4-0}   = Rd;
7606 }
7607
7608 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
7609                                 Operand immtype, dag opt_shift_iop,
7610                                 string opt_shift, string asm, string kind,
7611                                 list<dag> pattern>
7612   : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
7613                         !con((ins immtype:$imm8), opt_shift_iop), asm,
7614                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
7615                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7616                         "", pattern> {
7617   let DecoderMethod = "DecodeModImmInstruction";
7618 }
7619
7620 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
7621                                 Operand immtype, dag opt_shift_iop,
7622                                 string opt_shift, string asm, string kind,
7623                                 list<dag> pattern>
7624   : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
7625                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
7626                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
7627                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7628                         "$Rd = $dst", pattern> {
7629   let DecoderMethod = "DecodeModImmTiedInstruction";
7630 }
7631
7632 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
7633                                      RegisterOperand vectype, string asm,
7634                                      string kind, list<dag> pattern>
7635   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7636                               (ins logical_vec_shift:$shift),
7637                               "$shift", asm, kind, pattern> {
7638   bits<2> shift;
7639   let Inst{15}    = b15_b12{1};
7640   let Inst{14-13} = shift;
7641   let Inst{12}    = b15_b12{0};
7642 }
7643
7644 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
7645                                      RegisterOperand vectype, string asm,
7646                                      string kind, list<dag> pattern>
7647   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7648                               (ins logical_vec_shift:$shift),
7649                               "$shift", asm, kind, pattern> {
7650   bits<2> shift;
7651   let Inst{15}    = b15_b12{1};
7652   let Inst{14-13} = shift;
7653   let Inst{12}    = b15_b12{0};
7654 }
7655
7656
7657 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
7658                                          RegisterOperand vectype, string asm,
7659                                          string kind, list<dag> pattern>
7660   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7661                               (ins logical_vec_hw_shift:$shift),
7662                               "$shift", asm, kind, pattern> {
7663   bits<2> shift;
7664   let Inst{15} = b15_b12{1};
7665   let Inst{14} = 0;
7666   let Inst{13} = shift{0};
7667   let Inst{12} = b15_b12{0};
7668 }
7669
7670 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
7671                                          RegisterOperand vectype, string asm,
7672                                          string kind, list<dag> pattern>
7673   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7674                               (ins logical_vec_hw_shift:$shift),
7675                               "$shift", asm, kind, pattern> {
7676   bits<2> shift;
7677   let Inst{15} = b15_b12{1};
7678   let Inst{14} = 0;
7679   let Inst{13} = shift{0};
7680   let Inst{12} = b15_b12{0};
7681 }
7682
7683 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
7684                                       string asm> {
7685   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
7686                                                  asm, ".4h", []>;
7687   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
7688                                                  asm, ".8h", []>;
7689
7690   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
7691                                              asm, ".2s", []>;
7692   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
7693                                              asm, ".4s", []>;
7694 }
7695
7696 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
7697                                       bits<2> w_cmode, string asm,
7698                                       SDNode OpNode> {
7699   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
7700                                                  asm, ".4h",
7701              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
7702                                              imm0_255:$imm8,
7703                                              (i32 imm:$shift)))]>;
7704   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
7705                                                  asm, ".8h",
7706              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
7707                                               imm0_255:$imm8,
7708                                               (i32 imm:$shift)))]>;
7709
7710   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
7711                                              asm, ".2s",
7712              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
7713                                              imm0_255:$imm8,
7714                                              (i32 imm:$shift)))]>;
7715   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
7716                                              asm, ".4s",
7717              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
7718                                               imm0_255:$imm8,
7719                                               (i32 imm:$shift)))]>;
7720 }
7721
7722 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
7723                              RegisterOperand vectype, string asm,
7724                              string kind, list<dag> pattern>
7725   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7726                               (ins move_vec_shift:$shift),
7727                               "$shift", asm, kind, pattern> {
7728   bits<1> shift;
7729   let Inst{15-13} = cmode{3-1};
7730   let Inst{12}    = shift;
7731 }
7732
7733 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
7734                                    RegisterOperand vectype,
7735                                    Operand imm_type, string asm,
7736                                    string kind, list<dag> pattern>
7737   : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
7738                               asm, kind, pattern> {
7739   let Inst{15-12} = cmode;
7740 }
7741
7742 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
7743                                    list<dag> pattern>
7744   : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
7745                         "\t$Rd, $imm8", "", pattern> {
7746   let Inst{15-12} = cmode;
7747   let DecoderMethod = "DecodeModImmInstruction";
7748 }
7749
7750 //----------------------------------------------------------------------------
7751 // AdvSIMD indexed element
7752 //----------------------------------------------------------------------------
7753
7754 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7755 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7756                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
7757                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
7758                       string apple_kind, string dst_kind, string lhs_kind,
7759                       string rhs_kind, list<dag> pattern>
7760   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
7761       asm,
7762       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7763       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
7764     Sched<[WriteV]> {
7765   bits<5> Rd;
7766   bits<5> Rn;
7767   bits<5> Rm;
7768
7769   let Inst{31}    = 0;
7770   let Inst{30}    = Q;
7771   let Inst{29}    = U;
7772   let Inst{28}    = Scalar;
7773   let Inst{27-24} = 0b1111;
7774   let Inst{23-22} = size;
7775   // Bit 21 must be set by the derived class.
7776   let Inst{20-16} = Rm;
7777   let Inst{15-12} = opc;
7778   // Bit 11 must be set by the derived class.
7779   let Inst{10}    = 0;
7780   let Inst{9-5}   = Rn;
7781   let Inst{4-0}   = Rd;
7782 }
7783
7784 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7785 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7786                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
7787                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
7788                       string apple_kind, string dst_kind, string lhs_kind,
7789                       string rhs_kind, list<dag> pattern>
7790   : I<(outs dst_reg:$dst),
7791       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
7792       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7793       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
7794     Sched<[WriteV]> {
7795   bits<5> Rd;
7796   bits<5> Rn;
7797   bits<5> Rm;
7798
7799   let Inst{31}    = 0;
7800   let Inst{30}    = Q;
7801   let Inst{29}    = U;
7802   let Inst{28}    = Scalar;
7803   let Inst{27-24} = 0b1111;
7804   let Inst{23-22} = size;
7805   // Bit 21 must be set by the derived class.
7806   let Inst{20-16} = Rm;
7807   let Inst{15-12} = opc;
7808   // Bit 11 must be set by the derived class.
7809   let Inst{10}    = 0;
7810   let Inst{9-5}   = Rn;
7811   let Inst{4-0}   = Rd;
7812 }
7813
7814
7815 //----------------------------------------------------------------------------
7816 // Armv8.6 BFloat16 Extension
7817 //----------------------------------------------------------------------------
7818 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in {
7819
7820 class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1,
7821                                    string kind2, RegisterOperand RegType,
7822                                    ValueType AccumType, ValueType InputType>
7823   : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst),
7824                     (int_aarch64_neon_bfdot (AccumType RegType:$Rd),
7825                                             (InputType RegType:$Rn),
7826                                             (InputType RegType:$Rm)))]> {
7827   let AsmString = !strconcat(asm,
7828                              "{\t$Rd" # kind1 # ", $Rn" # kind2 #
7829                                ", $Rm" # kind2 # "}");
7830 }
7831
7832 multiclass SIMDThreeSameVectorBFDot<bit U, string asm> {
7833   def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64,
7834                                            v2f32, v8i8>;
7835   def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,
7836                                            v4f32, v16i8>;
7837 }
7838
7839 class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
7840                                       string dst_kind, string lhs_kind,
7841                                       string rhs_kind,
7842                                       RegisterOperand RegType,
7843                                       ValueType AccumType,
7844                                       ValueType InputType>
7845   : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111,
7846                         RegType, RegType, V128, VectorIndexS,
7847                         asm, "", dst_kind, lhs_kind, rhs_kind,
7848         [(set (AccumType RegType:$dst),
7849               (AccumType (int_aarch64_neon_bfdot
7850                                  (AccumType RegType:$Rd),
7851                                  (InputType RegType:$Rn),
7852                                  (InputType (bitconvert (AccumType
7853                                     (AArch64duplane32 (v4f32 V128:$Rm),
7854                                         VectorIndexH:$idx)))))))]> {
7855
7856   bits<2> idx;
7857   let Inst{21}    = idx{0};  // L
7858   let Inst{11}    = idx{1};  // H
7859 }
7860
7861 multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> {
7862
7863   def v4bf16  : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h",
7864                                                ".2h", V64, v2f32, v8i8>;
7865   def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h",
7866                                               ".2h", V128, v4f32, v16i8>;
7867 }
7868
7869 class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode>
7870   : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s",
7871               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
7872                                                (v16i8 V128:$Rn),
7873                                                (v16i8 V128:$Rm)))]> {
7874   let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}");
7875 }
7876
7877 class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode>
7878   : I<(outs V128:$dst),
7879       (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm,
7880       "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst",
7881           [(set (v4f32 V128:$dst),
7882                 (v4f32 (OpNode (v4f32 V128:$Rd),
7883                                (v16i8 V128:$Rn),
7884                                (v16i8 (bitconvert (v8bf16
7885                                   (AArch64duplane16 (v8bf16 V128_lo:$Rm),
7886                                       VectorIndexH:$idx)))))))]>,
7887     Sched<[WriteV]> {
7888   bits<5> Rd;
7889   bits<5> Rn;
7890   bits<4> Rm;
7891   bits<3> idx;
7892
7893   let Inst{31}    = 0;
7894   let Inst{30}    = Q;
7895   let Inst{29-22} = 0b00111111;
7896   let Inst{21-20} = idx{1-0};
7897   let Inst{19-16} = Rm;
7898   let Inst{15-12} = 0b1111;
7899   let Inst{11}    = idx{2};   // H
7900   let Inst{10}    = 0;
7901   let Inst{9-5}   = Rn;
7902   let Inst{4-0}   = Rd;
7903 }
7904
7905 class SIMDThreeSameVectorBF16MatrixMul<string asm>
7906   : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101,
7907                                 V128, asm, ".4s",
7908                           [(set (v4f32 V128:$dst),
7909                                 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd),
7910                                                          (v16i8 V128:$Rn),
7911                                                          (v16i8 V128:$Rm)))]> {
7912   let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h",
7913                                     ", $Rm", ".8h", "}");
7914 }
7915
7916 class SIMD_BFCVTN
7917   : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128,
7918                            "bfcvtn", ".4h", ".4s",
7919     [(set (v8bf16 V128:$Rd),
7920           (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>;
7921
7922 class SIMD_BFCVTN2
7923   : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128,
7924                            "bfcvtn2", ".8h", ".4s",
7925     [(set (v8bf16 V128:$dst),
7926           (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>;
7927
7928 class BF16ToSinglePrecision<string asm>
7929   : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "",
7930     [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>,
7931     Sched<[WriteFCvt]> {
7932   bits<5> Rd;
7933   bits<5> Rn;
7934   let Inst{31-10} = 0b0001111001100011010000;
7935   let Inst{9-5}   = Rn;
7936   let Inst{4-0}   = Rd;
7937 }
7938 } // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0
7939
7940 //----------------------------------------------------------------------------
7941 // Armv8.6 Matrix Multiply Extension
7942 //----------------------------------------------------------------------------
7943
7944 class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode>
7945   : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s",
7946               [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
7947                                                (v16i8 V128:$Rn),
7948                                                (v16i8 V128:$Rm)))]> {
7949   let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}";
7950 }
7951
7952 //----------------------------------------------------------------------------
7953 // ARMv8.2-A Dot Product Instructions (Indexed)
7954 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm,
7955                                       string dst_kind, string lhs_kind, string rhs_kind,
7956                                       RegisterOperand RegType,
7957                                       ValueType AccumType, ValueType InputType,
7958                                       SDPatternOperator OpNode> :
7959         BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128,
7960                             VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
7961         [(set (AccumType RegType:$dst),
7962               (AccumType (OpNode (AccumType RegType:$Rd),
7963                                  (InputType RegType:$Rn),
7964                                  (InputType (bitconvert (AccumType
7965                                     (AArch64duplane32 (v4i32 V128:$Rm),
7966                                         VectorIndexS:$idx)))))))]> {
7967   bits<2> idx;
7968   let Inst{21}    = idx{0};  // L
7969   let Inst{11}    = idx{1};  // H
7970 }
7971
7972 multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm,
7973                                        SDPatternOperator OpNode> {
7974   def v8i8  : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b",
7975                                               V64, v2i32, v8i8, OpNode>;
7976   def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b",
7977                                               V128, v4i32, v16i8, OpNode>;
7978 }
7979
7980 // ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed)
7981 class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm,
7982                                       string dst_kind, string lhs_kind,
7983                                       string rhs_kind, RegisterOperand RegType,
7984                                       ValueType AccumType, ValueType InputType,
7985                                       SDPatternOperator OpNode> :
7986         BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128,
7987                             VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind,
7988           [(set (AccumType RegType:$dst),
7989                 (AccumType (OpNode (AccumType RegType:$Rd),
7990                                    (InputType RegType:$Rn),
7991                                    (InputType (AArch64duplane16 (v8f16 V128:$Rm),
7992                                                 VectorIndexH:$idx)))))]> {
7993   // idx = H:L:M
7994   bits<3> idx;
7995   let Inst{11} = idx{2}; // H
7996   let Inst{21} = idx{1}; // L
7997   let Inst{20} = idx{0}; // M
7998 }
7999
8000 multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm,
8001                                        SDPatternOperator OpNode> {
8002   def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h",
8003                                               V64, v2f32, v4f16, OpNode>;
8004   def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h",
8005                                               V128, v4f32, v8f16, OpNode>;
8006 }
8007
8008 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
8009                          SDPatternOperator OpNode> {
8010   let Predicates = [HasNEON, HasFullFP16] in {
8011   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
8012                                       V64, V64,
8013                                       V128_lo, VectorIndexH,
8014                                       asm, ".4h", ".4h", ".4h", ".h",
8015     [(set (v4f16 V64:$Rd),
8016         (OpNode (v4f16 V64:$Rn),
8017          (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8018     bits<3> idx;
8019     let Inst{11} = idx{2};
8020     let Inst{21} = idx{1};
8021     let Inst{20} = idx{0};
8022   }
8023
8024   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
8025                                       V128, V128,
8026                                       V128_lo, VectorIndexH,
8027                                       asm, ".8h", ".8h", ".8h", ".h",
8028     [(set (v8f16 V128:$Rd),
8029         (OpNode (v8f16 V128:$Rn),
8030          (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8031     bits<3> idx;
8032     let Inst{11} = idx{2};
8033     let Inst{21} = idx{1};
8034     let Inst{20} = idx{0};
8035   }
8036   } // Predicates = [HasNEON, HasFullFP16]
8037
8038   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8039                                       V64, V64,
8040                                       V128, VectorIndexS,
8041                                       asm, ".2s", ".2s", ".2s", ".s",
8042     [(set (v2f32 V64:$Rd),
8043         (OpNode (v2f32 V64:$Rn),
8044          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8045     bits<2> idx;
8046     let Inst{11} = idx{1};
8047     let Inst{21} = idx{0};
8048   }
8049
8050   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8051                                       V128, V128,
8052                                       V128, VectorIndexS,
8053                                       asm, ".4s", ".4s", ".4s", ".s",
8054     [(set (v4f32 V128:$Rd),
8055         (OpNode (v4f32 V128:$Rn),
8056          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8057     bits<2> idx;
8058     let Inst{11} = idx{1};
8059     let Inst{21} = idx{0};
8060   }
8061
8062   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
8063                                       V128, V128,
8064                                       V128, VectorIndexD,
8065                                       asm, ".2d", ".2d", ".2d", ".d",
8066     [(set (v2f64 V128:$Rd),
8067         (OpNode (v2f64 V128:$Rn),
8068          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
8069     bits<1> idx;
8070     let Inst{11} = idx{0};
8071     let Inst{21} = 0;
8072   }
8073
8074   let Predicates = [HasNEON, HasFullFP16] in {
8075   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
8076                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8077                                       asm, ".h", "", "", ".h",
8078     [(set (f16 FPR16Op:$Rd),
8079           (OpNode (f16 FPR16Op:$Rn),
8080                   (f16 (vector_extract (v8f16 V128_lo:$Rm),
8081                                        VectorIndexH:$idx))))]> {
8082     bits<3> idx;
8083     let Inst{11} = idx{2};
8084     let Inst{21} = idx{1};
8085     let Inst{20} = idx{0};
8086   }
8087   } // Predicates = [HasNEON, HasFullFP16]
8088
8089   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8090                                       FPR32Op, FPR32Op, V128, VectorIndexS,
8091                                       asm, ".s", "", "", ".s",
8092     [(set (f32 FPR32Op:$Rd),
8093           (OpNode (f32 FPR32Op:$Rn),
8094                   (f32 (vector_extract (v4f32 V128:$Rm),
8095                                        VectorIndexS:$idx))))]> {
8096     bits<2> idx;
8097     let Inst{11} = idx{1};
8098     let Inst{21} = idx{0};
8099   }
8100
8101   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
8102                                       FPR64Op, FPR64Op, V128, VectorIndexD,
8103                                       asm, ".d", "", "", ".d",
8104     [(set (f64 FPR64Op:$Rd),
8105           (OpNode (f64 FPR64Op:$Rn),
8106                   (f64 (vector_extract (v2f64 V128:$Rm),
8107                                        VectorIndexD:$idx))))]> {
8108     bits<1> idx;
8109     let Inst{11} = idx{0};
8110     let Inst{21} = 0;
8111   }
8112 }
8113
8114 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
8115   let Predicates = [HasNEON, HasFullFP16] in {
8116   // Patterns for f16: DUPLANE, DUP scalar and vector_extract.
8117   def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8118                            (AArch64duplane16 (v8f16 V128_lo:$Rm),
8119                                            VectorIndexH:$idx))),
8120             (!cast<Instruction>(INST # "v8i16_indexed")
8121                 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8122   def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8123                            (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8124             (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn,
8125                 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8126
8127   def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8128                            (AArch64duplane16 (v8f16 V128_lo:$Rm),
8129                                            VectorIndexH:$idx))),
8130             (!cast<Instruction>(INST # "v4i16_indexed")
8131                 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8132   def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8133                            (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8134             (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn,
8135                 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8136
8137   def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn),
8138                          (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))),
8139             (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn,
8140                 V128_lo:$Rm, VectorIndexH:$idx)>;
8141   } // Predicates = [HasNEON, HasFullFP16]
8142
8143   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
8144   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8145                            (AArch64duplane32 (v4f32 V128:$Rm),
8146                                            VectorIndexS:$idx))),
8147             (!cast<Instruction>(INST # v2i32_indexed)
8148                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8149   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8150                            (AArch64dup (f32 FPR32Op:$Rm)))),
8151             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
8152                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8153
8154
8155   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
8156   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8157                            (AArch64duplane32 (v4f32 V128:$Rm),
8158                                            VectorIndexS:$idx))),
8159             (!cast<Instruction>(INST # "v4i32_indexed")
8160                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8161   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8162                            (AArch64dup (f32 FPR32Op:$Rm)))),
8163             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
8164                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8165
8166   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
8167   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
8168                            (AArch64duplane64 (v2f64 V128:$Rm),
8169                                            VectorIndexD:$idx))),
8170             (!cast<Instruction>(INST # "v2i64_indexed")
8171                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8172   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
8173                            (AArch64dup (f64 FPR64Op:$Rm)))),
8174             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
8175                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
8176
8177   // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s
8178   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
8179                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
8180             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
8181                 V128:$Rm, VectorIndexS:$idx)>;
8182
8183   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
8184   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
8185                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
8186             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
8187                 V128:$Rm, VectorIndexD:$idx)>;
8188 }
8189
8190 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
8191   let Predicates = [HasNEON, HasFullFP16] in {
8192   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
8193                                           V128_lo, VectorIndexH,
8194                                           asm, ".4h", ".4h", ".4h", ".h", []> {
8195     bits<3> idx;
8196     let Inst{11} = idx{2};
8197     let Inst{21} = idx{1};
8198     let Inst{20} = idx{0};
8199   }
8200
8201   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
8202                                           V128, V128,
8203                                           V128_lo, VectorIndexH,
8204                                           asm, ".8h", ".8h", ".8h", ".h", []> {
8205     bits<3> idx;
8206     let Inst{11} = idx{2};
8207     let Inst{21} = idx{1};
8208     let Inst{20} = idx{0};
8209   }
8210   } // Predicates = [HasNEON, HasFullFP16]
8211
8212   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
8213                                           V128, VectorIndexS,
8214                                           asm, ".2s", ".2s", ".2s", ".s", []> {
8215     bits<2> idx;
8216     let Inst{11} = idx{1};
8217     let Inst{21} = idx{0};
8218   }
8219
8220   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8221                                       V128, V128,
8222                                       V128, VectorIndexS,
8223                                       asm, ".4s", ".4s", ".4s", ".s", []> {
8224     bits<2> idx;
8225     let Inst{11} = idx{1};
8226     let Inst{21} = idx{0};
8227   }
8228
8229   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
8230                                       V128, V128,
8231                                       V128, VectorIndexD,
8232                                       asm, ".2d", ".2d", ".2d", ".d", []> {
8233     bits<1> idx;
8234     let Inst{11} = idx{0};
8235     let Inst{21} = 0;
8236   }
8237
8238   let Predicates = [HasNEON, HasFullFP16] in {
8239   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
8240                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8241                                       asm, ".h", "", "", ".h", []> {
8242     bits<3> idx;
8243     let Inst{11} = idx{2};
8244     let Inst{21} = idx{1};
8245     let Inst{20} = idx{0};
8246   }
8247   } // Predicates = [HasNEON, HasFullFP16]
8248
8249   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8250                                       FPR32Op, FPR32Op, V128, VectorIndexS,
8251                                       asm, ".s", "", "", ".s", []> {
8252     bits<2> idx;
8253     let Inst{11} = idx{1};
8254     let Inst{21} = idx{0};
8255   }
8256
8257   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
8258                                       FPR64Op, FPR64Op, V128, VectorIndexD,
8259                                       asm, ".d", "", "", ".d", []> {
8260     bits<1> idx;
8261     let Inst{11} = idx{0};
8262     let Inst{21} = 0;
8263   }
8264 }
8265
8266 multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane,
8267                                  SDPatternOperator OpNodeLaneQ> {
8268
8269   def : Pat<(v4i16 (OpNodeLane
8270                      (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm),
8271                      VectorIndexS32b:$idx)),
8272             (!cast<Instruction>(NAME # v4i16_indexed) $Rn,
8273               (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub),
8274               (UImmS1XForm $idx))>;
8275
8276   def : Pat<(v4i16 (OpNodeLaneQ
8277                      (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm),
8278                      VectorIndexH32b:$idx)),
8279             (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm,
8280               (UImmS1XForm $idx))>;
8281
8282   def : Pat<(v8i16 (OpNodeLane
8283                      (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm),
8284                      VectorIndexS32b:$idx)),
8285             (!cast<Instruction>(NAME # v8i16_indexed) $Rn,
8286               (SUBREG_TO_REG (i32 0), $Rm, dsub),
8287               (UImmS1XForm $idx))>;
8288
8289   def : Pat<(v8i16 (OpNodeLaneQ
8290                      (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm),
8291                      VectorIndexH32b:$idx)),
8292             (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm,
8293               (UImmS1XForm $idx))>;
8294
8295   def : Pat<(v2i32 (OpNodeLane
8296                      (v2i32 V64:$Rn), (v2i32 V64:$Rm),
8297                      VectorIndexD32b:$idx)),
8298             (!cast<Instruction>(NAME # v2i32_indexed) $Rn,
8299               (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub),
8300               (UImmS1XForm $idx))>;
8301
8302   def : Pat<(v2i32 (OpNodeLaneQ
8303                      (v2i32 V64:$Rn), (v4i32 V128:$Rm),
8304                      VectorIndexS32b:$idx)),
8305             (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm,
8306               (UImmS1XForm $idx))>;
8307
8308   def : Pat<(v4i32 (OpNodeLane
8309                      (v4i32 V128:$Rn), (v2i32 V64:$Rm),
8310                      VectorIndexD32b:$idx)),
8311             (!cast<Instruction>(NAME # v4i32_indexed) $Rn,
8312               (SUBREG_TO_REG (i32 0), $Rm, dsub),
8313               (UImmS1XForm $idx))>;
8314
8315   def : Pat<(v4i32 (OpNodeLaneQ
8316                      (v4i32 V128:$Rn),
8317                      (v4i32 V128:$Rm),
8318                      VectorIndexS32b:$idx)),
8319             (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm,
8320               (UImmS1XForm $idx))>;
8321
8322 }
8323
8324 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
8325                          SDPatternOperator OpNode> {
8326   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
8327                                       V128_lo, VectorIndexH,
8328                                       asm, ".4h", ".4h", ".4h", ".h",
8329     [(set (v4i16 V64:$Rd),
8330         (OpNode (v4i16 V64:$Rn),
8331          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8332     bits<3> idx;
8333     let Inst{11} = idx{2};
8334     let Inst{21} = idx{1};
8335     let Inst{20} = idx{0};
8336   }
8337
8338   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8339                                       V128, V128,
8340                                       V128_lo, VectorIndexH,
8341                                       asm, ".8h", ".8h", ".8h", ".h",
8342     [(set (v8i16 V128:$Rd),
8343        (OpNode (v8i16 V128:$Rn),
8344          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8345     bits<3> idx;
8346     let Inst{11} = idx{2};
8347     let Inst{21} = idx{1};
8348     let Inst{20} = idx{0};
8349   }
8350
8351   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8352                                       V64, V64,
8353                                       V128, VectorIndexS,
8354                                       asm, ".2s", ".2s", ".2s",  ".s",
8355     [(set (v2i32 V64:$Rd),
8356        (OpNode (v2i32 V64:$Rn),
8357           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8358     bits<2> idx;
8359     let Inst{11} = idx{1};
8360     let Inst{21} = idx{0};
8361   }
8362
8363   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8364                                       V128, V128,
8365                                       V128, VectorIndexS,
8366                                       asm, ".4s", ".4s", ".4s", ".s",
8367     [(set (v4i32 V128:$Rd),
8368        (OpNode (v4i32 V128:$Rn),
8369           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8370     bits<2> idx;
8371     let Inst{11} = idx{1};
8372     let Inst{21} = idx{0};
8373   }
8374
8375   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
8376                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8377                                       asm, ".h", "", "", ".h", []> {
8378     bits<3> idx;
8379     let Inst{11} = idx{2};
8380     let Inst{21} = idx{1};
8381     let Inst{20} = idx{0};
8382   }
8383
8384   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8385                                       FPR32Op, FPR32Op, V128, VectorIndexS,
8386                                       asm, ".s", "", "", ".s",
8387       [(set (i32 FPR32Op:$Rd),
8388             (OpNode FPR32Op:$Rn,
8389                     (i32 (vector_extract (v4i32 V128:$Rm),
8390                                          VectorIndexS:$idx))))]> {
8391     bits<2> idx;
8392     let Inst{11} = idx{1};
8393     let Inst{21} = idx{0};
8394   }
8395 }
8396
8397 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
8398                                SDPatternOperator OpNode> {
8399   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8400                                       V64, V64,
8401                                       V128_lo, VectorIndexH,
8402                                       asm, ".4h", ".4h", ".4h", ".h",
8403     [(set (v4i16 V64:$Rd),
8404         (OpNode (v4i16 V64:$Rn),
8405          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8406     bits<3> idx;
8407     let Inst{11} = idx{2};
8408     let Inst{21} = idx{1};
8409     let Inst{20} = idx{0};
8410   }
8411
8412   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8413                                       V128, V128,
8414                                       V128_lo, VectorIndexH,
8415                                       asm, ".8h", ".8h", ".8h", ".h",
8416     [(set (v8i16 V128:$Rd),
8417        (OpNode (v8i16 V128:$Rn),
8418          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8419     bits<3> idx;
8420     let Inst{11} = idx{2};
8421     let Inst{21} = idx{1};
8422     let Inst{20} = idx{0};
8423   }
8424
8425   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8426                                       V64, V64,
8427                                       V128, VectorIndexS,
8428                                       asm, ".2s", ".2s", ".2s", ".s",
8429     [(set (v2i32 V64:$Rd),
8430        (OpNode (v2i32 V64:$Rn),
8431           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8432     bits<2> idx;
8433     let Inst{11} = idx{1};
8434     let Inst{21} = idx{0};
8435   }
8436
8437   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8438                                       V128, V128,
8439                                       V128, VectorIndexS,
8440                                       asm, ".4s", ".4s", ".4s", ".s",
8441     [(set (v4i32 V128:$Rd),
8442        (OpNode (v4i32 V128:$Rn),
8443           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8444     bits<2> idx;
8445     let Inst{11} = idx{1};
8446     let Inst{21} = idx{0};
8447   }
8448 }
8449
8450 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
8451                                    SDPatternOperator OpNode> {
8452   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
8453                                           V128_lo, VectorIndexH,
8454                                           asm, ".4h", ".4h", ".4h", ".h",
8455     [(set (v4i16 V64:$dst),
8456         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
8457          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8458     bits<3> idx;
8459     let Inst{11} = idx{2};
8460     let Inst{21} = idx{1};
8461     let Inst{20} = idx{0};
8462   }
8463
8464   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8465                                       V128, V128,
8466                                       V128_lo, VectorIndexH,
8467                                       asm, ".8h", ".8h", ".8h", ".h",
8468     [(set (v8i16 V128:$dst),
8469        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8470          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8471     bits<3> idx;
8472     let Inst{11} = idx{2};
8473     let Inst{21} = idx{1};
8474     let Inst{20} = idx{0};
8475   }
8476
8477   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8478                                       V64, V64,
8479                                       V128, VectorIndexS,
8480                                       asm, ".2s", ".2s", ".2s", ".s",
8481     [(set (v2i32 V64:$dst),
8482        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8483           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8484     bits<2> idx;
8485     let Inst{11} = idx{1};
8486     let Inst{21} = idx{0};
8487   }
8488
8489   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8490                                       V128, V128,
8491                                       V128, VectorIndexS,
8492                                       asm, ".4s", ".4s", ".4s", ".s",
8493     [(set (v4i32 V128:$dst),
8494        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8495           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8496     bits<2> idx;
8497     let Inst{11} = idx{1};
8498     let Inst{21} = idx{0};
8499   }
8500 }
8501
8502 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
8503                              SDPatternOperator OpNode> {
8504   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8505                                       V128, V64,
8506                                       V128_lo, VectorIndexH,
8507                                       asm, ".4s", ".4s", ".4h", ".h",
8508     [(set (v4i32 V128:$Rd),
8509         (OpNode (v4i16 V64:$Rn),
8510          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8511     bits<3> idx;
8512     let Inst{11} = idx{2};
8513     let Inst{21} = idx{1};
8514     let Inst{20} = idx{0};
8515   }
8516
8517   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8518                                       V128, V128,
8519                                       V128_lo, VectorIndexH,
8520                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8521     [(set (v4i32 V128:$Rd),
8522           (OpNode (extract_high_v8i16 V128:$Rn),
8523                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8524                                                       VectorIndexH:$idx))))]> {
8525
8526     bits<3> idx;
8527     let Inst{11} = idx{2};
8528     let Inst{21} = idx{1};
8529     let Inst{20} = idx{0};
8530   }
8531
8532   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8533                                       V128, V64,
8534                                       V128, VectorIndexS,
8535                                       asm, ".2d", ".2d", ".2s", ".s",
8536     [(set (v2i64 V128:$Rd),
8537         (OpNode (v2i32 V64:$Rn),
8538          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8539     bits<2> idx;
8540     let Inst{11} = idx{1};
8541     let Inst{21} = idx{0};
8542   }
8543
8544   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8545                                       V128, V128,
8546                                       V128, VectorIndexS,
8547                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8548     [(set (v2i64 V128:$Rd),
8549           (OpNode (extract_high_v4i32 V128:$Rn),
8550                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8551                                                       VectorIndexS:$idx))))]> {
8552     bits<2> idx;
8553     let Inst{11} = idx{1};
8554     let Inst{21} = idx{0};
8555   }
8556
8557   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
8558                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8559                                       asm, ".h", "", "", ".h", []> {
8560     bits<3> idx;
8561     let Inst{11} = idx{2};
8562     let Inst{21} = idx{1};
8563     let Inst{20} = idx{0};
8564   }
8565
8566   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8567                                       FPR64Op, FPR32Op, V128, VectorIndexS,
8568                                       asm, ".s", "", "", ".s", []> {
8569     bits<2> idx;
8570     let Inst{11} = idx{1};
8571     let Inst{21} = idx{0};
8572   }
8573 }
8574
8575 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
8576                                        SDPatternOperator Accum> {
8577   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8578                                       V128, V64,
8579                                       V128_lo, VectorIndexH,
8580                                       asm, ".4s", ".4s", ".4h", ".h",
8581     [(set (v4i32 V128:$dst),
8582           (Accum (v4i32 V128:$Rd),
8583                  (v4i32 (int_aarch64_neon_sqdmull
8584                              (v4i16 V64:$Rn),
8585                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8586                                                     VectorIndexH:$idx))))))]> {
8587     bits<3> idx;
8588     let Inst{11} = idx{2};
8589     let Inst{21} = idx{1};
8590     let Inst{20} = idx{0};
8591   }
8592
8593   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
8594   // intermediate EXTRACT_SUBREG would be untyped.
8595   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8596                 (i32 (vector_extract (v4i32
8597                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
8598                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8599                                                     VectorIndexH:$idx)))),
8600                          (i64 0))))),
8601             (EXTRACT_SUBREG
8602                 (!cast<Instruction>(NAME # v4i16_indexed)
8603                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
8604                     V128_lo:$Rm, VectorIndexH:$idx),
8605                 ssub)>;
8606
8607   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8608                                       V128, V128,
8609                                       V128_lo, VectorIndexH,
8610                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8611     [(set (v4i32 V128:$dst),
8612           (Accum (v4i32 V128:$Rd),
8613                  (v4i32 (int_aarch64_neon_sqdmull
8614                             (extract_high_v8i16 V128:$Rn),
8615                             (extract_high_v8i16
8616                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8617                                                 VectorIndexH:$idx))))))]> {
8618     bits<3> idx;
8619     let Inst{11} = idx{2};
8620     let Inst{21} = idx{1};
8621     let Inst{20} = idx{0};
8622   }
8623
8624   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8625                                       V128, V64,
8626                                       V128, VectorIndexS,
8627                                       asm, ".2d", ".2d", ".2s", ".s",
8628     [(set (v2i64 V128:$dst),
8629         (Accum (v2i64 V128:$Rd),
8630                (v2i64 (int_aarch64_neon_sqdmull
8631                           (v2i32 V64:$Rn),
8632                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8633                                                  VectorIndexS:$idx))))))]> {
8634     bits<2> idx;
8635     let Inst{11} = idx{1};
8636     let Inst{21} = idx{0};
8637   }
8638
8639   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8640                                       V128, V128,
8641                                       V128, VectorIndexS,
8642                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8643     [(set (v2i64 V128:$dst),
8644           (Accum (v2i64 V128:$Rd),
8645                  (v2i64 (int_aarch64_neon_sqdmull
8646                             (extract_high_v4i32 V128:$Rn),
8647                             (extract_high_v4i32
8648                                 (AArch64duplane32 (v4i32 V128:$Rm),
8649                                                 VectorIndexS:$idx))))))]> {
8650     bits<2> idx;
8651     let Inst{11} = idx{1};
8652     let Inst{21} = idx{0};
8653   }
8654
8655   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8656                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8657                                       asm, ".h", "", "", ".h", []> {
8658     bits<3> idx;
8659     let Inst{11} = idx{2};
8660     let Inst{21} = idx{1};
8661     let Inst{20} = idx{0};
8662   }
8663
8664
8665   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8666                                       FPR64Op, FPR32Op, V128, VectorIndexS,
8667                                       asm, ".s", "", "", ".s",
8668     [(set (i64 FPR64Op:$dst),
8669           (Accum (i64 FPR64Op:$Rd),
8670                  (i64 (int_aarch64_neon_sqdmulls_scalar
8671                             (i32 FPR32Op:$Rn),
8672                             (i32 (vector_extract (v4i32 V128:$Rm),
8673                                                  VectorIndexS:$idx))))))]> {
8674
8675     bits<2> idx;
8676     let Inst{11} = idx{1};
8677     let Inst{21} = idx{0};
8678   }
8679 }
8680
8681 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
8682                                    SDPatternOperator OpNode> {
8683   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8684   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8685                                       V128, V64,
8686                                       V128_lo, VectorIndexH,
8687                                       asm, ".4s", ".4s", ".4h", ".h",
8688     [(set (v4i32 V128:$Rd),
8689         (OpNode (v4i16 V64:$Rn),
8690          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8691     bits<3> idx;
8692     let Inst{11} = idx{2};
8693     let Inst{21} = idx{1};
8694     let Inst{20} = idx{0};
8695   }
8696
8697   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8698                                       V128, V128,
8699                                       V128_lo, VectorIndexH,
8700                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8701     [(set (v4i32 V128:$Rd),
8702           (OpNode (extract_high_v8i16 V128:$Rn),
8703                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8704                                                       VectorIndexH:$idx))))]> {
8705
8706     bits<3> idx;
8707     let Inst{11} = idx{2};
8708     let Inst{21} = idx{1};
8709     let Inst{20} = idx{0};
8710   }
8711
8712   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8713                                       V128, V64,
8714                                       V128, VectorIndexS,
8715                                       asm, ".2d", ".2d", ".2s", ".s",
8716     [(set (v2i64 V128:$Rd),
8717         (OpNode (v2i32 V64:$Rn),
8718          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8719     bits<2> idx;
8720     let Inst{11} = idx{1};
8721     let Inst{21} = idx{0};
8722   }
8723
8724   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8725                                       V128, V128,
8726                                       V128, VectorIndexS,
8727                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8728     [(set (v2i64 V128:$Rd),
8729           (OpNode (extract_high_v4i32 V128:$Rn),
8730                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8731                                                       VectorIndexS:$idx))))]> {
8732     bits<2> idx;
8733     let Inst{11} = idx{1};
8734     let Inst{21} = idx{0};
8735   }
8736   }
8737 }
8738
8739 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
8740                                        SDPatternOperator OpNode> {
8741   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8742   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8743                                       V128, V64,
8744                                       V128_lo, VectorIndexH,
8745                                       asm, ".4s", ".4s", ".4h", ".h",
8746     [(set (v4i32 V128:$dst),
8747         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
8748          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8749     bits<3> idx;
8750     let Inst{11} = idx{2};
8751     let Inst{21} = idx{1};
8752     let Inst{20} = idx{0};
8753   }
8754
8755   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8756                                       V128, V128,
8757                                       V128_lo, VectorIndexH,
8758                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8759     [(set (v4i32 V128:$dst),
8760           (OpNode (v4i32 V128:$Rd),
8761                   (extract_high_v8i16 V128:$Rn),
8762                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8763                                                       VectorIndexH:$idx))))]> {
8764     bits<3> idx;
8765     let Inst{11} = idx{2};
8766     let Inst{21} = idx{1};
8767     let Inst{20} = idx{0};
8768   }
8769
8770   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8771                                       V128, V64,
8772                                       V128, VectorIndexS,
8773                                       asm, ".2d", ".2d", ".2s", ".s",
8774     [(set (v2i64 V128:$dst),
8775         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
8776          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8777     bits<2> idx;
8778     let Inst{11} = idx{1};
8779     let Inst{21} = idx{0};
8780   }
8781
8782   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8783                                       V128, V128,
8784                                       V128, VectorIndexS,
8785                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8786     [(set (v2i64 V128:$dst),
8787           (OpNode (v2i64 V128:$Rd),
8788                   (extract_high_v4i32 V128:$Rn),
8789                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8790                                                       VectorIndexS:$idx))))]> {
8791     bits<2> idx;
8792     let Inst{11} = idx{1};
8793     let Inst{21} = idx{0};
8794   }
8795   }
8796 }
8797
8798 //----------------------------------------------------------------------------
8799 // AdvSIMD scalar shift by immediate
8800 //----------------------------------------------------------------------------
8801
8802 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8803 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
8804                      RegisterClass regtype1, RegisterClass regtype2,
8805                      Operand immtype, string asm, list<dag> pattern>
8806   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
8807       asm, "\t$Rd, $Rn, $imm", "", pattern>,
8808     Sched<[WriteV]> {
8809   bits<5> Rd;
8810   bits<5> Rn;
8811   bits<7> imm;
8812   let Inst{31-30} = 0b01;
8813   let Inst{29}    = U;
8814   let Inst{28-23} = 0b111110;
8815   let Inst{22-16} = fixed_imm;
8816   let Inst{15-11} = opc;
8817   let Inst{10}    = 1;
8818   let Inst{9-5} = Rn;
8819   let Inst{4-0} = Rd;
8820 }
8821
8822 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8823 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
8824                      RegisterClass regtype1, RegisterClass regtype2,
8825                      Operand immtype, string asm, list<dag> pattern>
8826   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
8827       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
8828     Sched<[WriteV]> {
8829   bits<5> Rd;
8830   bits<5> Rn;
8831   bits<7> imm;
8832   let Inst{31-30} = 0b01;
8833   let Inst{29}    = U;
8834   let Inst{28-23} = 0b111110;
8835   let Inst{22-16} = fixed_imm;
8836   let Inst{15-11} = opc;
8837   let Inst{10}    = 1;
8838   let Inst{9-5} = Rn;
8839   let Inst{4-0} = Rd;
8840 }
8841
8842
8843 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
8844   let Predicates = [HasNEON, HasFullFP16] in {
8845   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8846                               FPR16, FPR16, vecshiftR16, asm, []> {
8847     let Inst{19-16} = imm{3-0};
8848   }
8849   } // Predicates = [HasNEON, HasFullFP16]
8850   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8851                               FPR32, FPR32, vecshiftR32, asm, []> {
8852     let Inst{20-16} = imm{4-0};
8853   }
8854   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8855                               FPR64, FPR64, vecshiftR64, asm, []> {
8856     let Inst{21-16} = imm{5-0};
8857   }
8858 }
8859
8860 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
8861                              SDPatternOperator OpNode> {
8862   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8863                               FPR64, FPR64, vecshiftR64, asm,
8864   [(set (i64 FPR64:$Rd),
8865      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
8866     let Inst{21-16} = imm{5-0};
8867   }
8868
8869   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
8870             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
8871 }
8872
8873 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
8874                                  SDPatternOperator OpNode = null_frag> {
8875   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8876                               FPR64, FPR64, vecshiftR64, asm,
8877   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
8878                                                    (i32 vecshiftR64:$imm)))]> {
8879     let Inst{21-16} = imm{5-0};
8880   }
8881
8882   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
8883                            (i32 vecshiftR64:$imm))),
8884             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
8885                                             vecshiftR64:$imm)>;
8886 }
8887
8888 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
8889                              SDPatternOperator OpNode> {
8890   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8891                               FPR64, FPR64, vecshiftL64, asm,
8892     [(set (v1i64 FPR64:$Rd),
8893        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8894     let Inst{21-16} = imm{5-0};
8895   }
8896 }
8897
8898 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8899 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
8900   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8901                               FPR64, FPR64, vecshiftL64, asm, []> {
8902     let Inst{21-16} = imm{5-0};
8903   }
8904 }
8905
8906 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8907 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
8908                                SDPatternOperator OpNode = null_frag> {
8909   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8910                               FPR8, FPR16, vecshiftR8, asm, []> {
8911     let Inst{18-16} = imm{2-0};
8912   }
8913
8914   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8915                               FPR16, FPR32, vecshiftR16, asm, []> {
8916     let Inst{19-16} = imm{3-0};
8917   }
8918
8919   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8920                               FPR32, FPR64, vecshiftR32, asm,
8921     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
8922     let Inst{20-16} = imm{4-0};
8923   }
8924 }
8925
8926 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
8927                                 SDPatternOperator OpNode> {
8928   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8929                               FPR8, FPR8, vecshiftL8, asm, []> {
8930     let Inst{18-16} = imm{2-0};
8931   }
8932
8933   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8934                               FPR16, FPR16, vecshiftL16, asm, []> {
8935     let Inst{19-16} = imm{3-0};
8936   }
8937
8938   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8939                               FPR32, FPR32, vecshiftL32, asm,
8940     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
8941     let Inst{20-16} = imm{4-0};
8942   }
8943
8944   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8945                               FPR64, FPR64, vecshiftL64, asm,
8946     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8947     let Inst{21-16} = imm{5-0};
8948   }
8949
8950   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
8951             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
8952 }
8953
8954 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
8955   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8956                               FPR8, FPR8, vecshiftR8, asm, []> {
8957     let Inst{18-16} = imm{2-0};
8958   }
8959
8960   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8961                               FPR16, FPR16, vecshiftR16, asm, []> {
8962     let Inst{19-16} = imm{3-0};
8963   }
8964
8965   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8966                               FPR32, FPR32, vecshiftR32, asm, []> {
8967     let Inst{20-16} = imm{4-0};
8968   }
8969
8970   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8971                               FPR64, FPR64, vecshiftR64, asm, []> {
8972     let Inst{21-16} = imm{5-0};
8973   }
8974 }
8975
8976 //----------------------------------------------------------------------------
8977 // AdvSIMD vector x indexed element
8978 //----------------------------------------------------------------------------
8979
8980 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8981 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8982                      RegisterOperand dst_reg, RegisterOperand src_reg,
8983                      Operand immtype,
8984                      string asm, string dst_kind, string src_kind,
8985                      list<dag> pattern>
8986   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
8987       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8988            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
8989     Sched<[WriteV]> {
8990   bits<5> Rd;
8991   bits<5> Rn;
8992   let Inst{31}    = 0;
8993   let Inst{30}    = Q;
8994   let Inst{29}    = U;
8995   let Inst{28-23} = 0b011110;
8996   let Inst{22-16} = fixed_imm;
8997   let Inst{15-11} = opc;
8998   let Inst{10}    = 1;
8999   let Inst{9-5}   = Rn;
9000   let Inst{4-0}   = Rd;
9001 }
9002
9003 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9004 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
9005                      RegisterOperand vectype1, RegisterOperand vectype2,
9006                      Operand immtype,
9007                      string asm, string dst_kind, string src_kind,
9008                      list<dag> pattern>
9009   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
9010       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
9011            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
9012     Sched<[WriteV]> {
9013   bits<5> Rd;
9014   bits<5> Rn;
9015   let Inst{31}    = 0;
9016   let Inst{30}    = Q;
9017   let Inst{29}    = U;
9018   let Inst{28-23} = 0b011110;
9019   let Inst{22-16} = fixed_imm;
9020   let Inst{15-11} = opc;
9021   let Inst{10}    = 1;
9022   let Inst{9-5}   = Rn;
9023   let Inst{4-0}   = Rd;
9024 }
9025
9026 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
9027                               Intrinsic OpNode> {
9028   let Predicates = [HasNEON, HasFullFP16] in {
9029   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9030                                   V64, V64, vecshiftR16,
9031                                   asm, ".4h", ".4h",
9032       [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
9033     bits<4> imm;
9034     let Inst{19-16} = imm;
9035   }
9036
9037   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9038                                   V128, V128, vecshiftR16,
9039                                   asm, ".8h", ".8h",
9040       [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
9041     bits<4> imm;
9042     let Inst{19-16} = imm;
9043   }
9044   } // Predicates = [HasNEON, HasFullFP16]
9045   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9046                                   V64, V64, vecshiftR32,
9047                                   asm, ".2s", ".2s",
9048       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
9049     bits<5> imm;
9050     let Inst{20-16} = imm;
9051   }
9052
9053   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9054                                   V128, V128, vecshiftR32,
9055                                   asm, ".4s", ".4s",
9056       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
9057     bits<5> imm;
9058     let Inst{20-16} = imm;
9059   }
9060
9061   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9062                                   V128, V128, vecshiftR64,
9063                                   asm, ".2d", ".2d",
9064       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
9065     bits<6> imm;
9066     let Inst{21-16} = imm;
9067   }
9068 }
9069
9070 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
9071                                   Intrinsic OpNode> {
9072   let Predicates = [HasNEON, HasFullFP16] in {
9073   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9074                                   V64, V64, vecshiftR16,
9075                                   asm, ".4h", ".4h",
9076       [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
9077     bits<4> imm;
9078     let Inst{19-16} = imm;
9079   }
9080
9081   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9082                                   V128, V128, vecshiftR16,
9083                                   asm, ".8h", ".8h",
9084       [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
9085     bits<4> imm;
9086     let Inst{19-16} = imm;
9087   }
9088   } // Predicates = [HasNEON, HasFullFP16]
9089
9090   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9091                                   V64, V64, vecshiftR32,
9092                                   asm, ".2s", ".2s",
9093       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
9094     bits<5> imm;
9095     let Inst{20-16} = imm;
9096   }
9097
9098   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9099                                   V128, V128, vecshiftR32,
9100                                   asm, ".4s", ".4s",
9101       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
9102     bits<5> imm;
9103     let Inst{20-16} = imm;
9104   }
9105
9106   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9107                                   V128, V128, vecshiftR64,
9108                                   asm, ".2d", ".2d",
9109       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
9110     bits<6> imm;
9111     let Inst{21-16} = imm;
9112   }
9113 }
9114
9115 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
9116                                      SDPatternOperator OpNode> {
9117   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9118                                   V64, V128, vecshiftR16Narrow,
9119                                   asm, ".8b", ".8h",
9120       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
9121     bits<3> imm;
9122     let Inst{18-16} = imm;
9123   }
9124
9125   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9126                                   V128, V128, vecshiftR16Narrow,
9127                                   asm#"2", ".16b", ".8h", []> {
9128     bits<3> imm;
9129     let Inst{18-16} = imm;
9130     let hasSideEffects = 0;
9131   }
9132
9133   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9134                                   V64, V128, vecshiftR32Narrow,
9135                                   asm, ".4h", ".4s",
9136       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
9137     bits<4> imm;
9138     let Inst{19-16} = imm;
9139   }
9140
9141   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9142                                   V128, V128, vecshiftR32Narrow,
9143                                   asm#"2", ".8h", ".4s", []> {
9144     bits<4> imm;
9145     let Inst{19-16} = imm;
9146     let hasSideEffects = 0;
9147   }
9148
9149   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9150                                   V64, V128, vecshiftR64Narrow,
9151                                   asm, ".2s", ".2d",
9152       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
9153     bits<5> imm;
9154     let Inst{20-16} = imm;
9155   }
9156
9157   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9158                                   V128, V128, vecshiftR64Narrow,
9159                                   asm#"2", ".4s", ".2d", []> {
9160     bits<5> imm;
9161     let Inst{20-16} = imm;
9162     let hasSideEffects = 0;
9163   }
9164
9165   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
9166   // themselves, so put them here instead.
9167
9168   // Patterns involving what's effectively an insert high and a normal
9169   // intrinsic, represented by CONCAT_VECTORS.
9170   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
9171                                                    vecshiftR16Narrow:$imm)),
9172             (!cast<Instruction>(NAME # "v16i8_shift")
9173                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9174                 V128:$Rn, vecshiftR16Narrow:$imm)>;
9175   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
9176                                                      vecshiftR32Narrow:$imm)),
9177             (!cast<Instruction>(NAME # "v8i16_shift")
9178                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9179                 V128:$Rn, vecshiftR32Narrow:$imm)>;
9180   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
9181                                                      vecshiftR64Narrow:$imm)),
9182             (!cast<Instruction>(NAME # "v4i32_shift")
9183                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9184                 V128:$Rn, vecshiftR64Narrow:$imm)>;
9185 }
9186
9187 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
9188                                 SDPatternOperator OpNode> {
9189   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9190                                   V64, V64, vecshiftL8,
9191                                   asm, ".8b", ".8b",
9192                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
9193                        (i32 vecshiftL8:$imm)))]> {
9194     bits<3> imm;
9195     let Inst{18-16} = imm;
9196   }
9197
9198   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9199                                   V128, V128, vecshiftL8,
9200                                   asm, ".16b", ".16b",
9201              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
9202                    (i32 vecshiftL8:$imm)))]> {
9203     bits<3> imm;
9204     let Inst{18-16} = imm;
9205   }
9206
9207   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9208                                   V64, V64, vecshiftL16,
9209                                   asm, ".4h", ".4h",
9210               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
9211                     (i32 vecshiftL16:$imm)))]> {
9212     bits<4> imm;
9213     let Inst{19-16} = imm;
9214   }
9215
9216   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9217                                   V128, V128, vecshiftL16,
9218                                   asm, ".8h", ".8h",
9219             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
9220                   (i32 vecshiftL16:$imm)))]> {
9221     bits<4> imm;
9222     let Inst{19-16} = imm;
9223   }
9224
9225   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9226                                   V64, V64, vecshiftL32,
9227                                   asm, ".2s", ".2s",
9228               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
9229                     (i32 vecshiftL32:$imm)))]> {
9230     bits<5> imm;
9231     let Inst{20-16} = imm;
9232   }
9233
9234   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9235                                   V128, V128, vecshiftL32,
9236                                   asm, ".4s", ".4s",
9237             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
9238                   (i32 vecshiftL32:$imm)))]> {
9239     bits<5> imm;
9240     let Inst{20-16} = imm;
9241   }
9242
9243   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9244                                   V128, V128, vecshiftL64,
9245                                   asm, ".2d", ".2d",
9246             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
9247                   (i32 vecshiftL64:$imm)))]> {
9248     bits<6> imm;
9249     let Inst{21-16} = imm;
9250   }
9251 }
9252
9253 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
9254                                 SDPatternOperator OpNode> {
9255   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9256                                   V64, V64, vecshiftR8,
9257                                   asm, ".8b", ".8b",
9258                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
9259                        (i32 vecshiftR8:$imm)))]> {
9260     bits<3> imm;
9261     let Inst{18-16} = imm;
9262   }
9263
9264   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9265                                   V128, V128, vecshiftR8,
9266                                   asm, ".16b", ".16b",
9267              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
9268                    (i32 vecshiftR8:$imm)))]> {
9269     bits<3> imm;
9270     let Inst{18-16} = imm;
9271   }
9272
9273   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9274                                   V64, V64, vecshiftR16,
9275                                   asm, ".4h", ".4h",
9276               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
9277                     (i32 vecshiftR16:$imm)))]> {
9278     bits<4> imm;
9279     let Inst{19-16} = imm;
9280   }
9281
9282   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9283                                   V128, V128, vecshiftR16,
9284                                   asm, ".8h", ".8h",
9285             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
9286                   (i32 vecshiftR16:$imm)))]> {
9287     bits<4> imm;
9288     let Inst{19-16} = imm;
9289   }
9290
9291   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9292                                   V64, V64, vecshiftR32,
9293                                   asm, ".2s", ".2s",
9294               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
9295                     (i32 vecshiftR32:$imm)))]> {
9296     bits<5> imm;
9297     let Inst{20-16} = imm;
9298   }
9299
9300   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9301                                   V128, V128, vecshiftR32,
9302                                   asm, ".4s", ".4s",
9303             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
9304                   (i32 vecshiftR32:$imm)))]> {
9305     bits<5> imm;
9306     let Inst{20-16} = imm;
9307   }
9308
9309   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9310                                   V128, V128, vecshiftR64,
9311                                   asm, ".2d", ".2d",
9312             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
9313                   (i32 vecshiftR64:$imm)))]> {
9314     bits<6> imm;
9315     let Inst{21-16} = imm;
9316   }
9317 }
9318
9319 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9320 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
9321                                     SDPatternOperator OpNode = null_frag> {
9322   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
9323                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
9324                  [(set (v8i8 V64:$dst),
9325                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
9326                            (i32 vecshiftR8:$imm)))]> {
9327     bits<3> imm;
9328     let Inst{18-16} = imm;
9329   }
9330
9331   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9332                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
9333              [(set (v16i8 V128:$dst),
9334                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
9335                        (i32 vecshiftR8:$imm)))]> {
9336     bits<3> imm;
9337     let Inst{18-16} = imm;
9338   }
9339
9340   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
9341                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
9342               [(set (v4i16 V64:$dst),
9343                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
9344                         (i32 vecshiftR16:$imm)))]> {
9345     bits<4> imm;
9346     let Inst{19-16} = imm;
9347   }
9348
9349   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9350                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
9351             [(set (v8i16 V128:$dst),
9352               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9353                       (i32 vecshiftR16:$imm)))]> {
9354     bits<4> imm;
9355     let Inst{19-16} = imm;
9356   }
9357
9358   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
9359                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
9360               [(set (v2i32 V64:$dst),
9361                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9362                         (i32 vecshiftR32:$imm)))]> {
9363     bits<5> imm;
9364     let Inst{20-16} = imm;
9365   }
9366
9367   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9368                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
9369             [(set (v4i32 V128:$dst),
9370               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9371                       (i32 vecshiftR32:$imm)))]> {
9372     bits<5> imm;
9373     let Inst{20-16} = imm;
9374   }
9375
9376   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
9377                                   V128, V128, vecshiftR64,
9378                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
9379               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
9380                       (i32 vecshiftR64:$imm)))]> {
9381     bits<6> imm;
9382     let Inst{21-16} = imm;
9383   }
9384 }
9385
9386 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
9387                                     SDPatternOperator OpNode = null_frag> {
9388   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
9389                                   V64, V64, vecshiftL8,
9390                                   asm, ".8b", ".8b",
9391                     [(set (v8i8 V64:$dst),
9392                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
9393                                   (i32 vecshiftL8:$imm)))]> {
9394     bits<3> imm;
9395     let Inst{18-16} = imm;
9396   }
9397
9398   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9399                                   V128, V128, vecshiftL8,
9400                                   asm, ".16b", ".16b",
9401                     [(set (v16i8 V128:$dst),
9402                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
9403                                   (i32 vecshiftL8:$imm)))]> {
9404     bits<3> imm;
9405     let Inst{18-16} = imm;
9406   }
9407
9408   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
9409                                   V64, V64, vecshiftL16,
9410                                   asm, ".4h", ".4h",
9411                     [(set (v4i16 V64:$dst),
9412                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
9413                                    (i32 vecshiftL16:$imm)))]> {
9414     bits<4> imm;
9415     let Inst{19-16} = imm;
9416   }
9417
9418   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9419                                   V128, V128, vecshiftL16,
9420                                   asm, ".8h", ".8h",
9421                     [(set (v8i16 V128:$dst),
9422                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9423                                   (i32 vecshiftL16:$imm)))]> {
9424     bits<4> imm;
9425     let Inst{19-16} = imm;
9426   }
9427
9428   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
9429                                   V64, V64, vecshiftL32,
9430                                   asm, ".2s", ".2s",
9431                     [(set (v2i32 V64:$dst),
9432                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9433                                   (i32 vecshiftL32:$imm)))]> {
9434     bits<5> imm;
9435     let Inst{20-16} = imm;
9436   }
9437
9438   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9439                                   V128, V128, vecshiftL32,
9440                                   asm, ".4s", ".4s",
9441                     [(set (v4i32 V128:$dst),
9442                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9443                                   (i32 vecshiftL32:$imm)))]> {
9444     bits<5> imm;
9445     let Inst{20-16} = imm;
9446   }
9447
9448   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
9449                                   V128, V128, vecshiftL64,
9450                                   asm, ".2d", ".2d",
9451                     [(set (v2i64 V128:$dst),
9452                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
9453                                   (i32 vecshiftL64:$imm)))]> {
9454     bits<6> imm;
9455     let Inst{21-16} = imm;
9456   }
9457 }
9458
9459 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
9460                                    SDPatternOperator OpNode> {
9461   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9462                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
9463       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
9464     bits<3> imm;
9465     let Inst{18-16} = imm;
9466   }
9467
9468   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9469                                   V128, V128, vecshiftL8,
9470                                   asm#"2", ".8h", ".16b",
9471       [(set (v8i16 V128:$Rd),
9472             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
9473     bits<3> imm;
9474     let Inst{18-16} = imm;
9475   }
9476
9477   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9478                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
9479       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
9480     bits<4> imm;
9481     let Inst{19-16} = imm;
9482   }
9483
9484   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9485                                   V128, V128, vecshiftL16,
9486                                   asm#"2", ".4s", ".8h",
9487       [(set (v4i32 V128:$Rd),
9488             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
9489
9490     bits<4> imm;
9491     let Inst{19-16} = imm;
9492   }
9493
9494   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9495                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
9496       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
9497     bits<5> imm;
9498     let Inst{20-16} = imm;
9499   }
9500
9501   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9502                                   V128, V128, vecshiftL32,
9503                                   asm#"2", ".2d", ".4s",
9504       [(set (v2i64 V128:$Rd),
9505             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
9506     bits<5> imm;
9507     let Inst{20-16} = imm;
9508   }
9509 }
9510
9511
9512 //---
9513 // Vector load/store
9514 //---
9515 // SIMD ldX/stX no-index memory references don't allow the optional
9516 // ", #0" constant and handle post-indexing explicitly, so we use
9517 // a more specialized parse method for them. Otherwise, it's the same as
9518 // the general GPR64sp handling.
9519
9520 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
9521                    string asm, dag oops, dag iops, list<dag> pattern>
9522   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
9523   bits<5> Vt;
9524   bits<5> Rn;
9525   let Inst{31} = 0;
9526   let Inst{30} = Q;
9527   let Inst{29-23} = 0b0011000;
9528   let Inst{22} = L;
9529   let Inst{21-16} = 0b000000;
9530   let Inst{15-12} = opcode;
9531   let Inst{11-10} = size;
9532   let Inst{9-5} = Rn;
9533   let Inst{4-0} = Vt;
9534 }
9535
9536 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
9537                        string asm, dag oops, dag iops>
9538   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
9539   bits<5> Vt;
9540   bits<5> Rn;
9541   bits<5> Xm;
9542   let Inst{31} = 0;
9543   let Inst{30} = Q;
9544   let Inst{29-23} = 0b0011001;
9545   let Inst{22} = L;
9546   let Inst{21} = 0;
9547   let Inst{20-16} = Xm;
9548   let Inst{15-12} = opcode;
9549   let Inst{11-10} = size;
9550   let Inst{9-5} = Rn;
9551   let Inst{4-0} = Vt;
9552 }
9553
9554 // The immediate form of AdvSIMD post-indexed addressing is encoded with
9555 // register post-index addressing from the zero register.
9556 multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
9557                            int Offset, int Size> {
9558   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
9559   //      "ld1\t$Vt, [$Rn], #16"
9560   // may get mapped to
9561   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
9562   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9563                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9564                       GPR64sp:$Rn,
9565                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9566                       XZR), 1>;
9567
9568   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
9569   //      "ld1.8b\t$Vt, [$Rn], #16"
9570   // may get mapped to
9571   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
9572   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9573                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9574                       GPR64sp:$Rn,
9575                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9576                       XZR), 0>;
9577
9578   // E.g. "ld1.8b { v0, v1 }, [x1]"
9579   //      "ld1\t$Vt, [$Rn]"
9580   // may get mapped to
9581   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
9582   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9583                   (!cast<Instruction>(BaseName # Count # "v" # layout)
9584                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9585                       GPR64sp:$Rn), 0>;
9586
9587   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
9588   //      "ld1\t$Vt, [$Rn], $Xm"
9589   // may get mapped to
9590   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
9591   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9592                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9593                       GPR64sp:$Rn,
9594                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9595                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9596 }
9597
9598 multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
9599                        int Offset128, int Offset64, bits<4> opcode> {
9600   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9601     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
9602                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
9603                            (ins GPR64sp:$Rn), []>;
9604     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
9605                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
9606                            (ins GPR64sp:$Rn), []>;
9607     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
9608                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
9609                            (ins GPR64sp:$Rn), []>;
9610     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
9611                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
9612                            (ins GPR64sp:$Rn), []>;
9613     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
9614                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
9615                            (ins GPR64sp:$Rn), []>;
9616     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
9617                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
9618                            (ins GPR64sp:$Rn), []>;
9619     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
9620                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
9621                            (ins GPR64sp:$Rn), []>;
9622
9623
9624     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
9625                        (outs GPR64sp:$wback,
9626                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
9627                        (ins GPR64sp:$Rn,
9628                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9629     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
9630                        (outs GPR64sp:$wback,
9631                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
9632                        (ins GPR64sp:$Rn,
9633                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9634     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
9635                        (outs GPR64sp:$wback,
9636                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
9637                        (ins GPR64sp:$Rn,
9638                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9639     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
9640                        (outs GPR64sp:$wback,
9641                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
9642                        (ins GPR64sp:$Rn,
9643                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9644     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
9645                        (outs GPR64sp:$wback,
9646                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
9647                        (ins GPR64sp:$Rn,
9648                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9649     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
9650                        (outs GPR64sp:$wback,
9651                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
9652                        (ins GPR64sp:$Rn,
9653                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9654     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
9655                        (outs GPR64sp:$wback,
9656                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
9657                        (ins GPR64sp:$Rn,
9658                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9659   }
9660
9661   defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9662   defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9663   defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9664   defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9665   defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9666   defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9667   defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9668 }
9669
9670 // Only ld1/st1 has a v1d version.
9671 multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
9672                        int Offset128, int Offset64, bits<4> opcode> {
9673   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
9674     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
9675                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9676                                  GPR64sp:$Rn), []>;
9677     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
9678                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9679                                 GPR64sp:$Rn), []>;
9680     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
9681                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9682                                 GPR64sp:$Rn), []>;
9683     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
9684                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9685                                 GPR64sp:$Rn), []>;
9686     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
9687                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9688                                 GPR64sp:$Rn), []>;
9689     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
9690                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9691                                 GPR64sp:$Rn), []>;
9692     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
9693                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9694                                 GPR64sp:$Rn), []>;
9695
9696     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
9697                        (outs GPR64sp:$wback),
9698                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9699                             GPR64sp:$Rn,
9700                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9701     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
9702                        (outs GPR64sp:$wback),
9703                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9704                             GPR64sp:$Rn,
9705                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9706     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
9707                        (outs GPR64sp:$wback),
9708                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9709                             GPR64sp:$Rn,
9710                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9711     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
9712                        (outs GPR64sp:$wback),
9713                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9714                             GPR64sp:$Rn,
9715                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9716     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
9717                        (outs GPR64sp:$wback),
9718                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9719                             GPR64sp:$Rn,
9720                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9721     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
9722                        (outs GPR64sp:$wback),
9723                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9724                             GPR64sp:$Rn,
9725                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9726     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
9727                        (outs GPR64sp:$wback),
9728                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9729                             GPR64sp:$Rn,
9730                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9731   }
9732
9733   defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9734   defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9735   defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9736   defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9737   defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9738   defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9739   defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9740 }
9741
9742 multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
9743                        int Offset128, int Offset64, bits<4> opcode>
9744   : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9745
9746   // LD1 instructions have extra "1d" variants.
9747   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9748     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
9749                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
9750                            (ins GPR64sp:$Rn), []>;
9751
9752     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
9753                        (outs GPR64sp:$wback,
9754                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
9755                        (ins GPR64sp:$Rn,
9756                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9757   }
9758
9759   defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9760 }
9761
9762 multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
9763                        int Offset128, int Offset64, bits<4> opcode>
9764   : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9765
9766   // ST1 instructions have extra "1d" variants.
9767   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
9768     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
9769                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9770                                 GPR64sp:$Rn), []>;
9771
9772     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
9773                        (outs GPR64sp:$wback),
9774                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9775                             GPR64sp:$Rn,
9776                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9777   }
9778
9779   defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9780 }
9781
9782 multiclass SIMDLd1Multiple<string asm> {
9783   defm One   : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8,  0b0111>;
9784   defm Two   : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9785   defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9786   defm Four  : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9787 }
9788
9789 multiclass SIMDSt1Multiple<string asm> {
9790   defm One   : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8,  0b0111>;
9791   defm Two   : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9792   defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9793   defm Four  : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9794 }
9795
9796 multiclass SIMDLd2Multiple<string asm> {
9797   defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9798 }
9799
9800 multiclass SIMDSt2Multiple<string asm> {
9801   defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9802 }
9803
9804 multiclass SIMDLd3Multiple<string asm> {
9805   defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9806 }
9807
9808 multiclass SIMDSt3Multiple<string asm> {
9809   defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9810 }
9811
9812 multiclass SIMDLd4Multiple<string asm> {
9813   defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9814 }
9815
9816 multiclass SIMDSt4Multiple<string asm> {
9817   defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9818 }
9819
9820 //---
9821 // AdvSIMD Load/store single-element
9822 //---
9823
9824 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
9825                          string asm, string operands, string cst,
9826                          dag oops, dag iops, list<dag> pattern>
9827   : I<oops, iops, asm, operands, cst, pattern> {
9828   bits<5> Vt;
9829   bits<5> Rn;
9830   let Inst{31} = 0;
9831   let Inst{29-24} = 0b001101;
9832   let Inst{22} = L;
9833   let Inst{21} = R;
9834   let Inst{15-13} = opcode;
9835   let Inst{9-5} = Rn;
9836   let Inst{4-0} = Vt;
9837 }
9838
9839 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
9840                          string asm, string operands, string cst,
9841                          dag oops, dag iops, list<dag> pattern>
9842   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
9843   bits<5> Vt;
9844   bits<5> Rn;
9845   let Inst{31} = 0;
9846   let Inst{29-24} = 0b001101;
9847   let Inst{22} = L;
9848   let Inst{21} = R;
9849   let Inst{15-13} = opcode;
9850   let Inst{9-5} = Rn;
9851   let Inst{4-0} = Vt;
9852 }
9853
9854
9855 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9856 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
9857                   DAGOperand listtype>
9858   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
9859                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
9860                        []> {
9861   let Inst{30} = Q;
9862   let Inst{23} = 0;
9863   let Inst{20-16} = 0b00000;
9864   let Inst{12} = S;
9865   let Inst{11-10} = size;
9866 }
9867 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9868 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
9869                       string asm, DAGOperand listtype, DAGOperand GPR64pi>
9870   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
9871                        "$Rn = $wback",
9872                        (outs GPR64sp:$wback, listtype:$Vt),
9873                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
9874   bits<5> Xm;
9875   let Inst{30} = Q;
9876   let Inst{23} = 1;
9877   let Inst{20-16} = Xm;
9878   let Inst{12} = S;
9879   let Inst{11-10} = size;
9880 }
9881
9882 multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
9883                           int Offset, int Size> {
9884   // E.g. "ld1r { v0.8b }, [x1], #1"
9885   //      "ld1r.8b\t$Vt, [$Rn], #1"
9886   // may get mapped to
9887   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9888   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9889                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9890                       GPR64sp:$Rn,
9891                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9892                       XZR), 1>;
9893
9894   // E.g. "ld1r.8b { v0 }, [x1], #1"
9895   //      "ld1r.8b\t$Vt, [$Rn], #1"
9896   // may get mapped to
9897   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9898   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9899                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9900                       GPR64sp:$Rn,
9901                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9902                       XZR), 0>;
9903
9904   // E.g. "ld1r.8b { v0 }, [x1]"
9905   //      "ld1r.8b\t$Vt, [$Rn]"
9906   // may get mapped to
9907   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9908   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9909                   (!cast<Instruction>(BaseName # "v" # layout)
9910                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9911                       GPR64sp:$Rn), 0>;
9912
9913   // E.g. "ld1r.8b { v0 }, [x1], x2"
9914   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
9915   // may get mapped to
9916   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9917   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9918                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9919                       GPR64sp:$Rn,
9920                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9921                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9922 }
9923
9924 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
9925   int Offset1, int Offset2, int Offset4, int Offset8> {
9926   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
9927                         !cast<DAGOperand>("VecList" # Count # "8b")>;
9928   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
9929                         !cast<DAGOperand>("VecList" # Count #"16b")>;
9930   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
9931                         !cast<DAGOperand>("VecList" # Count #"4h")>;
9932   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
9933                         !cast<DAGOperand>("VecList" # Count #"8h")>;
9934   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
9935                         !cast<DAGOperand>("VecList" # Count #"2s")>;
9936   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
9937                         !cast<DAGOperand>("VecList" # Count #"4s")>;
9938   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
9939                         !cast<DAGOperand>("VecList" # Count #"1d")>;
9940   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
9941                         !cast<DAGOperand>("VecList" # Count #"2d")>;
9942
9943   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
9944                                  !cast<DAGOperand>("VecList" # Count # "8b"),
9945                                  !cast<DAGOperand>("GPR64pi" # Offset1)>;
9946   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
9947                                  !cast<DAGOperand>("VecList" # Count # "16b"),
9948                                  !cast<DAGOperand>("GPR64pi" # Offset1)>;
9949   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
9950                                  !cast<DAGOperand>("VecList" # Count # "4h"),
9951                                  !cast<DAGOperand>("GPR64pi" # Offset2)>;
9952   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
9953                                  !cast<DAGOperand>("VecList" # Count # "8h"),
9954                                  !cast<DAGOperand>("GPR64pi" # Offset2)>;
9955   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
9956                                  !cast<DAGOperand>("VecList" # Count # "2s"),
9957                                  !cast<DAGOperand>("GPR64pi" # Offset4)>;
9958   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
9959                                  !cast<DAGOperand>("VecList" # Count # "4s"),
9960                                  !cast<DAGOperand>("GPR64pi" # Offset4)>;
9961   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
9962                                  !cast<DAGOperand>("VecList" # Count # "1d"),
9963                                  !cast<DAGOperand>("GPR64pi" # Offset8)>;
9964   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
9965                                  !cast<DAGOperand>("VecList" # Count # "2d"),
9966                                  !cast<DAGOperand>("GPR64pi" # Offset8)>;
9967
9968   defm : SIMDLdrAliases<NAME, asm, "8b",  Count, Offset1,  64>;
9969   defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
9970   defm : SIMDLdrAliases<NAME, asm, "4h",  Count, Offset2,  64>;
9971   defm : SIMDLdrAliases<NAME, asm, "8h",  Count, Offset2, 128>;
9972   defm : SIMDLdrAliases<NAME, asm, "2s",  Count, Offset4,  64>;
9973   defm : SIMDLdrAliases<NAME, asm, "4s",  Count, Offset4, 128>;
9974   defm : SIMDLdrAliases<NAME, asm, "1d",  Count, Offset8,  64>;
9975   defm : SIMDLdrAliases<NAME, asm, "2d",  Count, Offset8, 128>;
9976 }
9977
9978 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
9979                       dag oops, dag iops, list<dag> pattern>
9980   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9981                        pattern> {
9982   // idx encoded in Q:S:size fields.
9983   bits<4> idx;
9984   let Inst{30} = idx{3};
9985   let Inst{23} = 0;
9986   let Inst{20-16} = 0b00000;
9987   let Inst{12} = idx{2};
9988   let Inst{11-10} = idx{1-0};
9989 }
9990 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
9991                       dag oops, dag iops, list<dag> pattern>
9992   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9993                            oops, iops, pattern> {
9994   // idx encoded in Q:S:size fields.
9995   bits<4> idx;
9996   let Inst{30} = idx{3};
9997   let Inst{23} = 0;
9998   let Inst{20-16} = 0b00000;
9999   let Inst{12} = idx{2};
10000   let Inst{11-10} = idx{1-0};
10001 }
10002 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
10003                           dag oops, dag iops>
10004   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10005                        "$Rn = $wback", oops, iops, []> {
10006   // idx encoded in Q:S:size fields.
10007   bits<4> idx;
10008   bits<5> Xm;
10009   let Inst{30} = idx{3};
10010   let Inst{23} = 1;
10011   let Inst{20-16} = Xm;
10012   let Inst{12} = idx{2};
10013   let Inst{11-10} = idx{1-0};
10014 }
10015 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
10016                           dag oops, dag iops>
10017   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10018                            "$Rn = $wback", oops, iops, []> {
10019   // idx encoded in Q:S:size fields.
10020   bits<4> idx;
10021   bits<5> Xm;
10022   let Inst{30} = idx{3};
10023   let Inst{23} = 1;
10024   let Inst{20-16} = Xm;
10025   let Inst{12} = idx{2};
10026   let Inst{11-10} = idx{1-0};
10027 }
10028
10029 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
10030                       dag oops, dag iops, list<dag> pattern>
10031   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10032                        pattern> {
10033   // idx encoded in Q:S:size<1> fields.
10034   bits<3> idx;
10035   let Inst{30} = idx{2};
10036   let Inst{23} = 0;
10037   let Inst{20-16} = 0b00000;
10038   let Inst{12} = idx{1};
10039   let Inst{11} = idx{0};
10040   let Inst{10} = size;
10041 }
10042 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
10043                       dag oops, dag iops, list<dag> pattern>
10044   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10045                            oops, iops, pattern> {
10046   // idx encoded in Q:S:size<1> fields.
10047   bits<3> idx;
10048   let Inst{30} = idx{2};
10049   let Inst{23} = 0;
10050   let Inst{20-16} = 0b00000;
10051   let Inst{12} = idx{1};
10052   let Inst{11} = idx{0};
10053   let Inst{10} = size;
10054 }
10055
10056 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10057                           dag oops, dag iops>
10058   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10059                        "$Rn = $wback", oops, iops, []> {
10060   // idx encoded in Q:S:size<1> fields.
10061   bits<3> idx;
10062   bits<5> Xm;
10063   let Inst{30} = idx{2};
10064   let Inst{23} = 1;
10065   let Inst{20-16} = Xm;
10066   let Inst{12} = idx{1};
10067   let Inst{11} = idx{0};
10068   let Inst{10} = size;
10069 }
10070 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10071                           dag oops, dag iops>
10072   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10073                            "$Rn = $wback", oops, iops, []> {
10074   // idx encoded in Q:S:size<1> fields.
10075   bits<3> idx;
10076   bits<5> Xm;
10077   let Inst{30} = idx{2};
10078   let Inst{23} = 1;
10079   let Inst{20-16} = Xm;
10080   let Inst{12} = idx{1};
10081   let Inst{11} = idx{0};
10082   let Inst{10} = size;
10083 }
10084 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10085                       dag oops, dag iops, list<dag> pattern>
10086   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10087                        pattern> {
10088   // idx encoded in Q:S fields.
10089   bits<2> idx;
10090   let Inst{30} = idx{1};
10091   let Inst{23} = 0;
10092   let Inst{20-16} = 0b00000;
10093   let Inst{12} = idx{0};
10094   let Inst{11-10} = size;
10095 }
10096 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10097                       dag oops, dag iops, list<dag> pattern>
10098   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10099                            oops, iops, pattern> {
10100   // idx encoded in Q:S fields.
10101   bits<2> idx;
10102   let Inst{30} = idx{1};
10103   let Inst{23} = 0;
10104   let Inst{20-16} = 0b00000;
10105   let Inst{12} = idx{0};
10106   let Inst{11-10} = size;
10107 }
10108 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
10109                           string asm, dag oops, dag iops>
10110   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10111                        "$Rn = $wback", oops, iops, []> {
10112   // idx encoded in Q:S fields.
10113   bits<2> idx;
10114   bits<5> Xm;
10115   let Inst{30} = idx{1};
10116   let Inst{23} = 1;
10117   let Inst{20-16} = Xm;
10118   let Inst{12} = idx{0};
10119   let Inst{11-10} = size;
10120 }
10121 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
10122                           string asm, dag oops, dag iops>
10123   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10124                            "$Rn = $wback", oops, iops, []> {
10125   // idx encoded in Q:S fields.
10126   bits<2> idx;
10127   bits<5> Xm;
10128   let Inst{30} = idx{1};
10129   let Inst{23} = 1;
10130   let Inst{20-16} = Xm;
10131   let Inst{12} = idx{0};
10132   let Inst{11-10} = size;
10133 }
10134 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10135                       dag oops, dag iops, list<dag> pattern>
10136   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10137                        pattern> {
10138   // idx encoded in Q field.
10139   bits<1> idx;
10140   let Inst{30} = idx;
10141   let Inst{23} = 0;
10142   let Inst{20-16} = 0b00000;
10143   let Inst{12} = 0;
10144   let Inst{11-10} = size;
10145 }
10146 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10147                       dag oops, dag iops, list<dag> pattern>
10148   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10149                            oops, iops, pattern> {
10150   // idx encoded in Q field.
10151   bits<1> idx;
10152   let Inst{30} = idx;
10153   let Inst{23} = 0;
10154   let Inst{20-16} = 0b00000;
10155   let Inst{12} = 0;
10156   let Inst{11-10} = size;
10157 }
10158 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
10159                           string asm, dag oops, dag iops>
10160   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10161                        "$Rn = $wback", oops, iops, []> {
10162   // idx encoded in Q field.
10163   bits<1> idx;
10164   bits<5> Xm;
10165   let Inst{30} = idx;
10166   let Inst{23} = 1;
10167   let Inst{20-16} = Xm;
10168   let Inst{12} = 0;
10169   let Inst{11-10} = size;
10170 }
10171 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
10172                           string asm, dag oops, dag iops>
10173   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10174                            "$Rn = $wback", oops, iops, []> {
10175   // idx encoded in Q field.
10176   bits<1> idx;
10177   bits<5> Xm;
10178   let Inst{30} = idx;
10179   let Inst{23} = 1;
10180   let Inst{20-16} = Xm;
10181   let Inst{12} = 0;
10182   let Inst{11-10} = size;
10183 }
10184
10185 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10186 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
10187                          RegisterOperand listtype,
10188                          RegisterOperand GPR64pi> {
10189   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
10190                            (outs listtype:$dst),
10191                            (ins listtype:$Vt, VectorIndexB:$idx,
10192                                 GPR64sp:$Rn), []>;
10193
10194   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
10195                             (outs GPR64sp:$wback, listtype:$dst),
10196                             (ins listtype:$Vt, VectorIndexB:$idx,
10197                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
10198 }
10199 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10200 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
10201                          RegisterOperand listtype,
10202                          RegisterOperand GPR64pi> {
10203   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
10204                             (outs listtype:$dst),
10205                             (ins listtype:$Vt, VectorIndexH:$idx,
10206                                  GPR64sp:$Rn), []>;
10207
10208   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
10209                             (outs GPR64sp:$wback, listtype:$dst),
10210                             (ins listtype:$Vt, VectorIndexH:$idx,
10211                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
10212 }
10213 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10214 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
10215                          RegisterOperand listtype,
10216                          RegisterOperand GPR64pi> {
10217   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
10218                             (outs listtype:$dst),
10219                             (ins listtype:$Vt, VectorIndexS:$idx,
10220                                  GPR64sp:$Rn), []>;
10221
10222   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
10223                             (outs GPR64sp:$wback, listtype:$dst),
10224                             (ins listtype:$Vt, VectorIndexS:$idx,
10225                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
10226 }
10227 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10228 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
10229                          RegisterOperand listtype, RegisterOperand GPR64pi> {
10230   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
10231                             (outs listtype:$dst),
10232                             (ins listtype:$Vt, VectorIndexD:$idx,
10233                                  GPR64sp:$Rn), []>;
10234
10235   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
10236                             (outs GPR64sp:$wback, listtype:$dst),
10237                             (ins listtype:$Vt, VectorIndexD:$idx,
10238                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
10239 }
10240 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10241 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
10242                          RegisterOperand listtype, RegisterOperand GPR64pi> {
10243   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
10244                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
10245                                         GPR64sp:$Rn), []>;
10246
10247   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
10248                                     (outs GPR64sp:$wback),
10249                                     (ins listtype:$Vt, VectorIndexB:$idx,
10250                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
10251 }
10252 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10253 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
10254                          RegisterOperand listtype, RegisterOperand GPR64pi> {
10255   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
10256                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
10257                                          GPR64sp:$Rn), []>;
10258
10259   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
10260                             (outs GPR64sp:$wback),
10261                             (ins listtype:$Vt, VectorIndexH:$idx,
10262                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
10263 }
10264 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10265 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
10266                          RegisterOperand listtype, RegisterOperand GPR64pi> {
10267   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
10268                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
10269                                          GPR64sp:$Rn), []>;
10270
10271   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
10272                             (outs GPR64sp:$wback),
10273                             (ins listtype:$Vt, VectorIndexS:$idx,
10274                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
10275 }
10276 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10277 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
10278                          RegisterOperand listtype, RegisterOperand GPR64pi> {
10279   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
10280                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
10281                                          GPR64sp:$Rn), []>;
10282
10283   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
10284                             (outs GPR64sp:$wback),
10285                             (ins listtype:$Vt, VectorIndexD:$idx,
10286                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
10287 }
10288
10289 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
10290                                  string Count, int Offset, Operand idxtype> {
10291   // E.g. "ld1 { v0.8b }[0], [x1], #1"
10292   //      "ld1\t$Vt, [$Rn], #1"
10293   // may get mapped to
10294   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
10295   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
10296                   (!cast<Instruction>(NAME # Type  # "_POST")
10297                       GPR64sp:$Rn,
10298                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
10299                       idxtype:$idx, XZR), 1>;
10300
10301   // E.g. "ld1.8b { v0 }[0], [x1], #1"
10302   //      "ld1.8b\t$Vt, [$Rn], #1"
10303   // may get mapped to
10304   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
10305   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
10306                   (!cast<Instruction>(NAME # Type # "_POST")
10307                       GPR64sp:$Rn,
10308                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10309                       idxtype:$idx, XZR), 0>;
10310
10311   // E.g. "ld1.8b { v0 }[0], [x1]"
10312   //      "ld1.8b\t$Vt, [$Rn]"
10313   // may get mapped to
10314   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
10315   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
10316                       (!cast<Instruction>(NAME # Type)
10317                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10318                          idxtype:$idx, GPR64sp:$Rn), 0>;
10319
10320   // E.g. "ld1.8b { v0 }[0], [x1], x2"
10321   //      "ld1.8b\t$Vt, [$Rn], $Xm"
10322   // may get mapped to
10323   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
10324   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
10325                       (!cast<Instruction>(NAME # Type # "_POST")
10326                          GPR64sp:$Rn,
10327                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10328                          idxtype:$idx,
10329                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
10330 }
10331
10332 multiclass SIMDLdSt1SingleAliases<string asm> {
10333   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
10334   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
10335   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
10336   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
10337 }
10338
10339 multiclass SIMDLdSt2SingleAliases<string asm> {
10340   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
10341   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
10342   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
10343   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
10344 }
10345
10346 multiclass SIMDLdSt3SingleAliases<string asm> {
10347   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
10348   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
10349   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
10350   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
10351 }
10352
10353 multiclass SIMDLdSt4SingleAliases<string asm> {
10354   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
10355   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
10356   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
10357   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
10358 }
10359 } // end of 'let Predicates = [HasNEON]'
10360
10361 //----------------------------------------------------------------------------
10362 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
10363 //----------------------------------------------------------------------------
10364
10365 let Predicates = [HasNEON, HasRDM] in {
10366
10367 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
10368                                     RegisterOperand regtype, string asm,
10369                                     string kind, list<dag> pattern>
10370   : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
10371                                 pattern> {
10372 }
10373 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
10374                                              SDPatternOperator Accum> {
10375   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
10376     [(set (v4i16 V64:$dst),
10377           (Accum (v4i16 V64:$Rd),
10378                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
10379                                                    (v4i16 V64:$Rm)))))]>;
10380   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
10381     [(set (v8i16 V128:$dst),
10382           (Accum (v8i16 V128:$Rd),
10383                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
10384                                                    (v8i16 V128:$Rm)))))]>;
10385   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
10386     [(set (v2i32 V64:$dst),
10387           (Accum (v2i32 V64:$Rd),
10388                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
10389                                                    (v2i32 V64:$Rm)))))]>;
10390   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
10391     [(set (v4i32 V128:$dst),
10392           (Accum (v4i32 V128:$Rd),
10393                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
10394                                                    (v4i32 V128:$Rm)))))]>;
10395 }
10396
10397 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
10398                                      SDPatternOperator Accum> {
10399   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
10400                                           V64, V64, V128_lo, VectorIndexH,
10401                                           asm, ".4h", ".4h", ".4h", ".h",
10402     [(set (v4i16 V64:$dst),
10403           (Accum (v4i16 V64:$Rd),
10404                  (v4i16 (int_aarch64_neon_sqrdmulh
10405                           (v4i16 V64:$Rn),
10406                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10407                                                     VectorIndexH:$idx))))))]> {
10408     bits<3> idx;
10409     let Inst{11} = idx{2};
10410     let Inst{21} = idx{1};
10411     let Inst{20} = idx{0};
10412   }
10413
10414   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
10415                                           V128, V128, V128_lo, VectorIndexH,
10416                                           asm, ".8h", ".8h", ".8h", ".h",
10417     [(set (v8i16 V128:$dst),
10418           (Accum (v8i16 V128:$Rd),
10419                  (v8i16 (int_aarch64_neon_sqrdmulh
10420                           (v8i16 V128:$Rn),
10421                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10422                                                    VectorIndexH:$idx))))))]> {
10423     bits<3> idx;
10424     let Inst{11} = idx{2};
10425     let Inst{21} = idx{1};
10426     let Inst{20} = idx{0};
10427   }
10428
10429   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
10430                                           V64, V64, V128, VectorIndexS,
10431                                           asm, ".2s", ".2s", ".2s", ".s",
10432     [(set (v2i32 V64:$dst),
10433         (Accum (v2i32 V64:$Rd),
10434                (v2i32 (int_aarch64_neon_sqrdmulh
10435                         (v2i32 V64:$Rn),
10436                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
10437                                                  VectorIndexS:$idx))))))]> {
10438     bits<2> idx;
10439     let Inst{11} = idx{1};
10440     let Inst{21} = idx{0};
10441   }
10442
10443   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10444   // an intermediate EXTRACT_SUBREG would be untyped.
10445   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
10446   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
10447   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10448                        (i32 (vector_extract
10449                                (v4i32 (insert_subvector
10450                                        (undef),
10451                                         (v2i32 (int_aarch64_neon_sqrdmulh
10452                                                  (v2i32 V64:$Rn),
10453                                                  (v2i32 (AArch64duplane32
10454                                                           (v4i32 V128:$Rm),
10455                                                           VectorIndexS:$idx)))),
10456                                       (i32 0))),
10457                                (i64 0))))),
10458             (EXTRACT_SUBREG
10459                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
10460                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
10461                                                 FPR32Op:$Rd,
10462                                                 ssub)),
10463                           V64:$Rn,
10464                           V128:$Rm,
10465                           VectorIndexS:$idx)),
10466                 ssub)>;
10467
10468   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
10469                                           V128, V128, V128, VectorIndexS,
10470                                           asm, ".4s", ".4s", ".4s", ".s",
10471     [(set (v4i32 V128:$dst),
10472           (Accum (v4i32 V128:$Rd),
10473                  (v4i32 (int_aarch64_neon_sqrdmulh
10474                           (v4i32 V128:$Rn),
10475                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
10476                                                    VectorIndexS:$idx))))))]> {
10477     bits<2> idx;
10478     let Inst{11} = idx{1};
10479     let Inst{21} = idx{0};
10480   }
10481
10482   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10483   // an intermediate EXTRACT_SUBREG would be untyped.
10484   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10485                         (i32 (vector_extract
10486                                (v4i32 (int_aarch64_neon_sqrdmulh
10487                                         (v4i32 V128:$Rn),
10488                                         (v4i32 (AArch64duplane32
10489                                                  (v4i32 V128:$Rm),
10490                                                  VectorIndexS:$idx)))),
10491                                (i64 0))))),
10492             (EXTRACT_SUBREG
10493                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
10494                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
10495                                                FPR32Op:$Rd,
10496                                                ssub)),
10497                          V128:$Rn,
10498                          V128:$Rm,
10499                          VectorIndexS:$idx)),
10500                 ssub)>;
10501
10502   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
10503                                         FPR16Op, FPR16Op, V128_lo,
10504                                         VectorIndexH, asm, ".h", "", "", ".h",
10505                                         []> {
10506     bits<3> idx;
10507     let Inst{11} = idx{2};
10508     let Inst{21} = idx{1};
10509     let Inst{20} = idx{0};
10510   }
10511
10512   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
10513                                         FPR32Op, FPR32Op, V128, VectorIndexS,
10514                                         asm, ".s", "", "", ".s",
10515     [(set (i32 FPR32Op:$dst),
10516           (Accum (i32 FPR32Op:$Rd),
10517                  (i32 (int_aarch64_neon_sqrdmulh
10518                         (i32 FPR32Op:$Rn),
10519                         (i32 (vector_extract (v4i32 V128:$Rm),
10520                                              VectorIndexS:$idx))))))]> {
10521     bits<2> idx;
10522     let Inst{11} = idx{1};
10523     let Inst{21} = idx{0};
10524   }
10525 }
10526 } // let Predicates = [HasNeon, HasRDM]
10527
10528 //----------------------------------------------------------------------------
10529 // ARMv8.3 Complex ADD/MLA instructions
10530 //----------------------------------------------------------------------------
10531
10532 class ComplexRotationOperand<int Angle, int Remainder, string Type>
10533   : AsmOperandClass {
10534   let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
10535   let DiagnosticType = "InvalidComplexRotation" # Type;
10536   let Name = "ComplexRotation" # Type;
10537 }
10538 def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270;  }],
10539                                                   SDNodeXForm<imm, [{
10540   return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32);
10541 }]>> {
10542   let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
10543   let PrintMethod = "printComplexRotationOp<90, 0>";
10544 }
10545 def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270;  }],
10546                                                   SDNodeXForm<imm, [{
10547   return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32);
10548 }]>> {
10549   let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
10550   let PrintMethod = "printComplexRotationOp<180, 90>";
10551 }
10552 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10553 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
10554                                      RegisterOperand regtype, Operand rottype,
10555                                      string asm, string kind, list<dag> pattern>
10556   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10557       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10558       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
10559     Sched<[WriteV]> {
10560   bits<5> Rd;
10561   bits<5> Rn;
10562   bits<5> Rm;
10563   bits<1> rot;
10564   let Inst{31}    = 0;
10565   let Inst{30}    = Q;
10566   let Inst{29}    = U;
10567   let Inst{28-24} = 0b01110;
10568   let Inst{23-22} = size;
10569   let Inst{21}    = 0;
10570   let Inst{20-16} = Rm;
10571   let Inst{15-13} = opcode;
10572   // Non-tied version (FCADD) only has one rotation bit
10573   let Inst{12}    = rot;
10574   let Inst{11}    = 0;
10575   let Inst{10}    = 1;
10576   let Inst{9-5}   = Rn;
10577   let Inst{4-0}   = Rd;
10578 }
10579
10580 //8.3 CompNum - Floating-point complex number support
10581 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
10582                                           string asm, SDPatternOperator OpNode>{
10583   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10584   def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
10585               asm, ".4h",
10586               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10587                                               (v4f16 V64:$Rn),
10588                                               (v4f16 V64:$Rm),
10589                                               (rottype i32:$rot)))]>;
10590
10591   def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
10592               asm, ".8h",
10593               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10594                                                (v8f16 V128:$Rn),
10595                                                (v8f16 V128:$Rm),
10596                                                (rottype i32:$rot)))]>;
10597   }
10598
10599   let Predicates = [HasComplxNum, HasNEON] in {
10600   def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
10601               asm, ".2s",
10602               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10603                                               (v2f32 V64:$Rn),
10604                                               (v2f32 V64:$Rm),
10605                                               (rottype i32:$rot)))]>;
10606
10607   def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
10608               asm, ".4s",
10609               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10610                                                (v4f32 V128:$Rn),
10611                                                (v4f32 V128:$Rm),
10612                                                (rottype i32:$rot)))]>;
10613
10614   def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
10615               asm, ".2d",
10616               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10617                                                (v2f64 V128:$Rn),
10618                                                (v2f64 V128:$Rm),
10619                                                (rottype i32:$rot)))]>;
10620   }
10621 }
10622
10623 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10624 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
10625                                          bits<3> opcode,
10626                                          RegisterOperand regtype,
10627                                          Operand rottype, string asm,
10628                                          string kind, list<dag> pattern>
10629   : I<(outs regtype:$dst),
10630       (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10631       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10632       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
10633     Sched<[WriteV]> {
10634   bits<5> Rd;
10635   bits<5> Rn;
10636   bits<5> Rm;
10637   bits<2> rot;
10638   let Inst{31}    = 0;
10639   let Inst{30}    = Q;
10640   let Inst{29}    = U;
10641   let Inst{28-24} = 0b01110;
10642   let Inst{23-22} = size;
10643   let Inst{21}    = 0;
10644   let Inst{20-16} = Rm;
10645   let Inst{15-13} = opcode;
10646   let Inst{12-11} = rot;
10647   let Inst{10}    = 1;
10648   let Inst{9-5}   = Rn;
10649   let Inst{4-0}   = Rd;
10650 }
10651
10652 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
10653                                              Operand rottype, string asm,
10654                                              SDPatternOperator OpNode> {
10655   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10656   def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
10657               rottype, asm, ".4h",
10658               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10659                                               (v4f16 V64:$Rn),
10660                                               (v4f16 V64:$Rm),
10661                                               (rottype i32:$rot)))]>;
10662
10663   def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
10664               rottype, asm, ".8h",
10665               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10666                                                (v8f16 V128:$Rn),
10667                                                (v8f16 V128:$Rm),
10668                                                (rottype i32:$rot)))]>;
10669   }
10670
10671   let Predicates = [HasComplxNum, HasNEON] in {
10672   def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
10673               rottype, asm, ".2s",
10674               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10675                                               (v2f32 V64:$Rn),
10676                                               (v2f32 V64:$Rm),
10677                                               (rottype i32:$rot)))]>;
10678
10679   def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
10680               rottype, asm, ".4s",
10681               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10682                                                (v4f32 V128:$Rn),
10683                                                (v4f32 V128:$Rm),
10684                                                (rottype i32:$rot)))]>;
10685
10686   def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
10687               rottype, asm, ".2d",
10688               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10689                                                (v2f64 V128:$Rn),
10690                                                (v2f64 V128:$Rm),
10691                                                (rottype i32:$rot)))]>;
10692   }
10693 }
10694
10695 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10696 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
10697                                  bit opc1, bit opc2, RegisterOperand dst_reg,
10698                                  RegisterOperand lhs_reg,
10699                                  RegisterOperand rhs_reg, Operand vec_idx,
10700                                  Operand rottype, string asm, string apple_kind,
10701                                  string dst_kind, string lhs_kind,
10702                                  string rhs_kind, list<dag> pattern>
10703   : I<(outs dst_reg:$dst),
10704       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
10705       asm,
10706       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
10707       "$idx, $rot" # "|" # apple_kind #
10708       "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
10709     Sched<[WriteV]> {
10710   bits<5> Rd;
10711   bits<5> Rn;
10712   bits<5> Rm;
10713   bits<2> rot;
10714
10715   let Inst{31}    = 0;
10716   let Inst{30}    = Q;
10717   let Inst{29}    = U;
10718   let Inst{28}    = Scalar;
10719   let Inst{27-24} = 0b1111;
10720   let Inst{23-22} = size;
10721   // Bit 21 must be set by the derived class.
10722   let Inst{20-16} = Rm;
10723   let Inst{15}    = opc1;
10724   let Inst{14-13} = rot;
10725   let Inst{12}    = opc2;
10726   // Bit 11 must be set by the derived class.
10727   let Inst{10}    = 0;
10728   let Inst{9-5}   = Rn;
10729   let Inst{4-0}   = Rd;
10730 }
10731
10732 // The complex instructions index by pairs of elements, so the VectorIndexes
10733 // don't match the lane types, and the index bits are different to the other
10734 // classes.
10735 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
10736                                      string asm, SDPatternOperator OpNode> {
10737   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10738   def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
10739                       V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
10740                       ".4h", ".h", []> {
10741     bits<1> idx;
10742     let Inst{11} = 0;
10743     let Inst{21} = idx{0};
10744   }
10745
10746   def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
10747                       V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
10748                       ".8h", ".8h", ".h", []> {
10749     bits<2> idx;
10750     let Inst{11} = idx{1};
10751     let Inst{21} = idx{0};
10752   }
10753   } // Predicates = HasComplxNum, HasNEON, HasFullFP16]
10754
10755   let Predicates = [HasComplxNum, HasNEON] in {
10756   def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
10757                       V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
10758                       ".4s", ".4s", ".s", []> {
10759     bits<1> idx;
10760     let Inst{11} = idx{0};
10761     let Inst{21} = 0;
10762   }
10763   } // Predicates = [HasComplxNum, HasNEON]
10764 }
10765
10766 //----------------------------------------------------------------------------
10767 // Crypto extensions
10768 //----------------------------------------------------------------------------
10769
10770 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10771 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
10772               list<dag> pat>
10773   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
10774     Sched<[WriteV]>{
10775   bits<5> Rd;
10776   bits<5> Rn;
10777   let Inst{31-16} = 0b0100111000101000;
10778   let Inst{15-12} = opc;
10779   let Inst{11-10} = 0b10;
10780   let Inst{9-5}   = Rn;
10781   let Inst{4-0}   = Rd;
10782 }
10783
10784 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
10785   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
10786             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
10787
10788 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
10789   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
10790             "$Rd = $dst",
10791             [(set (v16i8 V128:$dst),
10792                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
10793
10794 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10795 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
10796                      dag oops, dag iops, list<dag> pat>
10797   : I<oops, iops, asm,
10798       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
10799       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
10800     Sched<[WriteV]>{
10801   bits<5> Rd;
10802   bits<5> Rn;
10803   bits<5> Rm;
10804   let Inst{31-21} = 0b01011110000;
10805   let Inst{20-16} = Rm;
10806   let Inst{15}    = 0;
10807   let Inst{14-12} = opc;
10808   let Inst{11-10} = 0b00;
10809   let Inst{9-5}   = Rn;
10810   let Inst{4-0}   = Rd;
10811 }
10812
10813 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
10814   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10815                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
10816                    [(set (v4i32 FPR128:$dst),
10817                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
10818                                  (v4i32 V128:$Rm)))]>;
10819
10820 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
10821   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
10822                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
10823                    [(set (v4i32 V128:$dst),
10824                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
10825                                  (v4i32 V128:$Rm)))]>;
10826
10827 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
10828   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10829                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
10830                    [(set (v4i32 FPR128:$dst),
10831                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
10832                                  (v4i32 V128:$Rm)))]>;
10833
10834 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10835 class SHA2OpInst<bits<4> opc, string asm, string kind,
10836                  string cstr, dag oops, dag iops,
10837                  list<dag> pat>
10838   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
10839                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
10840     Sched<[WriteV]>{
10841   bits<5> Rd;
10842   bits<5> Rn;
10843   let Inst{31-16} = 0b0101111000101000;
10844   let Inst{15-12} = opc;
10845   let Inst{11-10} = 0b10;
10846   let Inst{9-5}   = Rn;
10847   let Inst{4-0}   = Rd;
10848 }
10849
10850 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
10851   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
10852                (ins V128:$Rd, V128:$Rn),
10853                [(set (v4i32 V128:$dst),
10854                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
10855
10856 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
10857   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
10858                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
10859
10860 // Armv8.2-A Crypto extensions
10861 class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
10862                     list<dag> pattern>
10863   : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> {
10864   bits<5> Vd;
10865   bits<5> Vn;
10866   let Inst{31-25} = 0b1100111;
10867   let Inst{9-5}   = Vn;
10868   let Inst{4-0}   = Vd;
10869 }
10870
10871 class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
10872   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops,
10873                   "$Vm = $Vd", []> {
10874   let Inst{31-25} = 0b1100111;
10875   let Inst{24-21} = 0b0110;
10876   let Inst{20-15} = 0b000001;
10877   let Inst{14}    = op0;
10878   let Inst{13-12} = 0b00;
10879   let Inst{11-10} = op1;
10880 }
10881 class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
10882   : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">;
10883 class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
10884   : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">;
10885
10886 class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
10887                 string asmops, string cst>
10888   : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
10889   bits<5> Vm;
10890   let Inst{24-21} = 0b0011;
10891   let Inst{20-16} = Vm;
10892   let Inst{15}    = 0b1;
10893   let Inst{14}    = op0;
10894   let Inst{13-12} = 0b00;
10895   let Inst{11-10} = op1;
10896 }
10897 class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
10898   : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10899               "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">;
10900 class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
10901   : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10902               "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10903 class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
10904   : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10905               "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">;
10906 class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
10907   : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10908               "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10909 class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
10910   : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
10911               asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10912
10913 class CryptoRRRR<bits<2>op0, string asm, string asmops>
10914   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
10915                   asmops, "", []> {
10916   bits<5> Vm;
10917   bits<5> Va;
10918   let Inst{24-23} = 0b00;
10919   let Inst{22-21} = op0;
10920   let Inst{20-16} = Vm;
10921   let Inst{15}    = 0b0;
10922   let Inst{14-10} = Va;
10923 }
10924 class CryptoRRRR_16B<bits<2>op0, string asm>
10925  : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" #
10926                         "|.16b\t$Vd, $Vn, $Vm, $Va}"> {
10927 }
10928 class CryptoRRRR_4S<bits<2>op0, string asm>
10929  : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" #
10930                          "|.4s\t$Vd, $Vn, $Vm, $Va}"> {
10931 }
10932
10933 class CryptoRRRi6<string asm>
10934   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
10935                   "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" #
10936                   "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> {
10937   bits<6> imm;
10938   bits<5> Vm;
10939   let Inst{24-21} = 0b0100;
10940   let Inst{20-16} = Vm;
10941   let Inst{15-10} = imm;
10942   let Inst{9-5}   = Vn;
10943   let Inst{4-0}   = Vd;
10944 }
10945
10946 class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
10947   : BaseCryptoV82<(outs V128:$Vdst),
10948                   (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
10949                   asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" #
10950                        "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> {
10951   bits<2> imm;
10952   bits<5> Vm;
10953   let Inst{24-21} = 0b0010;
10954   let Inst{20-16} = Vm;
10955   let Inst{15}    = 0b1;
10956   let Inst{14}    = op0;
10957   let Inst{13-12} = imm;
10958   let Inst{11-10} = op1;
10959 }
10960
10961 //----------------------------------------------------------------------------
10962 // v8.1 atomic instructions extension:
10963 // * CAS
10964 // * CASP
10965 // * SWP
10966 // * LDOPregister<OP>, and aliases STOPregister<OP>
10967
10968 // Instruction encodings:
10969 //
10970 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
10971 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
10972 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
10973 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
10974 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
10975 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
10976
10977 // Instruction syntax:
10978 //
10979 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10980 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
10981 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
10982 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
10983 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10984 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
10985 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10986 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
10987 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
10988 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
10989
10990 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10991 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
10992                       string cstr, list<dag> pattern>
10993       : I<oops, iops, asm, operands, cstr, pattern> {
10994   bits<2> Sz;
10995   bit NP;
10996   bit Acq;
10997   bit Rel;
10998   bits<5> Rs;
10999   bits<5> Rn;
11000   bits<5> Rt;
11001   let Inst{31-30} = Sz;
11002   let Inst{29-24} = 0b001000;
11003   let Inst{23} = NP;
11004   let Inst{22} = Acq;
11005   let Inst{21} = 0b1;
11006   let Inst{20-16} = Rs;
11007   let Inst{15} = Rel;
11008   let Inst{14-10} = 0b11111;
11009   let Inst{9-5} = Rn;
11010   let Inst{4-0} = Rt;
11011   let Predicates = [HasLSE];
11012 }
11013
11014 class BaseCAS<string order, string size, RegisterClass RC>
11015       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11016                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
11017                         "$out = $Rs",[]>,
11018         Sched<[WriteAtomic]> {
11019   let NP = 1;
11020 }
11021
11022 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
11023   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
11024   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
11025   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
11026   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
11027 }
11028
11029 class BaseCASP<string order, string size, RegisterOperand RC>
11030       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11031                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
11032                         "$out = $Rs",[]>,
11033         Sched<[WriteAtomic]> {
11034   let NP = 0;
11035 }
11036
11037 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
11038   let Sz = 0b00, Acq = Acq, Rel = Rel in
11039     def W : BaseCASP<order, "", WSeqPairClassOperand>;
11040   let Sz = 0b01, Acq = Acq, Rel = Rel in
11041     def X : BaseCASP<order, "", XSeqPairClassOperand>;
11042 }
11043
11044 let Predicates = [HasLSE] in
11045 class BaseSWP<string order, string size, RegisterClass RC>
11046       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
11047           "\t$Rs, $Rt, [$Rn]","",[]>,
11048         Sched<[WriteAtomic]> {
11049   bits<2> Sz;
11050   bit Acq;
11051   bit Rel;
11052   bits<5> Rs;
11053   bits<3> opc = 0b000;
11054   bits<5> Rn;
11055   bits<5> Rt;
11056   let Inst{31-30} = Sz;
11057   let Inst{29-24} = 0b111000;
11058   let Inst{23} = Acq;
11059   let Inst{22} = Rel;
11060   let Inst{21} = 0b1;
11061   let Inst{20-16} = Rs;
11062   let Inst{15} = 0b1;
11063   let Inst{14-12} = opc;
11064   let Inst{11-10} = 0b00;
11065   let Inst{9-5} = Rn;
11066   let Inst{4-0} = Rt;
11067   let Predicates = [HasLSE];
11068 }
11069
11070 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
11071   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
11072   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
11073   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
11074   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
11075 }
11076
11077 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
11078 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
11079       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
11080           "\t$Rs, $Rt, [$Rn]","",[]>,
11081         Sched<[WriteAtomic]> {
11082   bits<2> Sz;
11083   bit Acq;
11084   bit Rel;
11085   bits<5> Rs;
11086   bits<3> opc;
11087   bits<5> Rn;
11088   bits<5> Rt;
11089   let Inst{31-30} = Sz;
11090   let Inst{29-24} = 0b111000;
11091   let Inst{23} = Acq;
11092   let Inst{22} = Rel;
11093   let Inst{21} = 0b1;
11094   let Inst{20-16} = Rs;
11095   let Inst{15} = 0b0;
11096   let Inst{14-12} = opc;
11097   let Inst{11-10} = 0b00;
11098   let Inst{9-5} = Rn;
11099   let Inst{4-0} = Rt;
11100   let Predicates = [HasLSE];
11101 }
11102
11103 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
11104                         string order> {
11105   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
11106     def B : BaseLDOPregister<op, order, "b", GPR32>;
11107   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
11108     def H : BaseLDOPregister<op, order, "h", GPR32>;
11109   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
11110     def W : BaseLDOPregister<op, order, "", GPR32>;
11111   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
11112     def X : BaseLDOPregister<op, order, "", GPR64>;
11113 }
11114
11115 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
11116 // complex DAG for DstRHS.
11117 let Predicates = [HasLSE] in
11118 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
11119                                          string size, dag SrcRHS, dag DstRHS> {
11120   def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
11121             (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
11122   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
11123             (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
11124   def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
11125             (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
11126   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
11127             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11128   def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
11129             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11130 }
11131
11132 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
11133                                      string size, dag RHS> {
11134   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
11135 }
11136
11137 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
11138                                          string size, dag LHS, dag RHS> {
11139   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
11140 }
11141
11142 multiclass LDOPregister_patterns<string inst, string op> {
11143   defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
11144   defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
11145   defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
11146   defm : LDOPregister_patterns_ord<inst, "B", op, "8",  (i32 GPR32:$Rm)>;
11147 }
11148
11149 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
11150   defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
11151                         (i64 GPR64:$Rm),
11152                         (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
11153   defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
11154                         (i32 GPR32:$Rm),
11155                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11156   defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
11157                         (i32 GPR32:$Rm),
11158                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11159   defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
11160                         (i32 GPR32:$Rm),
11161                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11162 }
11163
11164 let Predicates = [HasLSE] in
11165 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
11166                                         string size, dag OLD, dag NEW> {
11167   def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
11168             (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
11169   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
11170             (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11171   def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
11172             (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11173   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
11174             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11175   def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
11176             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11177 }
11178
11179 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
11180                                     string size, dag OLD, dag NEW> {
11181   defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
11182 }
11183
11184 multiclass CASregister_patterns<string inst, string op> {
11185   defm : CASregister_patterns_ord<inst, "X", op, "64",
11186                         (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
11187   defm : CASregister_patterns_ord<inst, "W", op, "32",
11188                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11189   defm : CASregister_patterns_ord<inst, "H", op, "16",
11190                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11191   defm : CASregister_patterns_ord<inst, "B", op, "8",
11192                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11193 }
11194
11195 let Predicates = [HasLSE] in
11196 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
11197                         Instruction inst> :
11198       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
11199
11200 multiclass STOPregister<string asm, string instr> {
11201   def : BaseSTOPregister<asm # "lb", GPR32, WZR,
11202                     !cast<Instruction>(instr # "LB")>;
11203   def : BaseSTOPregister<asm # "lh", GPR32, WZR,
11204                     !cast<Instruction>(instr # "LH")>;
11205   def : BaseSTOPregister<asm # "l",  GPR32, WZR,
11206                     !cast<Instruction>(instr # "LW")>;
11207   def : BaseSTOPregister<asm # "l",  GPR64, XZR,
11208                     !cast<Instruction>(instr # "LX")>;
11209   def : BaseSTOPregister<asm # "b",  GPR32, WZR,
11210                     !cast<Instruction>(instr # "B")>;
11211   def : BaseSTOPregister<asm # "h",  GPR32, WZR,
11212                     !cast<Instruction>(instr # "H")>;
11213   def : BaseSTOPregister<asm,        GPR32, WZR,
11214                     !cast<Instruction>(instr # "W")>;
11215   def : BaseSTOPregister<asm,        GPR64, XZR,
11216                     !cast<Instruction>(instr # "X")>;
11217 }
11218
11219 //----------------------------------------------------------------------------
11220 // Allow the size specifier tokens to be upper case, not just lower.
11221 def : TokenAlias<".4B", ".4b">;  // Add dot product
11222 def : TokenAlias<".8B", ".8b">;
11223 def : TokenAlias<".4H", ".4h">;
11224 def : TokenAlias<".2S", ".2s">;
11225 def : TokenAlias<".1D", ".1d">;
11226 def : TokenAlias<".16B", ".16b">;
11227 def : TokenAlias<".8H", ".8h">;
11228 def : TokenAlias<".4S", ".4s">;
11229 def : TokenAlias<".2D", ".2d">;
11230 def : TokenAlias<".1Q", ".1q">;
11231 def : TokenAlias<".2H", ".2h">;
11232 def : TokenAlias<".B", ".b">;
11233 def : TokenAlias<".H", ".h">;
11234 def : TokenAlias<".S", ".s">;
11235 def : TokenAlias<".D", ".d">;
11236 def : TokenAlias<".Q", ".q">;