]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrFormats.td
Merge ^/vendor/lvm-project/release-10.x up to its last change (upstream
[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 // AArch64 Instruction Format
24 class AArch64Inst<Format f, string cstr> : Instruction {
25   field bits<32> Inst; // Instruction encoding.
26   // Mask of bits that cause an encoding to be UNPREDICTABLE.
27   // If a bit is set, then if the corresponding bit in the
28   // target encoding differs from its value in the "Inst" field,
29   // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
30   field bits<32> Unpredictable = 0;
31   // SoftFail is the generic name for this field, but we alias it so
32   // as to make it more obvious what it means in ARM-land.
33   field bits<32> SoftFail = Unpredictable;
34   let Namespace   = "AArch64";
35   Format F        = f;
36   bits<2> Form    = F.Value;
37   let Pattern     = [];
38   let Constraints = cstr;
39 }
40
41 class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
42   : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
43
44 // Pseudo instructions (don't have encoding information)
45 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
46     : AArch64Inst<PseudoFrm, cstr> {
47   dag OutOperandList = oops;
48   dag InOperandList  = iops;
49   let Pattern        = pattern;
50   let isCodeGenOnly  = 1;
51 }
52
53 // Real instructions (have encoding information)
54 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
55   let Pattern = pattern;
56   let Size = 4;
57 }
58
59 // Enum describing whether an instruction is
60 // destructive in its first source operand.
61 class DestructiveInstTypeEnum<bits<1> val> {
62   bits<1> Value = val;
63 }
64 def NotDestructive  : DestructiveInstTypeEnum<0>;
65 def Destructive     : DestructiveInstTypeEnum<1>;
66
67 // Normal instructions
68 class I<dag oops, dag iops, string asm, string operands, string cstr,
69         list<dag> pattern>
70     : EncodedI<cstr, pattern> {
71   dag OutOperandList = oops;
72   dag InOperandList  = iops;
73   let AsmString      = !strconcat(asm, operands);
74
75   // Destructive operations (SVE)
76   DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
77   ElementSizeEnum ElementSize = ElementSizeB;
78
79   let TSFlags{3} = DestructiveInstType.Value;
80   let TSFlags{2-0} = ElementSize.Value;
81 }
82
83 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
84 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
85 class UnOpFrag<dag res>  : PatFrag<(ops node:$LHS), res>;
86
87 // Helper fragment for an extract of the high portion of a 128-bit vector.
88 def extract_high_v16i8 :
89    UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
90 def extract_high_v8i16 :
91    UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
92 def extract_high_v4i32 :
93    UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
94 def extract_high_v2i64 :
95    UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
96
97 //===----------------------------------------------------------------------===//
98 // Asm Operand Classes.
99 //
100
101 // Shifter operand for arithmetic shifted encodings.
102 def ShifterOperand : AsmOperandClass {
103   let Name = "Shifter";
104 }
105
106 // Shifter operand for mov immediate encodings.
107 def MovImm32ShifterOperand : AsmOperandClass {
108   let SuperClasses = [ShifterOperand];
109   let Name = "MovImm32Shifter";
110   let RenderMethod = "addShifterOperands";
111   let DiagnosticType = "InvalidMovImm32Shift";
112 }
113 def MovImm64ShifterOperand : AsmOperandClass {
114   let SuperClasses = [ShifterOperand];
115   let Name = "MovImm64Shifter";
116   let RenderMethod = "addShifterOperands";
117   let DiagnosticType = "InvalidMovImm64Shift";
118 }
119
120 // Shifter operand for arithmetic register shifted encodings.
121 class ArithmeticShifterOperand<int width> : AsmOperandClass {
122   let SuperClasses = [ShifterOperand];
123   let Name = "ArithmeticShifter" # width;
124   let PredicateMethod = "isArithmeticShifter<" # width # ">";
125   let RenderMethod = "addShifterOperands";
126   let DiagnosticType = "AddSubRegShift" # width;
127 }
128
129 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
130 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
131
132 // Shifter operand for logical register shifted encodings.
133 class LogicalShifterOperand<int width> : AsmOperandClass {
134   let SuperClasses = [ShifterOperand];
135   let Name = "LogicalShifter" # width;
136   let PredicateMethod = "isLogicalShifter<" # width # ">";
137   let RenderMethod = "addShifterOperands";
138   let DiagnosticType = "AddSubRegShift" # width;
139 }
140
141 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
142 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
143
144 // Shifter operand for logical vector 128/64-bit shifted encodings.
145 def LogicalVecShifterOperand : AsmOperandClass {
146   let SuperClasses = [ShifterOperand];
147   let Name = "LogicalVecShifter";
148   let RenderMethod = "addShifterOperands";
149 }
150 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
151   let SuperClasses = [LogicalVecShifterOperand];
152   let Name = "LogicalVecHalfWordShifter";
153   let RenderMethod = "addShifterOperands";
154 }
155
156 // The "MSL" shifter on the vector MOVI instruction.
157 def MoveVecShifterOperand : AsmOperandClass {
158   let SuperClasses = [ShifterOperand];
159   let Name = "MoveVecShifter";
160   let RenderMethod = "addShifterOperands";
161 }
162
163 // Extend operand for arithmetic encodings.
164 def ExtendOperand : AsmOperandClass {
165   let Name = "Extend";
166   let DiagnosticType = "AddSubRegExtendLarge";
167 }
168 def ExtendOperand64 : AsmOperandClass {
169   let SuperClasses = [ExtendOperand];
170   let Name = "Extend64";
171   let DiagnosticType = "AddSubRegExtendSmall";
172 }
173 // 'extend' that's a lsl of a 64-bit register.
174 def ExtendOperandLSL64 : AsmOperandClass {
175   let SuperClasses = [ExtendOperand];
176   let Name = "ExtendLSL64";
177   let RenderMethod = "addExtend64Operands";
178   let DiagnosticType = "AddSubRegExtendLarge";
179 }
180
181 // 8-bit floating-point immediate encodings.
182 def FPImmOperand : AsmOperandClass {
183   let Name = "FPImm";
184   let ParserMethod = "tryParseFPImm<true>";
185   let DiagnosticType = "InvalidFPImm";
186 }
187
188 def CondCode : AsmOperandClass {
189   let Name = "CondCode";
190   let DiagnosticType = "InvalidCondCode";
191 }
192
193 // A 32-bit register pasrsed as 64-bit
194 def GPR32as64Operand : AsmOperandClass {
195   let Name = "GPR32as64";
196   let ParserMethod =
197       "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";
198 }
199 def GPR32as64 : RegisterOperand<GPR32> {
200   let ParserMatchClass = GPR32as64Operand;
201 }
202
203 // A 64-bit register pasrsed as 32-bit
204 def GPR64as32Operand : AsmOperandClass {
205   let Name = "GPR64as32";
206   let ParserMethod =
207       "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";
208 }
209 def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {
210   let ParserMatchClass = GPR64as32Operand;
211 }
212
213 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
214 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
215 // are encoded as the eight bit value 'abcdefgh'.
216 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
217
218 class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
219   let Name = "UImm" # Width # "s" # Scale;
220   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;
221   let RenderMethod = "addImmScaledOperands<" # Scale # ">";
222   let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";
223 }
224
225 class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
226   let Name = "SImm" # Width # "s" # Scale;
227   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;
228   let RenderMethod = "addImmScaledOperands<" # Scale # ">";
229   let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";
230 }
231
232 //===----------------------------------------------------------------------===//
233 // Operand Definitions.
234 //
235
236 // ADR[P] instruction labels.
237 def AdrpOperand : AsmOperandClass {
238   let Name = "AdrpLabel";
239   let ParserMethod = "tryParseAdrpLabel";
240   let DiagnosticType = "InvalidLabel";
241 }
242 def adrplabel : Operand<i64> {
243   let EncoderMethod = "getAdrLabelOpValue";
244   let PrintMethod = "printAdrpLabel";
245   let ParserMatchClass = AdrpOperand;
246 }
247
248 def AdrOperand : AsmOperandClass {
249   let Name = "AdrLabel";
250   let ParserMethod = "tryParseAdrLabel";
251   let DiagnosticType = "InvalidLabel";
252 }
253 def adrlabel : Operand<i64> {
254   let EncoderMethod = "getAdrLabelOpValue";
255   let ParserMatchClass = AdrOperand;
256 }
257
258 class SImmOperand<int width> : AsmOperandClass {
259   let Name = "SImm" # width;
260   let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
261   let RenderMethod = "addImmOperands";
262   let PredicateMethod = "isSImm<" # width # ">";
263 }
264
265
266 class AsmImmRange<int Low, int High> : AsmOperandClass {
267   let Name = "Imm" # Low # "_" # High;
268   let DiagnosticType = "InvalidImm" # Low # "_" # High;
269   let RenderMethod = "addImmOperands";
270   let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
271 }
272
273 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
274 def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;
275 def simm10Scaled : Operand<i64> {
276   let ParserMatchClass = SImm10s8Operand;
277   let DecoderMethod = "DecodeSImm<10>";
278   let PrintMethod = "printImmScale<8>";
279 }
280
281 def simm9s16 : Operand<i64> {
282   let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;
283   let DecoderMethod = "DecodeSImm<9>";
284   let PrintMethod = "printImmScale<16>";
285 }
286
287 // uimm6 predicate - True if the immediate is in the range [0, 63].
288 def UImm6Operand : AsmOperandClass {
289   let Name = "UImm6";
290   let DiagnosticType = "InvalidImm0_63";
291 }
292
293 def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
294   let ParserMatchClass = UImm6Operand;
295 }
296
297 def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
298   let ParserMatchClass = AsmImmRange<0, 65535>;
299 }
300
301 def SImm9Operand : SImmOperand<9>;
302 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
303   let ParserMatchClass = SImm9Operand;
304   let DecoderMethod = "DecodeSImm<9>";
305 }
306
307 def SImm8Operand : SImmOperand<8>;
308 def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 127; }]> {
309   let ParserMatchClass = SImm8Operand;
310   let DecoderMethod = "DecodeSImm<8>";
311 }
312
313 def SImm6Operand : SImmOperand<6>;
314 def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
315   let ParserMatchClass = SImm6Operand;
316   let DecoderMethod = "DecodeSImm<6>";
317 }
318
319 def SImm5Operand : SImmOperand<5>;
320 def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
321   let ParserMatchClass = SImm5Operand;
322   let DecoderMethod = "DecodeSImm<5>";
323 }
324
325 def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
326   let ParserMatchClass = SImm5Operand;
327   let DecoderMethod = "DecodeSImm<5>";
328 }
329
330 // simm7sN predicate - True if the immediate is a multiple of N in the range
331 // [-64 * N, 63 * N].
332
333 def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;
334 def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;
335 def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
336
337 def simm7s4 : Operand<i32> {
338   let ParserMatchClass = SImm7s4Operand;
339   let PrintMethod = "printImmScale<4>";
340 }
341
342 def simm7s8 : Operand<i32> {
343   let ParserMatchClass = SImm7s8Operand;
344   let PrintMethod = "printImmScale<8>";
345 }
346
347 def simm7s16 : Operand<i32> {
348   let ParserMatchClass = SImm7s16Operand;
349   let PrintMethod = "printImmScale<16>";
350 }
351
352 def am_indexed7s8   : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
353 def am_indexed7s16  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
354 def am_indexed7s32  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
355 def am_indexed7s64  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
356 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
357
358 def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>;
359 def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>;
360
361 def UImmS2XForm : SDNodeXForm<imm, [{
362   return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);
363 }]>;
364 def UImmS4XForm : SDNodeXForm<imm, [{
365   return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);
366 }]>;
367 def UImmS8XForm : SDNodeXForm<imm, [{
368   return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
369 }]>;
370
371 // uimm5sN predicate - True if the immediate is a multiple of N in the range
372 // [0 * N, 32 * N].
373 def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
374 def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;
375 def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;
376
377 def uimm5s2 : Operand<i64>, ImmLeaf<i64,
378                 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
379                 UImmS2XForm> {
380   let ParserMatchClass = UImm5s2Operand;
381   let PrintMethod = "printImmScale<2>";
382 }
383 def uimm5s4 : Operand<i64>, ImmLeaf<i64,
384                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
385                 UImmS4XForm> {
386   let ParserMatchClass = UImm5s4Operand;
387   let PrintMethod = "printImmScale<4>";
388 }
389 def uimm5s8 : Operand<i64>, ImmLeaf<i64,
390                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
391                 UImmS8XForm> {
392   let ParserMatchClass = UImm5s8Operand;
393   let PrintMethod = "printImmScale<8>";
394 }
395
396 // tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant)
397 // instead of ImmLeaf (Constant)
398 def tuimm5s2 : Operand<i64>, TImmLeaf<i64,
399                 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
400                 UImmS2XForm> {
401   let ParserMatchClass = UImm5s2Operand;
402   let PrintMethod = "printImmScale<2>";
403 }
404 def tuimm5s4 : Operand<i64>, TImmLeaf<i64,
405                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
406                 UImmS4XForm> {
407   let ParserMatchClass = UImm5s4Operand;
408   let PrintMethod = "printImmScale<4>";
409 }
410 def tuimm5s8 : Operand<i64>, TImmLeaf<i64,
411                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
412                 UImmS8XForm> {
413   let ParserMatchClass = UImm5s8Operand;
414   let PrintMethod = "printImmScale<8>";
415 }
416
417 // uimm6sN predicate - True if the immediate is a multiple of N in the range
418 // [0 * N, 64 * N].
419 def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;
420 def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;
421 def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;
422 def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;
423 def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;
424
425 def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
426   let ParserMatchClass = UImm6s1Operand;
427 }
428 def uimm6s2 : Operand<i64>, ImmLeaf<i64,
429 [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
430   let PrintMethod = "printImmScale<2>";
431   let ParserMatchClass = UImm6s2Operand;
432 }
433 def uimm6s4 : Operand<i64>, ImmLeaf<i64,
434 [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
435   let PrintMethod = "printImmScale<4>";
436   let ParserMatchClass = UImm6s4Operand;
437 }
438 def uimm6s8 : Operand<i64>, ImmLeaf<i64,
439 [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
440   let PrintMethod = "printImmScale<8>";
441   let ParserMatchClass = UImm6s8Operand;
442 }
443 def uimm6s16 : Operand<i64>, ImmLeaf<i64,
444 [{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {
445   let PrintMethod = "printImmScale<16>";
446   let ParserMatchClass = UImm6s16Operand;
447 }
448
449 // simm6sN predicate - True if the immediate is a multiple of N in the range
450 // [-32 * N, 31 * N].
451 def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
452 def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
453   let ParserMatchClass = SImm6s1Operand;
454   let DecoderMethod = "DecodeSImm<6>";
455 }
456
457 // simm4sN predicate - True if the immediate is a multiple of N in the range
458 // [ -8* N, 7 * N].
459 def SImm4s1Operand  : SImmScaledMemoryIndexed<4, 1>;
460 def SImm4s2Operand  : SImmScaledMemoryIndexed<4, 2>;
461 def SImm4s3Operand  : SImmScaledMemoryIndexed<4, 3>;
462 def SImm4s4Operand  : SImmScaledMemoryIndexed<4, 4>;
463 def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
464
465 def simm4s1 : Operand<i64>, ImmLeaf<i64,
466 [{ return Imm >=-8  && Imm <= 7; }]> {
467   let ParserMatchClass = SImm4s1Operand;
468   let DecoderMethod = "DecodeSImm<4>";
469 }
470
471 def simm4s2 : Operand<i64>, ImmLeaf<i64,
472 [{ return Imm >=-16  && Imm <= 14 && (Imm % 2) == 0x0; }]> {
473   let PrintMethod = "printImmScale<2>";
474   let ParserMatchClass = SImm4s2Operand;
475   let DecoderMethod = "DecodeSImm<4>";
476 }
477
478 def simm4s3 : Operand<i64>, ImmLeaf<i64,
479 [{ return Imm >=-24  && Imm <= 21 && (Imm % 3) == 0x0; }]> {
480   let PrintMethod = "printImmScale<3>";
481   let ParserMatchClass = SImm4s3Operand;
482   let DecoderMethod = "DecodeSImm<4>";
483 }
484
485 def simm4s4 : Operand<i64>, ImmLeaf<i64,
486 [{ return Imm >=-32  && Imm <= 28 && (Imm % 4) == 0x0; }]> {
487   let PrintMethod = "printImmScale<4>";
488   let ParserMatchClass = SImm4s4Operand;
489   let DecoderMethod = "DecodeSImm<4>";
490 }
491 def simm4s16 : Operand<i64>, ImmLeaf<i64,
492 [{ return Imm >=-128  && Imm <= 112 && (Imm % 16) == 0x0; }]> {
493   let PrintMethod = "printImmScale<16>";
494   let ParserMatchClass = SImm4s16Operand;
495   let DecoderMethod = "DecodeSImm<4>";
496 }
497
498 def Imm1_8Operand : AsmImmRange<1, 8>;
499 def Imm1_16Operand : AsmImmRange<1, 16>;
500 def Imm1_32Operand : AsmImmRange<1, 32>;
501 def Imm1_64Operand : AsmImmRange<1, 64>;
502
503 class BranchTarget<int N> : AsmOperandClass {
504   let Name = "BranchTarget" # N;
505   let DiagnosticType = "InvalidLabel";
506   let PredicateMethod = "isBranchTarget<" # N # ">";
507 }
508
509 class PCRelLabel<int N> : BranchTarget<N> {
510   let Name = "PCRelLabel" # N;
511 }
512
513 def BranchTarget14Operand : BranchTarget<14>;
514 def BranchTarget26Operand : BranchTarget<26>;
515 def PCRelLabel19Operand   : PCRelLabel<19>;
516
517 def MovWSymbolG3AsmOperand : AsmOperandClass {
518   let Name = "MovWSymbolG3";
519   let RenderMethod = "addImmOperands";
520 }
521
522 def movw_symbol_g3 : Operand<i32> {
523   let ParserMatchClass = MovWSymbolG3AsmOperand;
524 }
525
526 def MovWSymbolG2AsmOperand : AsmOperandClass {
527   let Name = "MovWSymbolG2";
528   let RenderMethod = "addImmOperands";
529 }
530
531 def movw_symbol_g2 : Operand<i32> {
532   let ParserMatchClass = MovWSymbolG2AsmOperand;
533 }
534
535 def MovWSymbolG1AsmOperand : AsmOperandClass {
536   let Name = "MovWSymbolG1";
537   let RenderMethod = "addImmOperands";
538 }
539
540 def movw_symbol_g1 : Operand<i32> {
541   let ParserMatchClass = MovWSymbolG1AsmOperand;
542 }
543
544 def MovWSymbolG0AsmOperand : AsmOperandClass {
545   let Name = "MovWSymbolG0";
546   let RenderMethod = "addImmOperands";
547 }
548
549 def movw_symbol_g0 : Operand<i32> {
550   let ParserMatchClass = MovWSymbolG0AsmOperand;
551 }
552
553 class fixedpoint_i32<ValueType FloatVT>
554   : Operand<FloatVT>,
555     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
556   let EncoderMethod = "getFixedPointScaleOpValue";
557   let DecoderMethod = "DecodeFixedPointScaleImm32";
558   let ParserMatchClass = Imm1_32Operand;
559 }
560
561 class fixedpoint_i64<ValueType FloatVT>
562   : Operand<FloatVT>,
563     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
564   let EncoderMethod = "getFixedPointScaleOpValue";
565   let DecoderMethod = "DecodeFixedPointScaleImm64";
566   let ParserMatchClass = Imm1_64Operand;
567 }
568
569 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
570 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
571 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
572
573 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
574 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
575 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
576
577 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
578   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
579 }]> {
580   let EncoderMethod = "getVecShiftR8OpValue";
581   let DecoderMethod = "DecodeVecShiftR8Imm";
582   let ParserMatchClass = Imm1_8Operand;
583 }
584 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
585   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
586 }]> {
587   let EncoderMethod = "getVecShiftR16OpValue";
588   let DecoderMethod = "DecodeVecShiftR16Imm";
589   let ParserMatchClass = Imm1_16Operand;
590 }
591 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
592   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
593 }]> {
594   let EncoderMethod = "getVecShiftR16OpValue";
595   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
596   let ParserMatchClass = Imm1_8Operand;
597 }
598 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
599   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
600 }]> {
601   let EncoderMethod = "getVecShiftR32OpValue";
602   let DecoderMethod = "DecodeVecShiftR32Imm";
603   let ParserMatchClass = Imm1_32Operand;
604 }
605 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
606   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
607 }]> {
608   let EncoderMethod = "getVecShiftR32OpValue";
609   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
610   let ParserMatchClass = Imm1_16Operand;
611 }
612 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
613   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
614 }]> {
615   let EncoderMethod = "getVecShiftR64OpValue";
616   let DecoderMethod = "DecodeVecShiftR64Imm";
617   let ParserMatchClass = Imm1_64Operand;
618 }
619 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
620   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
621 }]> {
622   let EncoderMethod = "getVecShiftR64OpValue";
623   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
624   let ParserMatchClass = Imm1_32Operand;
625 }
626
627 // Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant
628 // (ImmLeaf)
629 def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
630   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
631 }]> {
632   let EncoderMethod = "getVecShiftR8OpValue";
633   let DecoderMethod = "DecodeVecShiftR8Imm";
634   let ParserMatchClass = Imm1_8Operand;
635 }
636 def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
637   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
638 }]> {
639   let EncoderMethod = "getVecShiftR16OpValue";
640   let DecoderMethod = "DecodeVecShiftR16Imm";
641   let ParserMatchClass = Imm1_16Operand;
642 }
643 def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
644   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
645 }]> {
646   let EncoderMethod = "getVecShiftR32OpValue";
647   let DecoderMethod = "DecodeVecShiftR32Imm";
648   let ParserMatchClass = Imm1_32Operand;
649 }
650
651 def Imm0_1Operand : AsmImmRange<0, 1>;
652 def Imm0_7Operand : AsmImmRange<0, 7>;
653 def Imm0_15Operand : AsmImmRange<0, 15>;
654 def Imm0_31Operand : AsmImmRange<0, 31>;
655 def Imm0_63Operand : AsmImmRange<0, 63>;
656
657 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
658   return (((uint32_t)Imm) < 8);
659 }]> {
660   let EncoderMethod = "getVecShiftL8OpValue";
661   let DecoderMethod = "DecodeVecShiftL8Imm";
662   let ParserMatchClass = Imm0_7Operand;
663 }
664 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
665   return (((uint32_t)Imm) < 16);
666 }]> {
667   let EncoderMethod = "getVecShiftL16OpValue";
668   let DecoderMethod = "DecodeVecShiftL16Imm";
669   let ParserMatchClass = Imm0_15Operand;
670 }
671 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
672   return (((uint32_t)Imm) < 32);
673 }]> {
674   let EncoderMethod = "getVecShiftL32OpValue";
675   let DecoderMethod = "DecodeVecShiftL32Imm";
676   let ParserMatchClass = Imm0_31Operand;
677 }
678 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
679   return (((uint32_t)Imm) < 64);
680 }]> {
681   let EncoderMethod = "getVecShiftL64OpValue";
682   let DecoderMethod = "DecodeVecShiftL64Imm";
683   let ParserMatchClass = Imm0_63Operand;
684 }
685
686
687 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
688 // instructions for splatting repeating bit patterns across the immediate.
689 def logical_imm32_XFORM : SDNodeXForm<imm, [{
690   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
691   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
692 }]>;
693 def logical_imm64_XFORM : SDNodeXForm<imm, [{
694   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
695   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
696 }]>;
697
698 def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">,
699   GISDNodeXFormEquiv<logical_imm32_XFORM>;
700 def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">,
701   GISDNodeXFormEquiv<logical_imm64_XFORM>;
702
703 let DiagnosticType = "LogicalSecondSource" in {
704   def LogicalImm32Operand : AsmOperandClass {
705     let Name = "LogicalImm32";
706     let PredicateMethod = "isLogicalImm<int32_t>";
707     let RenderMethod = "addLogicalImmOperands<int32_t>";
708   }
709   def LogicalImm64Operand : AsmOperandClass {
710     let Name = "LogicalImm64";
711     let PredicateMethod = "isLogicalImm<int64_t>";
712     let RenderMethod = "addLogicalImmOperands<int64_t>";
713   }
714   def LogicalImm32NotOperand : AsmOperandClass {
715     let Name = "LogicalImm32Not";
716     let PredicateMethod = "isLogicalImm<int32_t>";
717     let RenderMethod = "addLogicalImmNotOperands<int32_t>";
718   }
719   def LogicalImm64NotOperand : AsmOperandClass {
720     let Name = "LogicalImm64Not";
721     let PredicateMethod = "isLogicalImm<int64_t>";
722     let RenderMethod = "addLogicalImmNotOperands<int64_t>";
723   }
724 }
725 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
726   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
727 }], logical_imm32_XFORM> {
728   let PrintMethod = "printLogicalImm<int32_t>";
729   let ParserMatchClass = LogicalImm32Operand;
730 }
731 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
732   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
733 }], logical_imm64_XFORM> {
734   let PrintMethod = "printLogicalImm<int64_t>";
735   let ParserMatchClass = LogicalImm64Operand;
736 }
737 def logical_imm32_not : Operand<i32> {
738   let ParserMatchClass = LogicalImm32NotOperand;
739 }
740 def logical_imm64_not : Operand<i64> {
741   let ParserMatchClass = LogicalImm64NotOperand;
742 }
743
744 // iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535].
745 let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in {
746 def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{
747   return ((uint32_t)Imm) < 65536;
748 }]>;
749
750 def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{
751   return ((uint64_t)Imm) < 65536;
752 }]>;
753 }
754
755 // imm0_255 predicate - True if the immediate is in the range [0,255].
756 def Imm0_255Operand : AsmImmRange<0,255>;
757
758 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
759   return ((uint32_t)Imm) < 256;
760 }]> {
761   let ParserMatchClass = Imm0_255Operand;
762   let PrintMethod = "printImm";
763 }
764
765 // imm0_127 predicate - True if the immediate is in the range [0,127]
766 def Imm0_127Operand : AsmImmRange<0, 127>;
767 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
768   return ((uint32_t)Imm) < 128;
769 }]> {
770   let ParserMatchClass = Imm0_127Operand;
771   let PrintMethod = "printImm";
772 }
773
774 def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{
775   return ((uint64_t)Imm) < 128;
776 }]> {
777   let ParserMatchClass = Imm0_127Operand;
778   let PrintMethod = "printImm";
779 }
780
781 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
782 // for all shift-amounts.
783
784 // imm0_63 predicate - True if the immediate is in the range [0,63]
785 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
786   return ((uint64_t)Imm) < 64;
787 }]> {
788   let ParserMatchClass = Imm0_63Operand;
789 }
790
791 // imm0_31 predicate - True if the immediate is in the range [0,31]
792 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
793   return ((uint64_t)Imm) < 32;
794 }]> {
795   let ParserMatchClass = Imm0_31Operand;
796 }
797
798 // timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf)
799 // instead of Contant (ImmLeaf)
800 def timm0_31 : Operand<i64>, TImmLeaf<i64, [{
801   return ((uint64_t)Imm) < 32;
802 }]> {
803   let ParserMatchClass = Imm0_31Operand;
804 }
805
806 // True if the 32-bit immediate is in the range [0,31]
807 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
808   return ((uint64_t)Imm) < 32;
809 }]> {
810   let ParserMatchClass = Imm0_31Operand;
811 }
812
813 // imm0_1 predicate - True if the immediate is in the range [0,1]
814 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
815   return ((uint64_t)Imm) < 2;
816 }]> {
817   let ParserMatchClass = Imm0_1Operand;
818 }
819
820 // imm0_15 predicate - True if the immediate is in the range [0,15]
821 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
822   return ((uint64_t)Imm) < 16;
823 }]> {
824   let ParserMatchClass = Imm0_15Operand;
825 }
826
827 // imm0_7 predicate - True if the immediate is in the range [0,7]
828 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
829   return ((uint64_t)Imm) < 8;
830 }]> {
831   let ParserMatchClass = Imm0_7Operand;
832 }
833
834 // imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
835 def imm32_0_7 : Operand<i32>, ImmLeaf<i32, [{
836   return ((uint32_t)Imm) < 8;
837 }]> {
838   let ParserMatchClass = Imm0_7Operand;
839 }
840
841 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
842 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
843   return ((uint32_t)Imm) < 16;
844 }]> {
845   let ParserMatchClass = Imm0_15Operand;
846 }
847
848 // An arithmetic shifter operand:
849 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
850 //  {5-0} - imm6
851 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
852   let PrintMethod = "printShifter";
853   let ParserMatchClass = !cast<AsmOperandClass>(
854                          "ArithmeticShifterOperand" # width);
855 }
856
857 def arith_shift32 : arith_shift<i32, 32>;
858 def arith_shift64 : arith_shift<i64, 64>;
859
860 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
861     : Operand<Ty>,
862       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
863   let PrintMethod = "printShiftedRegister";
864   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
865 }
866
867 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
868 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
869
870 def gi_arith_shifted_reg32 :
871   GIComplexOperandMatcher<s32, "selectArithShiftedRegister">,
872   GIComplexPatternEquiv<arith_shifted_reg32>;
873
874 def gi_arith_shifted_reg64 :
875   GIComplexOperandMatcher<s64, "selectArithShiftedRegister">,
876   GIComplexPatternEquiv<arith_shifted_reg64>;
877
878 // An arithmetic shifter operand:
879 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
880 //  {5-0} - imm6
881 class logical_shift<int width> : Operand<i32> {
882   let PrintMethod = "printShifter";
883   let ParserMatchClass = !cast<AsmOperandClass>(
884                          "LogicalShifterOperand" # width);
885 }
886
887 def logical_shift32 : logical_shift<32>;
888 def logical_shift64 : logical_shift<64>;
889
890 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
891     : Operand<Ty>,
892       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
893   let PrintMethod = "printShiftedRegister";
894   let MIOperandInfo = (ops regclass, shiftop);
895 }
896
897 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
898 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
899
900 def gi_logical_shifted_reg32 :
901   GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">,
902   GIComplexPatternEquiv<logical_shifted_reg32>;
903
904 def gi_logical_shifted_reg64 :
905   GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">,
906   GIComplexPatternEquiv<logical_shifted_reg64>;
907
908 // A logical vector shifter operand:
909 //  {7-6} - shift type: 00 = lsl
910 //  {5-0} - imm6: #0, #8, #16, or #24
911 def logical_vec_shift : Operand<i32> {
912   let PrintMethod = "printShifter";
913   let EncoderMethod = "getVecShifterOpValue";
914   let ParserMatchClass = LogicalVecShifterOperand;
915 }
916
917 // A logical vector half-word shifter operand:
918 //  {7-6} - shift type: 00 = lsl
919 //  {5-0} - imm6: #0 or #8
920 def logical_vec_hw_shift : Operand<i32> {
921   let PrintMethod = "printShifter";
922   let EncoderMethod = "getVecShifterOpValue";
923   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
924 }
925
926 // A vector move shifter operand:
927 //  {0} - imm1: #8 or #16
928 def move_vec_shift : Operand<i32> {
929   let PrintMethod = "printShifter";
930   let EncoderMethod = "getMoveVecShifterOpValue";
931   let ParserMatchClass = MoveVecShifterOperand;
932 }
933
934 let DiagnosticType = "AddSubSecondSource" in {
935   def AddSubImmOperand : AsmOperandClass {
936     let Name = "AddSubImm";
937     let ParserMethod = "tryParseImmWithOptionalShift";
938     let RenderMethod = "addImmWithOptionalShiftOperands<12>";
939   }
940   def AddSubImmNegOperand : AsmOperandClass {
941     let Name = "AddSubImmNeg";
942     let ParserMethod = "tryParseImmWithOptionalShift";
943     let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
944   }
945 }
946 // An ADD/SUB immediate shifter operand:
947 //  second operand:
948 //  {7-6} - shift type: 00 = lsl
949 //  {5-0} - imm6: #0 or #12
950 class addsub_shifted_imm<ValueType Ty>
951     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
952   let PrintMethod = "printAddSubImm";
953   let EncoderMethod = "getAddSubImmOpValue";
954   let ParserMatchClass = AddSubImmOperand;
955   let MIOperandInfo = (ops i32imm, i32imm);
956 }
957
958 class addsub_shifted_imm_neg<ValueType Ty>
959     : Operand<Ty> {
960   let EncoderMethod = "getAddSubImmOpValue";
961   let ParserMatchClass = AddSubImmNegOperand;
962   let MIOperandInfo = (ops i32imm, i32imm);
963 }
964
965 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
966 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
967 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
968 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
969
970 def gi_addsub_shifted_imm32 :
971     GIComplexOperandMatcher<s32, "selectArithImmed">,
972     GIComplexPatternEquiv<addsub_shifted_imm32>;
973
974 def gi_addsub_shifted_imm64 :
975     GIComplexOperandMatcher<s64, "selectArithImmed">,
976     GIComplexPatternEquiv<addsub_shifted_imm64>;
977
978 class neg_addsub_shifted_imm<ValueType Ty>
979     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
980   let PrintMethod = "printAddSubImm";
981   let EncoderMethod = "getAddSubImmOpValue";
982   let ParserMatchClass = AddSubImmOperand;
983   let MIOperandInfo = (ops i32imm, i32imm);
984 }
985
986 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
987 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
988
989 def gi_neg_addsub_shifted_imm32 :
990     GIComplexOperandMatcher<s32, "selectNegArithImmed">,
991     GIComplexPatternEquiv<neg_addsub_shifted_imm32>;
992
993 def gi_neg_addsub_shifted_imm64 :
994     GIComplexOperandMatcher<s64, "selectNegArithImmed">,
995     GIComplexPatternEquiv<neg_addsub_shifted_imm64>;
996
997 // An extend operand:
998 //  {5-3} - extend type
999 //  {2-0} - imm3
1000 def arith_extend : Operand<i32> {
1001   let PrintMethod = "printArithExtend";
1002   let ParserMatchClass = ExtendOperand;
1003 }
1004 def arith_extend64 : Operand<i32> {
1005   let PrintMethod = "printArithExtend";
1006   let ParserMatchClass = ExtendOperand64;
1007 }
1008
1009 // 'extend' that's a lsl of a 64-bit register.
1010 def arith_extendlsl64 : Operand<i32> {
1011   let PrintMethod = "printArithExtend";
1012   let ParserMatchClass = ExtendOperandLSL64;
1013 }
1014
1015 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
1016                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1017   let PrintMethod = "printExtendedRegister";
1018   let MIOperandInfo = (ops GPR32, arith_extend);
1019 }
1020
1021 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
1022                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1023   let PrintMethod = "printExtendedRegister";
1024   let MIOperandInfo = (ops GPR32, arith_extend64);
1025 }
1026
1027 def arith_extended_reg32_i32 : arith_extended_reg32<i32>;
1028 def gi_arith_extended_reg32_i32 :
1029     GIComplexOperandMatcher<s32, "selectArithExtendedRegister">,
1030     GIComplexPatternEquiv<arith_extended_reg32_i32>;
1031
1032 def arith_extended_reg32_i64 : arith_extended_reg32<i64>;
1033 def gi_arith_extended_reg32_i64 :
1034     GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1035     GIComplexPatternEquiv<arith_extended_reg32_i64>;
1036
1037 def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>;
1038 def gi_arith_extended_reg32to64_i64 :
1039     GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1040     GIComplexPatternEquiv<arith_extended_reg32to64_i64>;
1041
1042 // Floating-point immediate.
1043 def fpimm16 : Operand<f16>,
1044               FPImmLeaf<f16, [{
1045       return AArch64_AM::getFP16Imm(Imm) != -1;
1046     }], SDNodeXForm<fpimm, [{
1047       APFloat InVal = N->getValueAPF();
1048       uint32_t enc = AArch64_AM::getFP16Imm(InVal);
1049       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1050     }]>> {
1051   let ParserMatchClass = FPImmOperand;
1052   let PrintMethod = "printFPImmOperand";
1053 }
1054 def fpimm32 : Operand<f32>,
1055               FPImmLeaf<f32, [{
1056       return AArch64_AM::getFP32Imm(Imm) != -1;
1057     }], SDNodeXForm<fpimm, [{
1058       APFloat InVal = N->getValueAPF();
1059       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
1060       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1061     }]>> {
1062   let ParserMatchClass = FPImmOperand;
1063   let PrintMethod = "printFPImmOperand";
1064 }
1065 def fpimm64 : Operand<f64>,
1066               FPImmLeaf<f64, [{
1067       return AArch64_AM::getFP64Imm(Imm) != -1;
1068     }], SDNodeXForm<fpimm, [{
1069       APFloat InVal = N->getValueAPF();
1070       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
1071       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1072     }]>> {
1073   let ParserMatchClass = FPImmOperand;
1074   let PrintMethod = "printFPImmOperand";
1075 }
1076
1077 def fpimm8 : Operand<i32> {
1078   let ParserMatchClass = FPImmOperand;
1079   let PrintMethod = "printFPImmOperand";
1080 }
1081
1082 def fpimm0 : FPImmLeaf<fAny, [{
1083   return Imm.isExactlyValue(+0.0);
1084 }]>;
1085
1086 // Vector lane operands
1087 class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {
1088   let Name = NamePrefix # "IndexRange" # Min # "_" # Max;
1089   let DiagnosticType = "Invalid" # Name;
1090   let PredicateMethod = "isVectorIndex<" # Min # ", " # Max #  ">";
1091   let RenderMethod = "addVectorIndexOperands";
1092 }
1093
1094 class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc, code pred>
1095     : Operand<ty>, ImmLeaf<ty, pred> {
1096   let ParserMatchClass = mc;
1097   let PrintMethod = "printVectorIndex";
1098 }
1099
1100 def VectorIndex1Operand : AsmVectorIndex<1, 1>;
1101 def VectorIndexBOperand : AsmVectorIndex<0, 15>;
1102 def VectorIndexHOperand : AsmVectorIndex<0, 7>;
1103 def VectorIndexSOperand : AsmVectorIndex<0, 3>;
1104 def VectorIndexDOperand : AsmVectorIndex<0, 1>;
1105
1106 def VectorIndex1 : AsmVectorIndexOpnd<i64, VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>;
1107 def VectorIndexB : AsmVectorIndexOpnd<i64, VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>;
1108 def VectorIndexH : AsmVectorIndexOpnd<i64, VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>;
1109 def VectorIndexS : AsmVectorIndexOpnd<i64, VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>;
1110 def VectorIndexD : AsmVectorIndexOpnd<i64, VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>;
1111
1112 def VectorIndex132b : AsmVectorIndexOpnd<i32, VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>;
1113 def VectorIndexB32b : AsmVectorIndexOpnd<i32, VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>;
1114 def VectorIndexH32b : AsmVectorIndexOpnd<i32, VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>;
1115 def VectorIndexS32b : AsmVectorIndexOpnd<i32, VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>;
1116 def VectorIndexD32b : AsmVectorIndexOpnd<i32, VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>;
1117
1118 def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
1119 def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
1120 def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
1121 def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
1122 def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
1123
1124 def sve_elm_idx_extdup_b
1125   : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupBOperand, [{ return ((uint64_t)Imm) < 64; }]>;
1126 def sve_elm_idx_extdup_h
1127   : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupHOperand, [{ return ((uint64_t)Imm) < 32; }]>;
1128 def sve_elm_idx_extdup_s
1129   : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupSOperand, [{ return ((uint64_t)Imm) < 16; }]>;
1130 def sve_elm_idx_extdup_d
1131   : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupDOperand, [{ return ((uint64_t)Imm) < 8; }]>;
1132 def sve_elm_idx_extdup_q
1133   : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupQOperand, [{ return ((uint64_t)Imm) < 4; }]>;
1134
1135 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
1136 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
1137 // are encoded as the eight bit value 'abcdefgh'.
1138 def simdimmtype10 : Operand<i32>,
1139                     FPImmLeaf<f64, [{
1140       return AArch64_AM::isAdvSIMDModImmType10(
1141                  Imm.bitcastToAPInt().getZExtValue());
1142     }], SDNodeXForm<fpimm, [{
1143       APFloat InVal = N->getValueAPF();
1144       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
1145                                                            .bitcastToAPInt()
1146                                                            .getZExtValue());
1147       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1148     }]>> {
1149   let ParserMatchClass = SIMDImmType10Operand;
1150   let PrintMethod = "printSIMDType10Operand";
1151 }
1152
1153
1154 //---
1155 // System management
1156 //---
1157
1158 // Base encoding for system instruction operands.
1159 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
1160 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
1161                   list<dag> pattern = []>
1162     : I<oops, iops, asm, operands, "", pattern> {
1163   let Inst{31-22} = 0b1101010100;
1164   let Inst{21}    = L;
1165 }
1166
1167 // System instructions which do not have an Rt register.
1168 class SimpleSystemI<bit L, dag iops, string asm, string operands,
1169                     list<dag> pattern = []>
1170     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
1171   let Inst{4-0} = 0b11111;
1172 }
1173
1174 // System instructions which have an Rt register.
1175 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
1176     : BaseSystemI<L, oops, iops, asm, operands>,
1177       Sched<[WriteSys]> {
1178   bits<5> Rt;
1179   let Inst{4-0} = Rt;
1180 }
1181
1182 // System instructions for transactional memory extension
1183 class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops,
1184                     string asm, string operands, list<dag> pattern>
1185     : BaseSystemI<L, oops, iops, asm, operands, pattern>,
1186       Sched<[WriteSys]> {
1187   let Inst{20-12} = 0b000110011;
1188   let Inst{11-8} = CRm;
1189   let Inst{7-5} = op2;
1190   let DecoderMethod = "";
1191
1192   let mayLoad = 1;
1193   let mayStore = 1;
1194 }
1195
1196 // System instructions for transactional memory - single input operand
1197 class TMSystemI<bits<4> CRm, string asm, list<dag> pattern>
1198     : TMBaseSystemI<0b1, CRm, 0b011,
1199                     (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> {
1200   bits<5> Rt;
1201   let Inst{4-0} = Rt;
1202 }
1203
1204 // System instructions for transactional memory - no operand
1205 class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern>
1206     : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> {
1207   let Inst{4-0} = 0b11111;
1208 }
1209
1210 // System instructions for exit from transactions
1211 class TMSystemException<bits<3> op1, string asm, list<dag> pattern>
1212     : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>,
1213       Sched<[WriteSys]> {
1214   bits<16> imm;
1215   let Inst{31-24} = 0b11010100;
1216   let Inst{23-21} = op1;
1217   let Inst{20-5}  = imm;
1218   let Inst{4-0}   = 0b00000;
1219 }
1220
1221 // Hint instructions that take both a CRm and a 3-bit immediate.
1222 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
1223 // model patterns with sufficiently fine granularity
1224 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
1225   class HintI<string mnemonic>
1226       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
1227                       [(int_aarch64_hint imm0_127:$imm)]>,
1228         Sched<[WriteHint]> {
1229     bits <7> imm;
1230     let Inst{20-12} = 0b000110010;
1231     let Inst{11-5} = imm;
1232   }
1233
1234 // System instructions taking a single literal operand which encodes into
1235 // CRm. op2 differentiates the opcodes.
1236 def BarrierAsmOperand : AsmOperandClass {
1237   let Name = "Barrier";
1238   let ParserMethod = "tryParseBarrierOperand";
1239 }
1240 def barrier_op : Operand<i32> {
1241   let PrintMethod = "printBarrierOption";
1242   let ParserMatchClass = BarrierAsmOperand;
1243 }
1244 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
1245                  list<dag> pattern = []>
1246     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
1247       Sched<[WriteBarrier]> {
1248   bits<4> CRm;
1249   let Inst{20-12} = 0b000110011;
1250   let Inst{11-8} = CRm;
1251   let Inst{7-5} = opc;
1252 }
1253
1254 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
1255     : SimpleSystemI<0, (ins), asm, "", pattern>,
1256       Sched<[]> {
1257   bits<4> CRm;
1258   let CRm = 0b0011;
1259   let Inst{31-12} = 0b11010101000000110010;
1260   let Inst{11-8} = CRm;
1261   let Inst{7-5} = op2;
1262   let Inst{4-0} = 0b11111;
1263 }
1264
1265 // MRS/MSR system instructions. These have different operand classes because
1266 // a different subset of registers can be accessed through each instruction.
1267 def MRSSystemRegisterOperand : AsmOperandClass {
1268   let Name = "MRSSystemRegister";
1269   let ParserMethod = "tryParseSysReg";
1270   let DiagnosticType = "MRS";
1271 }
1272 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
1273 def mrs_sysreg_op : Operand<i32> {
1274   let ParserMatchClass = MRSSystemRegisterOperand;
1275   let DecoderMethod = "DecodeMRSSystemRegister";
1276   let PrintMethod = "printMRSSystemRegister";
1277 }
1278
1279 def MSRSystemRegisterOperand : AsmOperandClass {
1280   let Name = "MSRSystemRegister";
1281   let ParserMethod = "tryParseSysReg";
1282   let DiagnosticType = "MSR";
1283 }
1284 def msr_sysreg_op : Operand<i32> {
1285   let ParserMatchClass = MSRSystemRegisterOperand;
1286   let DecoderMethod = "DecodeMSRSystemRegister";
1287   let PrintMethod = "printMSRSystemRegister";
1288 }
1289
1290 def PSBHintOperand : AsmOperandClass {
1291   let Name = "PSBHint";
1292   let ParserMethod = "tryParsePSBHint";
1293 }
1294 def psbhint_op : Operand<i32> {
1295   let ParserMatchClass = PSBHintOperand;
1296   let PrintMethod = "printPSBHintOp";
1297   let MCOperandPredicate = [{
1298     // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
1299     // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
1300     if (!MCOp.isImm())
1301       return false;
1302     return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
1303   }];
1304 }
1305
1306 def BTIHintOperand : AsmOperandClass {
1307   let Name = "BTIHint";
1308   let ParserMethod = "tryParseBTIHint";
1309 }
1310 def btihint_op : Operand<i32> {
1311   let ParserMatchClass = BTIHintOperand;
1312   let PrintMethod = "printBTIHintOp";
1313   let MCOperandPredicate = [{
1314     // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.
1315     if (!MCOp.isImm())
1316       return false;
1317     return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr;
1318   }];
1319 }
1320
1321 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
1322                        "mrs", "\t$Rt, $systemreg"> {
1323   bits<16> systemreg;
1324   let Inst{20-5} = systemreg;
1325 }
1326
1327 // FIXME: Some of these def NZCV, others don't. Best way to model that?
1328 // Explicitly modeling each of the system register as a register class
1329 // would do it, but feels like overkill at this point.
1330 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
1331                        "msr", "\t$systemreg, $Rt"> {
1332   bits<16> systemreg;
1333   let Inst{20-5} = systemreg;
1334 }
1335
1336 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
1337   let Name = "SystemPStateFieldWithImm0_15";
1338   let ParserMethod = "tryParseSysReg";
1339 }
1340 def pstatefield4_op : Operand<i32> {
1341   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
1342   let PrintMethod = "printSystemPStateField";
1343 }
1344
1345 // Instructions to modify PSTATE, no input reg
1346 let Defs = [NZCV] in
1347 class PstateWriteSimple<dag iops, string asm, string operands>
1348   : SimpleSystemI<0, iops, asm, operands> {
1349
1350   let Inst{20-19} = 0b00;
1351   let Inst{15-12} = 0b0100;
1352 }
1353
1354 class MSRpstateImm0_15
1355   : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr",
1356                   "\t$pstatefield, $imm">,
1357     Sched<[WriteSys]> {
1358
1359   bits<6> pstatefield;
1360   bits<4> imm;
1361   let Inst{18-16} = pstatefield{5-3};
1362   let Inst{11-8} = imm;
1363   let Inst{7-5} = pstatefield{2-0};
1364
1365   let DecoderMethod = "DecodeSystemPStateInstruction";
1366   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1367   // Fail the decoder should attempt to decode the instruction as MSRI.
1368   let hasCompleteDecoder = 0;
1369 }
1370
1371 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1372   let Name = "SystemPStateFieldWithImm0_1";
1373   let ParserMethod = "tryParseSysReg";
1374 }
1375 def pstatefield1_op : Operand<i32> {
1376   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1377   let PrintMethod = "printSystemPStateField";
1378 }
1379
1380 class MSRpstateImm0_1
1381   : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",
1382                  "\t$pstatefield, $imm">,
1383     Sched<[WriteSys]> {
1384
1385   bits<6> pstatefield;
1386   bit imm;
1387   let Inst{18-16} = pstatefield{5-3};
1388   let Inst{11-9} = 0b000;
1389   let Inst{8} = imm;
1390   let Inst{7-5} = pstatefield{2-0};
1391
1392   let DecoderMethod = "DecodeSystemPStateInstruction";
1393   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1394   // Fail the decoder should attempt to decode the instruction as MSRI.
1395   let hasCompleteDecoder = 0;
1396 }
1397
1398 // SYS and SYSL generic system instructions.
1399 def SysCRAsmOperand : AsmOperandClass {
1400   let Name = "SysCR";
1401   let ParserMethod = "tryParseSysCROperand";
1402 }
1403
1404 def sys_cr_op : Operand<i32> {
1405   let PrintMethod = "printSysCROperand";
1406   let ParserMatchClass = SysCRAsmOperand;
1407 }
1408
1409 class SystemXtI<bit L, string asm>
1410   : RtSystemI<L, (outs),
1411        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1412        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1413   bits<3> op1;
1414   bits<4> Cn;
1415   bits<4> Cm;
1416   bits<3> op2;
1417   let Inst{20-19} = 0b01;
1418   let Inst{18-16} = op1;
1419   let Inst{15-12} = Cn;
1420   let Inst{11-8}  = Cm;
1421   let Inst{7-5}   = op2;
1422 }
1423
1424 class SystemLXtI<bit L, string asm>
1425   : RtSystemI<L, (outs),
1426        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1427        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1428   bits<3> op1;
1429   bits<4> Cn;
1430   bits<4> Cm;
1431   bits<3> op2;
1432   let Inst{20-19} = 0b01;
1433   let Inst{18-16} = op1;
1434   let Inst{15-12} = Cn;
1435   let Inst{11-8}  = Cm;
1436   let Inst{7-5}   = op2;
1437 }
1438
1439
1440 // Branch (register) instructions:
1441 //
1442 //  case opc of
1443 //    0001 blr
1444 //    0000 br
1445 //    0101 dret
1446 //    0100 eret
1447 //    0010 ret
1448 //    otherwise UNDEFINED
1449 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1450                     string operands, list<dag> pattern>
1451     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1452   let Inst{31-25} = 0b1101011;
1453   let Inst{24-21} = opc;
1454   let Inst{20-16} = 0b11111;
1455   let Inst{15-10} = 0b000000;
1456   let Inst{4-0}   = 0b00000;
1457 }
1458
1459 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1460     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1461   bits<5> Rn;
1462   let Inst{9-5} = Rn;
1463 }
1464
1465 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1466 class SpecialReturn<bits<4> opc, string asm>
1467     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1468   let Inst{9-5} = 0b11111;
1469 }
1470
1471 let mayLoad = 1 in
1472 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
1473   : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
1474   Sched<[]> {
1475   bits<5> Rn;
1476   bits<5> Rt;
1477   let Inst{31-30} = sz;
1478   let Inst{29-10} = 0b11100010111111110000;
1479   let Inst{9-5} = Rn;
1480   let Inst{4-0} = Rt;
1481 }
1482
1483 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
1484                list<dag> pattern>
1485   : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
1486   let isAuthenticated = 1;
1487   let Inst{31-25} = 0b1101011;
1488   let Inst{20-11} = 0b1111100001;
1489   let Inst{10} = M;
1490   let Inst{4-0} = 0b11111;
1491 }
1492
1493 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
1494   : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
1495   bits<5> Rn;
1496   bits<5> Rm;
1497   let Inst{24-22} = 0b100;
1498   let Inst{21} = op;
1499   let Inst{9-5} = Rn;
1500   let Inst{4-0} = Rm;
1501 }
1502
1503 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
1504   : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
1505   bits<5> Rn;
1506   let Inst{24} = 0;
1507   let Inst{23-21} = opc;
1508   let Inst{9-5} = Rn;
1509 }
1510
1511 let Uses = [LR,SP] in
1512 class AuthReturn<bits<3> op, bits<1> M, string asm>
1513   : AuthBase<M, (outs), (ins), asm, "", []> {
1514   let Inst{24} = 0;
1515   let Inst{23-21} = op;
1516   let Inst{9-0} = 0b1111111111;
1517 }
1518
1519 let mayLoad = 1 in
1520 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
1521                    string operands, string cstr, Operand opr>
1522   : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
1523   bits<10> offset;
1524   bits<5> Rn;
1525   bits<5> Rt;
1526   let isAuthenticated = 1;
1527   let Inst{31-24} = 0b11111000;
1528   let Inst{23} = M;
1529   let Inst{22} = offset{9};
1530   let Inst{21} = 1;
1531   let Inst{20-12} = offset{8-0};
1532   let Inst{11} = W;
1533   let Inst{10} = 1;
1534   let Inst{9-5} = Rn;
1535   let Inst{4-0} = Rt;
1536 }
1537
1538 multiclass AuthLoad<bit M, string asm, Operand opr> {
1539   def indexed   : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
1540                                (ins GPR64sp:$Rn, opr:$offset),
1541                                asm, "\t$Rt, [$Rn, $offset]", "", opr>;
1542   def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
1543                                (ins GPR64sp:$Rn, opr:$offset),
1544                                asm, "\t$Rt, [$Rn, $offset]!",
1545                                "$Rn = $wback,@earlyclobber $wback", opr>;
1546
1547   def : InstAlias<asm # "\t$Rt, [$Rn]",
1548                   (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
1549
1550   def : InstAlias<asm # "\t$Rt, [$wback]!",
1551                   (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>;
1552 }
1553
1554 //---
1555 // Conditional branch instruction.
1556 //---
1557
1558 // Condition code.
1559 // 4-bit immediate. Pretty-printed as <cc>
1560 def ccode : Operand<i32> {
1561   let PrintMethod = "printCondCode";
1562   let ParserMatchClass = CondCode;
1563 }
1564 def inv_ccode : Operand<i32> {
1565   // AL and NV are invalid in the aliases which use inv_ccode
1566   let PrintMethod = "printInverseCondCode";
1567   let ParserMatchClass = CondCode;
1568   let MCOperandPredicate = [{
1569     return MCOp.isImm() &&
1570            MCOp.getImm() != AArch64CC::AL &&
1571            MCOp.getImm() != AArch64CC::NV;
1572   }];
1573 }
1574
1575 // Conditional branch target. 19-bit immediate. The low two bits of the target
1576 // offset are implied zero and so are not part of the immediate.
1577 def am_brcond : Operand<OtherVT> {
1578   let EncoderMethod = "getCondBranchTargetOpValue";
1579   let DecoderMethod = "DecodePCRelLabel19";
1580   let PrintMethod = "printAlignedLabel";
1581   let ParserMatchClass = PCRelLabel19Operand;
1582   let OperandType = "OPERAND_PCREL";
1583 }
1584
1585 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1586                      "b", ".$cond\t$target", "",
1587                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1588                    Sched<[WriteBr]> {
1589   let isBranch = 1;
1590   let isTerminator = 1;
1591   let Uses = [NZCV];
1592
1593   bits<4> cond;
1594   bits<19> target;
1595   let Inst{31-24} = 0b01010100;
1596   let Inst{23-5} = target;
1597   let Inst{4} = 0;
1598   let Inst{3-0} = cond;
1599 }
1600
1601 //---
1602 // Compare-and-branch instructions.
1603 //---
1604 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1605     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1606          asm, "\t$Rt, $target", "",
1607          [(node regtype:$Rt, bb:$target)]>,
1608       Sched<[WriteBr]> {
1609   let isBranch = 1;
1610   let isTerminator = 1;
1611
1612   bits<5> Rt;
1613   bits<19> target;
1614   let Inst{30-25} = 0b011010;
1615   let Inst{24}    = op;
1616   let Inst{23-5}  = target;
1617   let Inst{4-0}   = Rt;
1618 }
1619
1620 multiclass CmpBranch<bit op, string asm, SDNode node> {
1621   def W : BaseCmpBranch<GPR32, op, asm, node> {
1622     let Inst{31} = 0;
1623   }
1624   def X : BaseCmpBranch<GPR64, op, asm, node> {
1625     let Inst{31} = 1;
1626   }
1627 }
1628
1629 //---
1630 // Test-bit-and-branch instructions.
1631 //---
1632 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1633 // the target offset are implied zero and so are not part of the immediate.
1634 def am_tbrcond : Operand<OtherVT> {
1635   let EncoderMethod = "getTestBranchTargetOpValue";
1636   let PrintMethod = "printAlignedLabel";
1637   let ParserMatchClass = BranchTarget14Operand;
1638   let OperandType = "OPERAND_PCREL";
1639 }
1640
1641 // AsmOperand classes to emit (or not) special diagnostics
1642 def TBZImm0_31Operand : AsmOperandClass {
1643   let Name = "TBZImm0_31";
1644   let PredicateMethod = "isImmInRange<0,31>";
1645   let RenderMethod = "addImmOperands";
1646 }
1647 def TBZImm32_63Operand : AsmOperandClass {
1648   let Name = "Imm32_63";
1649   let PredicateMethod = "isImmInRange<32,63>";
1650   let DiagnosticType = "InvalidImm0_63";
1651   let RenderMethod = "addImmOperands";
1652 }
1653
1654 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1655   return (((uint32_t)Imm) < 32);
1656 }]> {
1657   let ParserMatchClass = matcher;
1658 }
1659
1660 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1661 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1662
1663 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1664   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1665 }]> {
1666   let ParserMatchClass = TBZImm32_63Operand;
1667 }
1668
1669 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1670                      bit op, string asm, SDNode node>
1671     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1672        asm, "\t$Rt, $bit_off, $target", "",
1673        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1674       Sched<[WriteBr]> {
1675   let isBranch = 1;
1676   let isTerminator = 1;
1677
1678   bits<5> Rt;
1679   bits<6> bit_off;
1680   bits<14> target;
1681
1682   let Inst{30-25} = 0b011011;
1683   let Inst{24}    = op;
1684   let Inst{23-19} = bit_off{4-0};
1685   let Inst{18-5}  = target;
1686   let Inst{4-0}   = Rt;
1687
1688   let DecoderMethod = "DecodeTestAndBranch";
1689 }
1690
1691 multiclass TestBranch<bit op, string asm, SDNode node> {
1692   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1693     let Inst{31} = 0;
1694   }
1695
1696   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1697     let Inst{31} = 1;
1698   }
1699
1700   // Alias X-reg with 0-31 imm to W-Reg.
1701   def : InstAlias<asm # "\t$Rd, $imm, $target",
1702                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1703                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1704   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1705             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1706             tbz_imm0_31_diag:$imm, bb:$target)>;
1707 }
1708
1709 //---
1710 // Unconditional branch (immediate) instructions.
1711 //---
1712 def am_b_target : Operand<OtherVT> {
1713   let EncoderMethod = "getBranchTargetOpValue";
1714   let PrintMethod = "printAlignedLabel";
1715   let ParserMatchClass = BranchTarget26Operand;
1716   let OperandType = "OPERAND_PCREL";
1717 }
1718 def am_bl_target : Operand<i64> {
1719   let EncoderMethod = "getBranchTargetOpValue";
1720   let PrintMethod = "printAlignedLabel";
1721   let ParserMatchClass = BranchTarget26Operand;
1722   let OperandType = "OPERAND_PCREL";
1723 }
1724
1725 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1726     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1727   bits<26> addr;
1728   let Inst{31}    = op;
1729   let Inst{30-26} = 0b00101;
1730   let Inst{25-0}  = addr;
1731
1732   let DecoderMethod = "DecodeUnconditionalBranch";
1733 }
1734
1735 class BranchImm<bit op, string asm, list<dag> pattern>
1736     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1737 class CallImm<bit op, string asm, list<dag> pattern>
1738     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1739
1740 //---
1741 // Basic one-operand data processing instructions.
1742 //---
1743
1744 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1745 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1746                          SDPatternOperator node>
1747   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1748       [(set regtype:$Rd, (node regtype:$Rn))]>,
1749     Sched<[WriteI, ReadI]> {
1750   bits<5> Rd;
1751   bits<5> Rn;
1752
1753   let Inst{30-13} = 0b101101011000000000;
1754   let Inst{12-10} = opc;
1755   let Inst{9-5}   = Rn;
1756   let Inst{4-0}   = Rd;
1757 }
1758
1759 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1760 multiclass OneOperandData<bits<3> opc, string asm,
1761                           SDPatternOperator node = null_frag> {
1762   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1763     let Inst{31} = 0;
1764   }
1765
1766   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1767     let Inst{31} = 1;
1768   }
1769 }
1770
1771 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1772     : BaseOneOperandData<opc, GPR32, asm, node> {
1773   let Inst{31} = 0;
1774 }
1775
1776 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1777     : BaseOneOperandData<opc, GPR64, asm, node> {
1778   let Inst{31} = 1;
1779 }
1780
1781 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
1782   : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "",
1783       []>,
1784     Sched<[WriteI, ReadI]> {
1785   bits<5> Rd;
1786   bits<5> Rn;
1787   let Inst{31-15} = 0b11011010110000010;
1788   let Inst{14-12} = opcode_prefix;
1789   let Inst{11-10} = opcode;
1790   let Inst{9-5} = Rn;
1791   let Inst{4-0} = Rd;
1792 }
1793
1794 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
1795   : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> {
1796   bits<5> Rd;
1797   let Inst{31-15} = 0b11011010110000010;
1798   let Inst{14-12} = opcode_prefix;
1799   let Inst{11-10} = opcode;
1800   let Inst{9-5} = 0b11111;
1801   let Inst{4-0} = Rd;
1802 }
1803
1804 class SignAuthTwoOperand<bits<4> opc, string asm,
1805                          SDPatternOperator OpNode>
1806   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
1807       asm, "\t$Rd, $Rn, $Rm", "",
1808       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
1809     Sched<[WriteI, ReadI, ReadI]> {
1810   bits<5> Rd;
1811   bits<5> Rn;
1812   bits<5> Rm;
1813   let Inst{31-21} = 0b10011010110;
1814   let Inst{20-16} = Rm;
1815   let Inst{15-14} = 0b00;
1816   let Inst{13-10} = opc;
1817   let Inst{9-5}   = Rn;
1818   let Inst{4-0}   = Rd;
1819 }
1820
1821 // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
1822 class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
1823     : I<(outs), iops, asm, ops, "", []>,
1824       Sched<[WriteI, ReadI, ReadI]> {
1825   let Uses = [NZCV];
1826   bits<5> Rn;
1827   let Inst{31}    = sf;
1828   let Inst{30-15} = 0b0111010000000000;
1829   let Inst{14}    = sz;
1830   let Inst{13-10} = 0b0010;
1831   let Inst{9-5}   = Rn;
1832   let Inst{4-0}   = 0b01101;
1833 }
1834
1835 class FlagRotate<dag iops, string asm, string ops>
1836     : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
1837   bits<6> imm;
1838   bits<4> mask;
1839   let Inst{20-15} = imm;
1840   let Inst{13-10} = 0b0001;
1841   let Inst{4}     = 0b0;
1842   let Inst{3-0}   = mask;
1843 }
1844
1845 //---
1846 // Basic two-operand data processing instructions.
1847 //---
1848 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1849                           list<dag> pattern>
1850     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1851         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1852       Sched<[WriteI, ReadI, ReadI]> {
1853   let Uses = [NZCV];
1854   bits<5> Rd;
1855   bits<5> Rn;
1856   bits<5> Rm;
1857   let Inst{30}    = isSub;
1858   let Inst{28-21} = 0b11010000;
1859   let Inst{20-16} = Rm;
1860   let Inst{15-10} = 0;
1861   let Inst{9-5}   = Rn;
1862   let Inst{4-0}   = Rd;
1863 }
1864
1865 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1866                       SDNode OpNode>
1867     : BaseBaseAddSubCarry<isSub, regtype, asm,
1868         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1869
1870 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1871                               SDNode OpNode>
1872     : BaseBaseAddSubCarry<isSub, regtype, asm,
1873         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1874          (implicit NZCV)]> {
1875   let Defs = [NZCV];
1876 }
1877
1878 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1879                        SDNode OpNode, SDNode OpNode_setflags> {
1880   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1881     let Inst{31} = 0;
1882     let Inst{29} = 0;
1883   }
1884   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1885     let Inst{31} = 1;
1886     let Inst{29} = 0;
1887   }
1888
1889   // Sets flags.
1890   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1891                                     OpNode_setflags> {
1892     let Inst{31} = 0;
1893     let Inst{29} = 1;
1894   }
1895   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1896                                     OpNode_setflags> {
1897     let Inst{31} = 1;
1898     let Inst{29} = 1;
1899   }
1900 }
1901
1902 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1903                      SDPatternOperator OpNode,
1904                      RegisterClass in1regtype = regtype,
1905                      RegisterClass in2regtype = regtype>
1906   : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm),
1907       asm, "\t$Rd, $Rn, $Rm", "",
1908       [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> {
1909   bits<5> Rd;
1910   bits<5> Rn;
1911   bits<5> Rm;
1912   let Inst{30-21} = 0b0011010110;
1913   let Inst{20-16} = Rm;
1914   let Inst{15-14} = 0b00;
1915   let Inst{13-10} = opc;
1916   let Inst{9-5}   = Rn;
1917   let Inst{4-0}   = Rd;
1918 }
1919
1920 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1921               SDPatternOperator OpNode>
1922     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1923   let Inst{10}    = isSigned;
1924 }
1925
1926 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1927   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1928            Sched<[WriteID32, ReadID, ReadID]> {
1929     let Inst{31} = 0;
1930   }
1931   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1932            Sched<[WriteID64, ReadID, ReadID]> {
1933     let Inst{31} = 1;
1934   }
1935 }
1936
1937 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1938                 SDPatternOperator OpNode = null_frag>
1939   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1940     Sched<[WriteIS, ReadI]> {
1941   let Inst{11-10} = shift_type;
1942 }
1943
1944 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1945   def Wr : BaseShift<shift_type, GPR32, asm> {
1946     let Inst{31} = 0;
1947   }
1948
1949   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1950     let Inst{31} = 1;
1951   }
1952
1953   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1954             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1955                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1956
1957   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1958             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1959
1960   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1961             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1962
1963   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1964             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1965
1966   def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))),
1967             (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
1968                 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
1969
1970   def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))),
1971             (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
1972                 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
1973 }
1974
1975 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1976     : InstAlias<asm#"\t$dst, $src1, $src2",
1977                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1978
1979 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1980                        RegisterClass addtype, string asm,
1981                        list<dag> pattern>
1982   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1983       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1984   bits<5> Rd;
1985   bits<5> Rn;
1986   bits<5> Rm;
1987   bits<5> Ra;
1988   let Inst{30-24} = 0b0011011;
1989   let Inst{23-21} = opc;
1990   let Inst{20-16} = Rm;
1991   let Inst{15}    = isSub;
1992   let Inst{14-10} = Ra;
1993   let Inst{9-5}   = Rn;
1994   let Inst{4-0}   = Rd;
1995 }
1996
1997 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1998   // MADD/MSUB generation is decided by MachineCombiner.cpp
1999   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
2000       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
2001       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2002     let Inst{31} = 0;
2003   }
2004
2005   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
2006       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
2007       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
2008     let Inst{31} = 1;
2009   }
2010 }
2011
2012 class WideMulAccum<bit isSub, bits<3> opc, string asm,
2013                    SDNode AccNode, SDNode ExtNode>
2014   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
2015     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
2016                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
2017     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2018   let Inst{31} = 1;
2019 }
2020
2021 class MulHi<bits<3> opc, string asm, SDNode OpNode>
2022   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
2023       asm, "\t$Rd, $Rn, $Rm", "",
2024       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
2025     Sched<[WriteIM64, ReadIM, ReadIM]> {
2026   bits<5> Rd;
2027   bits<5> Rn;
2028   bits<5> Rm;
2029   let Inst{31-24} = 0b10011011;
2030   let Inst{23-21} = opc;
2031   let Inst{20-16} = Rm;
2032   let Inst{15}    = 0;
2033   let Inst{9-5}   = Rn;
2034   let Inst{4-0}   = Rd;
2035
2036   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
2037   // (i.e. all bits 1) but is ignored by the processor.
2038   let PostEncoderMethod = "fixMulHigh";
2039 }
2040
2041 class MulAccumWAlias<string asm, Instruction inst>
2042     : InstAlias<asm#"\t$dst, $src1, $src2",
2043                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
2044 class MulAccumXAlias<string asm, Instruction inst>
2045     : InstAlias<asm#"\t$dst, $src1, $src2",
2046                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
2047 class WideMulAccumAlias<string asm, Instruction inst>
2048     : InstAlias<asm#"\t$dst, $src1, $src2",
2049                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
2050
2051 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
2052               SDPatternOperator OpNode, string asm>
2053   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
2054       asm, "\t$Rd, $Rn, $Rm", "",
2055       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
2056     Sched<[WriteISReg, ReadI, ReadISReg]> {
2057   bits<5> Rd;
2058   bits<5> Rn;
2059   bits<5> Rm;
2060
2061   let Inst{31} = sf;
2062   let Inst{30-21} = 0b0011010110;
2063   let Inst{20-16} = Rm;
2064   let Inst{15-13} = 0b010;
2065   let Inst{12} = C;
2066   let Inst{11-10} = sz;
2067   let Inst{9-5} = Rn;
2068   let Inst{4-0} = Rd;
2069   let Predicates = [HasCRC];
2070 }
2071
2072 //---
2073 // Address generation.
2074 //---
2075
2076 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
2077     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
2078         pattern>,
2079       Sched<[WriteI]> {
2080   bits<5>  Xd;
2081   bits<21> label;
2082   let Inst{31}    = page;
2083   let Inst{30-29} = label{1-0};
2084   let Inst{28-24} = 0b10000;
2085   let Inst{23-5}  = label{20-2};
2086   let Inst{4-0}   = Xd;
2087
2088   let DecoderMethod = "DecodeAdrInstruction";
2089 }
2090
2091 //---
2092 // Move immediate.
2093 //---
2094
2095 def movimm32_imm : Operand<i32> {
2096   let ParserMatchClass = AsmImmRange<0, 65535>;
2097   let EncoderMethod = "getMoveWideImmOpValue";
2098   let PrintMethod = "printImm";
2099 }
2100 def movimm32_shift : Operand<i32> {
2101   let PrintMethod = "printShifter";
2102   let ParserMatchClass = MovImm32ShifterOperand;
2103 }
2104 def movimm64_shift : Operand<i32> {
2105   let PrintMethod = "printShifter";
2106   let ParserMatchClass = MovImm64ShifterOperand;
2107 }
2108
2109 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2110 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2111                         string asm>
2112   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
2113        asm, "\t$Rd, $imm$shift", "", []>,
2114     Sched<[WriteImm]> {
2115   bits<5> Rd;
2116   bits<16> imm;
2117   bits<6> shift;
2118   let Inst{30-29} = opc;
2119   let Inst{28-23} = 0b100101;
2120   let Inst{22-21} = shift{5-4};
2121   let Inst{20-5}  = imm;
2122   let Inst{4-0}   = Rd;
2123
2124   let DecoderMethod = "DecodeMoveImmInstruction";
2125 }
2126
2127 multiclass MoveImmediate<bits<2> opc, string asm> {
2128   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
2129     let Inst{31} = 0;
2130   }
2131
2132   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
2133     let Inst{31} = 1;
2134   }
2135 }
2136
2137 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2138 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2139                           string asm>
2140   : I<(outs regtype:$Rd),
2141       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
2142        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
2143     Sched<[WriteI, ReadI]> {
2144   bits<5> Rd;
2145   bits<16> imm;
2146   bits<6> shift;
2147   let Inst{30-29} = opc;
2148   let Inst{28-23} = 0b100101;
2149   let Inst{22-21} = shift{5-4};
2150   let Inst{20-5}  = imm;
2151   let Inst{4-0}   = Rd;
2152
2153   let DecoderMethod = "DecodeMoveImmInstruction";
2154 }
2155
2156 multiclass InsertImmediate<bits<2> opc, string asm> {
2157   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
2158     let Inst{31} = 0;
2159   }
2160
2161   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
2162     let Inst{31} = 1;
2163   }
2164 }
2165
2166 //---
2167 // Add/Subtract
2168 //---
2169
2170 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
2171                     string asm_inst, string asm_ops,
2172                     dag inputs, dag pattern>
2173     : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>,
2174       Sched<[WriteI, ReadI]> {
2175   bits<5>  Rd;
2176   bits<5>  Rn;
2177   let Inst{30}    = isSub;
2178   let Inst{29}    = setFlags;
2179   let Inst{28-24} = 0b10001;
2180   let Inst{9-5}   = Rn;
2181   let Inst{4-0}   = Rd;
2182 }
2183
2184 class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype,
2185                      RegisterClass srcRegtype, addsub_shifted_imm immtype,
2186                      string asm_inst, SDPatternOperator OpNode>
2187     : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm",
2188                     (ins srcRegtype:$Rn, immtype:$imm),
2189                     (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> {
2190   bits<14> imm;
2191   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
2192   let Inst{21-10} = imm{11-0};
2193   let DecoderMethod = "DecodeAddSubImmShift";
2194 }
2195
2196 class BaseAddSubRegPseudo<RegisterClass regtype,
2197                           SDPatternOperator OpNode>
2198     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2199              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2200       Sched<[WriteI, ReadI, ReadI]>;
2201
2202 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
2203                      arith_shifted_reg shifted_regtype, string asm,
2204                      SDPatternOperator OpNode>
2205     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2206         asm, "\t$Rd, $Rn, $Rm", "",
2207         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
2208       Sched<[WriteISReg, ReadI, ReadISReg]> {
2209   // The operands are in order to match the 'addr' MI operands, so we
2210   // don't need an encoder method and by-name matching. Just use the default
2211   // in-order handling. Since we're using by-order, make sure the names
2212   // do not match.
2213   bits<5> dst;
2214   bits<5> src1;
2215   bits<5> src2;
2216   bits<8> shift;
2217   let Inst{30}    = isSub;
2218   let Inst{29}    = setFlags;
2219   let Inst{28-24} = 0b01011;
2220   let Inst{23-22} = shift{7-6};
2221   let Inst{21}    = 0;
2222   let Inst{20-16} = src2;
2223   let Inst{15-10} = shift{5-0};
2224   let Inst{9-5}   = src1;
2225   let Inst{4-0}   = dst;
2226
2227   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2228 }
2229
2230 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
2231                      RegisterClass src1Regtype, Operand src2Regtype,
2232                      string asm, SDPatternOperator OpNode>
2233     : I<(outs dstRegtype:$R1),
2234         (ins src1Regtype:$R2, src2Regtype:$R3),
2235         asm, "\t$R1, $R2, $R3", "",
2236         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
2237       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2238   bits<5> Rd;
2239   bits<5> Rn;
2240   bits<5> Rm;
2241   bits<6> ext;
2242   let Inst{30}    = isSub;
2243   let Inst{29}    = setFlags;
2244   let Inst{28-24} = 0b01011;
2245   let Inst{23-21} = 0b001;
2246   let Inst{20-16} = Rm;
2247   let Inst{15-13} = ext{5-3};
2248   let Inst{12-10} = ext{2-0};
2249   let Inst{9-5}   = Rn;
2250   let Inst{4-0}   = Rd;
2251
2252   let DecoderMethod = "DecodeAddSubERegInstruction";
2253 }
2254
2255 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2256 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
2257                        RegisterClass src1Regtype, RegisterClass src2Regtype,
2258                        Operand ext_op, string asm>
2259     : I<(outs dstRegtype:$Rd),
2260         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
2261         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
2262       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2263   bits<5> Rd;
2264   bits<5> Rn;
2265   bits<5> Rm;
2266   bits<6> ext;
2267   let Inst{30}    = isSub;
2268   let Inst{29}    = setFlags;
2269   let Inst{28-24} = 0b01011;
2270   let Inst{23-21} = 0b001;
2271   let Inst{20-16} = Rm;
2272   let Inst{15}    = ext{5};
2273   let Inst{12-10} = ext{2-0};
2274   let Inst{9-5}   = Rn;
2275   let Inst{4-0}   = Rd;
2276
2277   let DecoderMethod = "DecodeAddSubERegInstruction";
2278 }
2279
2280 // Aliases for register+register add/subtract.
2281 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
2282                      RegisterClass src1Regtype, RegisterClass src2Regtype,
2283                      int shiftExt>
2284     : InstAlias<asm#"\t$dst, $src1, $src2",
2285                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
2286                       shiftExt)>;
2287
2288 multiclass AddSub<bit isSub, string mnemonic, string alias,
2289                   SDPatternOperator OpNode = null_frag> {
2290   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2291   // Add/Subtract immediate
2292   // Increase the weight of the immediate variant to try to match it before
2293   // the extended register variant.
2294   // We used to match the register variant before the immediate when the
2295   // register argument could be implicitly zero-extended.
2296   let AddedComplexity = 6 in
2297   def Wri  : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
2298                            mnemonic, OpNode> {
2299     let Inst{31} = 0;
2300   }
2301   let AddedComplexity = 6 in
2302   def Xri  : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
2303                            mnemonic, OpNode> {
2304     let Inst{31} = 1;
2305   }
2306
2307   // Add/Subtract register - Only used for CodeGen
2308   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2309   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2310
2311   // Add/Subtract shifted register
2312   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
2313                            OpNode> {
2314     let Inst{31} = 0;
2315   }
2316   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
2317                            OpNode> {
2318     let Inst{31} = 1;
2319   }
2320   }
2321
2322   // Add/Subtract extended register
2323   let AddedComplexity = 1, hasSideEffects = 0 in {
2324   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
2325                            arith_extended_reg32_i32, mnemonic, OpNode> {
2326     let Inst{31} = 0;
2327   }
2328   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
2329                            arith_extended_reg32to64_i64, mnemonic, OpNode> {
2330     let Inst{31} = 1;
2331   }
2332   }
2333
2334   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
2335                                arith_extendlsl64, mnemonic> {
2336     // UXTX and SXTX only.
2337     let Inst{14-13} = 0b11;
2338     let Inst{31} = 1;
2339   }
2340
2341   // add Rd, Rb, -imm -> sub Rd, Rn, imm
2342   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2343                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
2344                       addsub_shifted_imm32_neg:$imm), 0>;
2345   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2346                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
2347                        addsub_shifted_imm64_neg:$imm), 0>;
2348
2349   // Register/register aliases with no shift when SP is not used.
2350   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2351                        GPR32, GPR32, GPR32, 0>;
2352   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2353                        GPR64, GPR64, GPR64, 0>;
2354
2355   // Register/register aliases with no shift when either the destination or
2356   // first source register is SP.
2357   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2358                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
2359   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2360                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
2361   def : AddSubRegAlias<mnemonic,
2362                        !cast<Instruction>(NAME#"Xrx64"),
2363                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
2364   def : AddSubRegAlias<mnemonic,
2365                        !cast<Instruction>(NAME#"Xrx64"),
2366                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
2367 }
2368
2369 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
2370                    string alias, string cmpAlias> {
2371   let isCompare = 1, Defs = [NZCV] in {
2372   // Add/Subtract immediate
2373   def Wri  : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
2374                            mnemonic, OpNode> {
2375     let Inst{31} = 0;
2376   }
2377   def Xri  : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
2378                            mnemonic, OpNode> {
2379     let Inst{31} = 1;
2380   }
2381
2382   // Add/Subtract register
2383   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2384   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2385
2386   // Add/Subtract shifted register
2387   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
2388                            OpNode> {
2389     let Inst{31} = 0;
2390   }
2391   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
2392                            OpNode> {
2393     let Inst{31} = 1;
2394   }
2395
2396   // Add/Subtract extended register
2397   let AddedComplexity = 1 in {
2398   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
2399                            arith_extended_reg32_i32, mnemonic, OpNode> {
2400     let Inst{31} = 0;
2401   }
2402   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
2403                            arith_extended_reg32_i64, mnemonic, OpNode> {
2404     let Inst{31} = 1;
2405   }
2406   }
2407
2408   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
2409                                arith_extendlsl64, mnemonic> {
2410     // UXTX and SXTX only.
2411     let Inst{14-13} = 0b11;
2412     let Inst{31} = 1;
2413   }
2414   } // Defs = [NZCV]
2415
2416   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
2417   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2418                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
2419                       addsub_shifted_imm32_neg:$imm), 0>;
2420   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2421                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
2422                        addsub_shifted_imm64_neg:$imm), 0>;
2423
2424   // Compare aliases
2425   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2426                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
2427   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2428                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
2429   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
2430                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2431   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
2432                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2433   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
2434                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
2435   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
2436                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
2437   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
2438                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
2439
2440   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
2441   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2442                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
2443   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2444                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
2445
2446   // Compare shorthands
2447   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
2448                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
2449   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
2450                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
2451   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
2452                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
2453   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
2454                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
2455
2456   // Register/register aliases with no shift when SP is not used.
2457   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2458                        GPR32, GPR32, GPR32, 0>;
2459   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2460                        GPR64, GPR64, GPR64, 0>;
2461
2462   // Register/register aliases with no shift when the first source register
2463   // is SP.
2464   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2465                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
2466   def : AddSubRegAlias<mnemonic,
2467                        !cast<Instruction>(NAME#"Xrx64"),
2468                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
2469 }
2470
2471 class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode>
2472       : BaseAddSubImm<
2473           isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4",
2474           (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4),
2475           (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> {
2476   bits<6> imm6;
2477   bits<4> imm4;
2478   let Inst{31} = 1;
2479   let Inst{23-22} = 0b10;
2480   let Inst{21-16} = imm6;
2481   let Inst{15-14} = 0b00;
2482   let Inst{13-10} = imm4;
2483   let Unpredictable{15-14} = 0b11;
2484 }
2485
2486 class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode>
2487       : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> {
2488   let Inst{31} = 1;
2489   let Inst{29} = setsFlags;
2490 }
2491
2492 //---
2493 // Extract
2494 //---
2495 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2496                                       SDTCisPtrTy<3>]>;
2497 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
2498
2499 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
2500                      list<dag> patterns>
2501     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
2502          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
2503       Sched<[WriteExtr, ReadExtrHi]> {
2504   bits<5> Rd;
2505   bits<5> Rn;
2506   bits<5> Rm;
2507   bits<6> imm;
2508
2509   let Inst{30-23} = 0b00100111;
2510   let Inst{21}    = 0;
2511   let Inst{20-16} = Rm;
2512   let Inst{15-10} = imm;
2513   let Inst{9-5}   = Rn;
2514   let Inst{4-0}   = Rd;
2515 }
2516
2517 multiclass ExtractImm<string asm> {
2518   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
2519                       [(set GPR32:$Rd,
2520                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
2521     let Inst{31} = 0;
2522     let Inst{22} = 0;
2523     // imm<5> must be zero.
2524     let imm{5}   = 0;
2525   }
2526   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
2527                       [(set GPR64:$Rd,
2528                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
2529
2530     let Inst{31} = 1;
2531     let Inst{22} = 1;
2532   }
2533 }
2534
2535 //---
2536 // Bitfield
2537 //---
2538
2539 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2540 class BaseBitfieldImm<bits<2> opc,
2541                       RegisterClass regtype, Operand imm_type, string asm>
2542     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
2543          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
2544       Sched<[WriteIS, ReadI]> {
2545   bits<5> Rd;
2546   bits<5> Rn;
2547   bits<6> immr;
2548   bits<6> imms;
2549
2550   let Inst{30-29} = opc;
2551   let Inst{28-23} = 0b100110;
2552   let Inst{21-16} = immr;
2553   let Inst{15-10} = imms;
2554   let Inst{9-5}   = Rn;
2555   let Inst{4-0}   = Rd;
2556 }
2557
2558 multiclass BitfieldImm<bits<2> opc, string asm> {
2559   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2560     let Inst{31} = 0;
2561     let Inst{22} = 0;
2562     // imms<5> and immr<5> must be zero, else ReservedValue().
2563     let Inst{21} = 0;
2564     let Inst{15} = 0;
2565   }
2566   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2567     let Inst{31} = 1;
2568     let Inst{22} = 1;
2569   }
2570 }
2571
2572 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2573 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2574                       RegisterClass regtype, Operand imm_type, string asm>
2575     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2576                              imm_type:$imms),
2577          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2578       Sched<[WriteIS, ReadI]> {
2579   bits<5> Rd;
2580   bits<5> Rn;
2581   bits<6> immr;
2582   bits<6> imms;
2583
2584   let Inst{30-29} = opc;
2585   let Inst{28-23} = 0b100110;
2586   let Inst{21-16} = immr;
2587   let Inst{15-10} = imms;
2588   let Inst{9-5}   = Rn;
2589   let Inst{4-0}   = Rd;
2590 }
2591
2592 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2593   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2594     let Inst{31} = 0;
2595     let Inst{22} = 0;
2596     // imms<5> and immr<5> must be zero, else ReservedValue().
2597     let Inst{21} = 0;
2598     let Inst{15} = 0;
2599   }
2600   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2601     let Inst{31} = 1;
2602     let Inst{22} = 1;
2603   }
2604 }
2605
2606 //---
2607 // Logical
2608 //---
2609
2610 // Logical (immediate)
2611 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2612                      RegisterClass sregtype, Operand imm_type, string asm,
2613                      list<dag> pattern>
2614     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2615          asm, "\t$Rd, $Rn, $imm", "", pattern>,
2616       Sched<[WriteI, ReadI]> {
2617   bits<5>  Rd;
2618   bits<5>  Rn;
2619   bits<13> imm;
2620   let Inst{30-29} = opc;
2621   let Inst{28-23} = 0b100100;
2622   let Inst{22}    = imm{12};
2623   let Inst{21-16} = imm{11-6};
2624   let Inst{15-10} = imm{5-0};
2625   let Inst{9-5}   = Rn;
2626   let Inst{4-0}   = Rd;
2627
2628   let DecoderMethod = "DecodeLogicalImmInstruction";
2629 }
2630
2631 // Logical (shifted register)
2632 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2633                       logical_shifted_reg shifted_regtype, string asm,
2634                       list<dag> pattern>
2635     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2636         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2637       Sched<[WriteISReg, ReadI, ReadISReg]> {
2638   // The operands are in order to match the 'addr' MI operands, so we
2639   // don't need an encoder method and by-name matching. Just use the default
2640   // in-order handling. Since we're using by-order, make sure the names
2641   // do not match.
2642   bits<5> dst;
2643   bits<5> src1;
2644   bits<5> src2;
2645   bits<8> shift;
2646   let Inst{30-29} = opc;
2647   let Inst{28-24} = 0b01010;
2648   let Inst{23-22} = shift{7-6};
2649   let Inst{21}    = N;
2650   let Inst{20-16} = src2;
2651   let Inst{15-10} = shift{5-0};
2652   let Inst{9-5}   = src1;
2653   let Inst{4-0}   = dst;
2654
2655   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2656 }
2657
2658 // Aliases for register+register logical instructions.
2659 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2660     : InstAlias<asm#"\t$dst, $src1, $src2",
2661                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2662
2663 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2664                       string Alias> {
2665   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2666   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2667                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2668                                                logical_imm32:$imm))]> {
2669     let Inst{31} = 0;
2670     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2671   }
2672   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2673   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2674                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2675                                                logical_imm64:$imm))]> {
2676     let Inst{31} = 1;
2677   }
2678
2679   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2680                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2681                       logical_imm32_not:$imm), 0>;
2682   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2683                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2684                        logical_imm64_not:$imm), 0>;
2685 }
2686
2687 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2688                        string Alias> {
2689   let isCompare = 1, Defs = [NZCV] in {
2690   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2691       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2692     let Inst{31} = 0;
2693     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2694   }
2695   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2696       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2697     let Inst{31} = 1;
2698   }
2699   } // end Defs = [NZCV]
2700
2701   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2702                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2703                       logical_imm32_not:$imm), 0>;
2704   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2705                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2706                        logical_imm64_not:$imm), 0>;
2707 }
2708
2709 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2710     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2711              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2712       Sched<[WriteI, ReadI, ReadI]>;
2713
2714 // Split from LogicalImm as not all instructions have both.
2715 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2716                       SDPatternOperator OpNode> {
2717   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2718   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2719   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2720   }
2721
2722   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2723                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2724                                                  logical_shifted_reg32:$Rm))]> {
2725     let Inst{31} = 0;
2726   }
2727   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2728                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2729                                                  logical_shifted_reg64:$Rm))]> {
2730     let Inst{31} = 1;
2731   }
2732
2733   def : LogicalRegAlias<mnemonic,
2734                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2735   def : LogicalRegAlias<mnemonic,
2736                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2737 }
2738
2739 // Split from LogicalReg to allow setting NZCV Defs
2740 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2741                        SDPatternOperator OpNode = null_frag> {
2742   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2743   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2744   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2745
2746   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2747             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2748     let Inst{31} = 0;
2749   }
2750   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2751             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2752     let Inst{31} = 1;
2753   }
2754   } // Defs = [NZCV]
2755
2756   def : LogicalRegAlias<mnemonic,
2757                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2758   def : LogicalRegAlias<mnemonic,
2759                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2760 }
2761
2762 //---
2763 // Conditionally set flags
2764 //---
2765
2766 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2767 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2768                             string mnemonic, SDNode OpNode>
2769     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2770          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2771          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2772                              (i32 imm:$cond), NZCV))]>,
2773       Sched<[WriteI, ReadI]> {
2774   let Uses = [NZCV];
2775   let Defs = [NZCV];
2776
2777   bits<5> Rn;
2778   bits<5> imm;
2779   bits<4> nzcv;
2780   bits<4> cond;
2781
2782   let Inst{30}    = op;
2783   let Inst{29-21} = 0b111010010;
2784   let Inst{20-16} = imm;
2785   let Inst{15-12} = cond;
2786   let Inst{11-10} = 0b10;
2787   let Inst{9-5}   = Rn;
2788   let Inst{4}     = 0b0;
2789   let Inst{3-0}   = nzcv;
2790 }
2791
2792 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2793 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2794                             SDNode OpNode>
2795     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2796          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2797          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2798                              (i32 imm:$cond), NZCV))]>,
2799       Sched<[WriteI, ReadI, ReadI]> {
2800   let Uses = [NZCV];
2801   let Defs = [NZCV];
2802
2803   bits<5> Rn;
2804   bits<5> Rm;
2805   bits<4> nzcv;
2806   bits<4> cond;
2807
2808   let Inst{30}    = op;
2809   let Inst{29-21} = 0b111010010;
2810   let Inst{20-16} = Rm;
2811   let Inst{15-12} = cond;
2812   let Inst{11-10} = 0b00;
2813   let Inst{9-5}   = Rn;
2814   let Inst{4}     = 0b0;
2815   let Inst{3-0}   = nzcv;
2816 }
2817
2818 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2819   // immediate operand variants
2820   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2821     let Inst{31} = 0;
2822   }
2823   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2824     let Inst{31} = 1;
2825   }
2826   // register operand variants
2827   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2828     let Inst{31} = 0;
2829   }
2830   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2831     let Inst{31} = 1;
2832   }
2833 }
2834
2835 //---
2836 // Conditional select
2837 //---
2838
2839 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2840     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2841          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2842          [(set regtype:$Rd,
2843                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2844       Sched<[WriteI, ReadI, ReadI]> {
2845   let Uses = [NZCV];
2846
2847   bits<5> Rd;
2848   bits<5> Rn;
2849   bits<5> Rm;
2850   bits<4> cond;
2851
2852   let Inst{30}    = op;
2853   let Inst{29-21} = 0b011010100;
2854   let Inst{20-16} = Rm;
2855   let Inst{15-12} = cond;
2856   let Inst{11-10} = op2;
2857   let Inst{9-5}   = Rn;
2858   let Inst{4-0}   = Rd;
2859 }
2860
2861 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2862   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2863     let Inst{31} = 0;
2864   }
2865   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2866     let Inst{31} = 1;
2867   }
2868 }
2869
2870 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2871                        PatFrag frag>
2872     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2873          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2874          [(set regtype:$Rd,
2875                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2876                (i32 imm:$cond), NZCV))]>,
2877       Sched<[WriteI, ReadI, ReadI]> {
2878   let Uses = [NZCV];
2879
2880   bits<5> Rd;
2881   bits<5> Rn;
2882   bits<5> Rm;
2883   bits<4> cond;
2884
2885   let Inst{30}    = op;
2886   let Inst{29-21} = 0b011010100;
2887   let Inst{20-16} = Rm;
2888   let Inst{15-12} = cond;
2889   let Inst{11-10} = op2;
2890   let Inst{9-5}   = Rn;
2891   let Inst{4-0}   = Rd;
2892 }
2893
2894 def inv_cond_XFORM : SDNodeXForm<imm, [{
2895   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2896   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2897                                    MVT::i32);
2898 }]>;
2899
2900 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2901   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2902     let Inst{31} = 0;
2903   }
2904   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2905     let Inst{31} = 1;
2906   }
2907
2908   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2909             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2910                                            (inv_cond_XFORM imm:$cond))>;
2911
2912   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2913             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2914                                            (inv_cond_XFORM imm:$cond))>;
2915 }
2916
2917 //---
2918 // Special Mask Value
2919 //---
2920 def maski8_or_more : Operand<i32>,
2921   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2922 }
2923 def maski16_or_more : Operand<i32>,
2924   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2925 }
2926
2927
2928 //---
2929 // Load/store
2930 //---
2931
2932 // (unsigned immediate)
2933 // Indexed for 8-bit registers. offset is in range [0,4095].
2934 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2935 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2936 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2937 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2938 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2939
2940 def gi_am_indexed8 :
2941     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
2942     GIComplexPatternEquiv<am_indexed8>;
2943 def gi_am_indexed16 :
2944     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
2945     GIComplexPatternEquiv<am_indexed16>;
2946 def gi_am_indexed32 :
2947     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
2948     GIComplexPatternEquiv<am_indexed32>;
2949 def gi_am_indexed64 :
2950     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
2951     GIComplexPatternEquiv<am_indexed64>;
2952 def gi_am_indexed128 :
2953     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
2954     GIComplexPatternEquiv<am_indexed128>;
2955
2956 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2957   let Name = "UImm12Offset" # Scale;
2958   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2959   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2960   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2961 }
2962
2963 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2964 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2965 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2966 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2967 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2968
2969 class uimm12_scaled<int Scale> : Operand<i64> {
2970   let ParserMatchClass
2971    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2972   let EncoderMethod
2973    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2974   let PrintMethod = "printUImm12Offset<" # Scale # ">";
2975 }
2976
2977 def uimm12s1 : uimm12_scaled<1>;
2978 def uimm12s2 : uimm12_scaled<2>;
2979 def uimm12s4 : uimm12_scaled<4>;
2980 def uimm12s8 : uimm12_scaled<8>;
2981 def uimm12s16 : uimm12_scaled<16>;
2982
2983 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2984                       string asm, list<dag> pattern>
2985     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2986   bits<5> Rt;
2987
2988   bits<5> Rn;
2989   bits<12> offset;
2990
2991   let Inst{31-30} = sz;
2992   let Inst{29-27} = 0b111;
2993   let Inst{26}    = V;
2994   let Inst{25-24} = 0b01;
2995   let Inst{23-22} = opc;
2996   let Inst{21-10} = offset;
2997   let Inst{9-5}   = Rn;
2998   let Inst{4-0}   = Rt;
2999
3000   let DecoderMethod = "DecodeUnsignedLdStInstruction";
3001 }
3002
3003 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3004                   Operand indextype, string asm, list<dag> pattern> {
3005   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3006   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
3007                            (ins GPR64sp:$Rn, indextype:$offset),
3008                            asm, pattern>,
3009            Sched<[WriteLD]>;
3010
3011   def : InstAlias<asm # "\t$Rt, [$Rn]",
3012                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3013 }
3014
3015 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3016              Operand indextype, string asm, list<dag> pattern> {
3017   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3018   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3019                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3020                            asm, pattern>,
3021            Sched<[WriteST]>;
3022
3023   def : InstAlias<asm # "\t$Rt, [$Rn]",
3024                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3025 }
3026
3027 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
3028 // substitute zero-registers automatically.
3029 //
3030 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
3031 //       into StoreUI.
3032 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3033              Operand indextype, string asm, list<dag> pattern> {
3034   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3035   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3036                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3037                            asm, pattern>,
3038            Sched<[WriteST]>;
3039
3040   def : InstAlias<asm # "\t$Rt, [$Rn]",
3041                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3042 }
3043
3044 def PrefetchOperand : AsmOperandClass {
3045   let Name = "Prefetch";
3046   let ParserMethod = "tryParsePrefetch";
3047 }
3048 def prfop : Operand<i32> {
3049   let PrintMethod = "printPrefetchOp";
3050   let ParserMatchClass = PrefetchOperand;
3051 }
3052
3053 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3054 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
3055     : BaseLoadStoreUI<sz, V, opc,
3056                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
3057                       asm, pat>,
3058       Sched<[WriteLD]>;
3059
3060 //---
3061 // Load literal
3062 //---
3063
3064 // Load literal address: 19-bit immediate. The low two bits of the target
3065 // offset are implied zero and so are not part of the immediate.
3066 def am_ldrlit : Operand<iPTR> {
3067   let EncoderMethod = "getLoadLiteralOpValue";
3068   let DecoderMethod = "DecodePCRelLabel19";
3069   let PrintMethod = "printAlignedLabel";
3070   let ParserMatchClass = PCRelLabel19Operand;
3071   let OperandType = "OPERAND_PCREL";
3072 }
3073
3074 let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
3075 class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
3076     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
3077         asm, "\t$Rt, $label", "", pat>,
3078       Sched<[WriteLD]> {
3079   bits<5> Rt;
3080   bits<19> label;
3081   let Inst{31-30} = opc;
3082   let Inst{29-27} = 0b011;
3083   let Inst{26}    = V;
3084   let Inst{25-24} = 0b00;
3085   let Inst{23-5}  = label;
3086   let Inst{4-0}   = Rt;
3087 }
3088
3089 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3090 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
3091     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
3092         asm, "\t$Rt, $label", "", pat>,
3093       Sched<[WriteLD]> {
3094   bits<5> Rt;
3095   bits<19> label;
3096   let Inst{31-30} = opc;
3097   let Inst{29-27} = 0b011;
3098   let Inst{26}    = V;
3099   let Inst{25-24} = 0b00;
3100   let Inst{23-5}  = label;
3101   let Inst{4-0}   = Rt;
3102 }
3103
3104 //---
3105 // Load/store register offset
3106 //---
3107
3108 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
3109 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
3110 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
3111 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
3112 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
3113
3114 def gi_ro_Xindexed8 :
3115     GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">,
3116     GIComplexPatternEquiv<ro_Xindexed8>;
3117 def gi_ro_Xindexed16 :
3118     GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">,
3119     GIComplexPatternEquiv<ro_Xindexed16>;
3120 def gi_ro_Xindexed32 :
3121     GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">,
3122     GIComplexPatternEquiv<ro_Xindexed32>;
3123 def gi_ro_Xindexed64 :
3124     GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">,
3125     GIComplexPatternEquiv<ro_Xindexed64>;
3126 def gi_ro_Xindexed128 :
3127     GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">,
3128     GIComplexPatternEquiv<ro_Xindexed128>;
3129
3130 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
3131 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
3132 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
3133 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
3134 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
3135
3136 def gi_ro_Windexed8 :
3137     GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">,
3138     GIComplexPatternEquiv<ro_Windexed8>;
3139 def gi_ro_Windexed16 :
3140     GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">,
3141     GIComplexPatternEquiv<ro_Windexed16>;
3142 def gi_ro_Windexed32 :
3143     GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">,
3144     GIComplexPatternEquiv<ro_Windexed32>;
3145 def gi_ro_Windexed64 :
3146     GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">,
3147     GIComplexPatternEquiv<ro_Windexed64>;
3148 def gi_ro_Windexed128 :
3149     GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">,
3150     GIComplexPatternEquiv<ro_Windexed128>;
3151
3152 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
3153   let Name = "Mem" # Reg # "Extend" # Width;
3154   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
3155   let RenderMethod = "addMemExtendOperands";
3156   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
3157 }
3158
3159 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
3160   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3161   // the trivial shift.
3162   let RenderMethod = "addMemExtend8Operands";
3163 }
3164 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
3165 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
3166 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
3167 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
3168
3169 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
3170   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3171   // the trivial shift.
3172   let RenderMethod = "addMemExtend8Operands";
3173 }
3174 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
3175 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
3176 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
3177 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
3178
3179 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
3180         : Operand<i32> {
3181   let ParserMatchClass = ParserClass;
3182   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
3183   let DecoderMethod = "DecodeMemExtend";
3184   let EncoderMethod = "getMemExtendOpValue";
3185   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
3186 }
3187
3188 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
3189 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
3190 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
3191 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
3192 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
3193
3194 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
3195 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
3196 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
3197 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
3198 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
3199
3200 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
3201                   Operand wextend, Operand xextend>  {
3202   // CodeGen-level pattern covering the entire addressing mode.
3203   ComplexPattern Wpat = windex;
3204   ComplexPattern Xpat = xindex;
3205
3206   // Asm-level Operand covering the valid "uxtw #3" style syntax.
3207   Operand Wext = wextend;
3208   Operand Xext = xextend;
3209 }
3210
3211 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
3212 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
3213 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
3214 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
3215 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
3216                        ro_Xextend128>;
3217
3218 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3219                       string asm, dag ins, dag outs, list<dag> pat>
3220     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3221   bits<5> Rt;
3222   bits<5> Rn;
3223   bits<5> Rm;
3224   bits<2> extend;
3225   let Inst{31-30} = sz;
3226   let Inst{29-27} = 0b111;
3227   let Inst{26}    = V;
3228   let Inst{25-24} = 0b00;
3229   let Inst{23-22} = opc;
3230   let Inst{21}    = 1;
3231   let Inst{20-16} = Rm;
3232   let Inst{15}    = extend{1}; // sign extend Rm?
3233   let Inst{14}    = 1;
3234   let Inst{12}    = extend{0}; // do shift?
3235   let Inst{11-10} = 0b10;
3236   let Inst{9-5}   = Rn;
3237   let Inst{4-0}   = Rt;
3238 }
3239
3240 class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST>
3241   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
3242               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3243
3244 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3245                    string asm, ValueType Ty, SDPatternOperator loadop> {
3246   let AddedComplexity = 10 in
3247   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
3248                  (outs regtype:$Rt),
3249                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3250                  [(set (Ty regtype:$Rt),
3251                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3252                                              ro_Wextend8:$extend)))]>,
3253            Sched<[WriteLDIdx, ReadAdrBase]> {
3254     let Inst{13} = 0b0;
3255   }
3256
3257   let AddedComplexity = 10 in
3258   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
3259                  (outs regtype:$Rt),
3260                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3261                  [(set (Ty regtype:$Rt),
3262                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3263                                              ro_Xextend8:$extend)))]>,
3264            Sched<[WriteLDIdx, ReadAdrBase]> {
3265     let Inst{13} = 0b1;
3266   }
3267
3268   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3269 }
3270
3271 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3272                     string asm, ValueType Ty, SDPatternOperator storeop> {
3273   let AddedComplexity = 10 in
3274   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3275                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3276                  [(storeop (Ty regtype:$Rt),
3277                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3278                                          ro_Wextend8:$extend))]>,
3279             Sched<[WriteSTIdx, ReadAdrBase]> {
3280     let Inst{13} = 0b0;
3281   }
3282
3283   let AddedComplexity = 10 in
3284   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3285                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3286                  [(storeop (Ty regtype:$Rt),
3287                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3288                                          ro_Xextend8:$extend))]>,
3289             Sched<[WriteSTIdx, ReadAdrBase]> {
3290     let Inst{13} = 0b1;
3291   }
3292
3293   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3294 }
3295
3296 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3297                       string asm, dag ins, dag outs, list<dag> pat>
3298     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3299   bits<5> Rt;
3300   bits<5> Rn;
3301   bits<5> Rm;
3302   bits<2> extend;
3303   let Inst{31-30} = sz;
3304   let Inst{29-27} = 0b111;
3305   let Inst{26}    = V;
3306   let Inst{25-24} = 0b00;
3307   let Inst{23-22} = opc;
3308   let Inst{21}    = 1;
3309   let Inst{20-16} = Rm;
3310   let Inst{15}    = extend{1}; // sign extend Rm?
3311   let Inst{14}    = 1;
3312   let Inst{12}    = extend{0}; // do shift?
3313   let Inst{11-10} = 0b10;
3314   let Inst{9-5}   = Rn;
3315   let Inst{4-0}   = Rt;
3316 }
3317
3318 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3319                     string asm, ValueType Ty, SDPatternOperator loadop> {
3320   let AddedComplexity = 10 in
3321   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3322                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3323                  [(set (Ty regtype:$Rt),
3324                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3325                                               ro_Wextend16:$extend)))]>,
3326             Sched<[WriteLDIdx, ReadAdrBase]> {
3327     let Inst{13} = 0b0;
3328   }
3329
3330   let AddedComplexity = 10 in
3331   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3332                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3333                  [(set (Ty regtype:$Rt),
3334                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3335                                              ro_Xextend16:$extend)))]>,
3336             Sched<[WriteLDIdx, ReadAdrBase]> {
3337     let Inst{13} = 0b1;
3338   }
3339
3340   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3341 }
3342
3343 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3344                      string asm, ValueType Ty, SDPatternOperator storeop> {
3345   let AddedComplexity = 10 in
3346   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3347                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3348                 [(storeop (Ty regtype:$Rt),
3349                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3350                                          ro_Wextend16:$extend))]>,
3351            Sched<[WriteSTIdx, ReadAdrBase]> {
3352     let Inst{13} = 0b0;
3353   }
3354
3355   let AddedComplexity = 10 in
3356   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3357                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3358                 [(storeop (Ty regtype:$Rt),
3359                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3360                                          ro_Xextend16:$extend))]>,
3361            Sched<[WriteSTIdx, ReadAdrBase]> {
3362     let Inst{13} = 0b1;
3363   }
3364
3365   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3366 }
3367
3368 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3369                       string asm, dag ins, dag outs, list<dag> pat>
3370     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3371   bits<5> Rt;
3372   bits<5> Rn;
3373   bits<5> Rm;
3374   bits<2> extend;
3375   let Inst{31-30} = sz;
3376   let Inst{29-27} = 0b111;
3377   let Inst{26}    = V;
3378   let Inst{25-24} = 0b00;
3379   let Inst{23-22} = opc;
3380   let Inst{21}    = 1;
3381   let Inst{20-16} = Rm;
3382   let Inst{15}    = extend{1}; // sign extend Rm?
3383   let Inst{14}    = 1;
3384   let Inst{12}    = extend{0}; // do shift?
3385   let Inst{11-10} = 0b10;
3386   let Inst{9-5}   = Rn;
3387   let Inst{4-0}   = Rt;
3388 }
3389
3390 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3391                     string asm, ValueType Ty, SDPatternOperator loadop> {
3392   let AddedComplexity = 10 in
3393   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3394                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3395                  [(set (Ty regtype:$Rt),
3396                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3397                                               ro_Wextend32:$extend)))]>,
3398            Sched<[WriteLDIdx, ReadAdrBase]> {
3399     let Inst{13} = 0b0;
3400   }
3401
3402   let AddedComplexity = 10 in
3403   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3404                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3405                  [(set (Ty regtype:$Rt),
3406                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3407                                               ro_Xextend32:$extend)))]>,
3408            Sched<[WriteLDIdx, ReadAdrBase]> {
3409     let Inst{13} = 0b1;
3410   }
3411
3412   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3413 }
3414
3415 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3416                      string asm, ValueType Ty, SDPatternOperator storeop> {
3417   let AddedComplexity = 10 in
3418   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3419                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3420                 [(storeop (Ty regtype:$Rt),
3421                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3422                                          ro_Wextend32:$extend))]>,
3423             Sched<[WriteSTIdx, ReadAdrBase]> {
3424     let Inst{13} = 0b0;
3425   }
3426
3427   let AddedComplexity = 10 in
3428   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3429                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3430                 [(storeop (Ty regtype:$Rt),
3431                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3432                                         ro_Xextend32:$extend))]>,
3433             Sched<[WriteSTIdx, ReadAdrBase]> {
3434     let Inst{13} = 0b1;
3435   }
3436
3437   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3438 }
3439
3440 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3441                       string asm, dag ins, dag outs, list<dag> pat>
3442     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3443   bits<5> Rt;
3444   bits<5> Rn;
3445   bits<5> Rm;
3446   bits<2> extend;
3447   let Inst{31-30} = sz;
3448   let Inst{29-27} = 0b111;
3449   let Inst{26}    = V;
3450   let Inst{25-24} = 0b00;
3451   let Inst{23-22} = opc;
3452   let Inst{21}    = 1;
3453   let Inst{20-16} = Rm;
3454   let Inst{15}    = extend{1}; // sign extend Rm?
3455   let Inst{14}    = 1;
3456   let Inst{12}    = extend{0}; // do shift?
3457   let Inst{11-10} = 0b10;
3458   let Inst{9-5}   = Rn;
3459   let Inst{4-0}   = Rt;
3460 }
3461
3462 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3463                     string asm, ValueType Ty, SDPatternOperator loadop> {
3464   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3465   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3466                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3467                 [(set (Ty regtype:$Rt),
3468                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3469                                              ro_Wextend64:$extend)))]>,
3470            Sched<[WriteLDIdx, ReadAdrBase]> {
3471     let Inst{13} = 0b0;
3472   }
3473
3474   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3475   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3476                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3477                  [(set (Ty regtype:$Rt),
3478                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3479                                               ro_Xextend64:$extend)))]>,
3480            Sched<[WriteLDIdx, ReadAdrBase]> {
3481     let Inst{13} = 0b1;
3482   }
3483
3484   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3485 }
3486
3487 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3488                      string asm, ValueType Ty, SDPatternOperator storeop> {
3489   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3490   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3491                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3492                 [(storeop (Ty regtype:$Rt),
3493                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3494                                          ro_Wextend64:$extend))]>,
3495             Sched<[WriteSTIdx, ReadAdrBase]> {
3496     let Inst{13} = 0b0;
3497   }
3498
3499   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3500   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3501                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3502                 [(storeop (Ty regtype:$Rt),
3503                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3504                                          ro_Xextend64:$extend))]>,
3505             Sched<[WriteSTIdx, ReadAdrBase]> {
3506     let Inst{13} = 0b1;
3507   }
3508
3509   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3510 }
3511
3512 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3513                       string asm, dag ins, dag outs, list<dag> pat>
3514     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3515   bits<5> Rt;
3516   bits<5> Rn;
3517   bits<5> Rm;
3518   bits<2> extend;
3519   let Inst{31-30} = sz;
3520   let Inst{29-27} = 0b111;
3521   let Inst{26}    = V;
3522   let Inst{25-24} = 0b00;
3523   let Inst{23-22} = opc;
3524   let Inst{21}    = 1;
3525   let Inst{20-16} = Rm;
3526   let Inst{15}    = extend{1}; // sign extend Rm?
3527   let Inst{14}    = 1;
3528   let Inst{12}    = extend{0}; // do shift?
3529   let Inst{11-10} = 0b10;
3530   let Inst{9-5}   = Rn;
3531   let Inst{4-0}   = Rt;
3532 }
3533
3534 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3535                      string asm, ValueType Ty, SDPatternOperator loadop> {
3536   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3537   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3538                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3539                  [(set (Ty regtype:$Rt),
3540                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
3541                                                ro_Wextend128:$extend)))]>,
3542             Sched<[WriteLDIdx, ReadAdrBase]> {
3543     let Inst{13} = 0b0;
3544   }
3545
3546   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3547   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3548                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3549                  [(set (Ty regtype:$Rt),
3550                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
3551                                                ro_Xextend128:$extend)))]>,
3552             Sched<[WriteLDIdx, ReadAdrBase]> {
3553     let Inst{13} = 0b1;
3554   }
3555
3556   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3557 }
3558
3559 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3560                       string asm, ValueType Ty, SDPatternOperator storeop> {
3561   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3562   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3563                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3564                 []>,
3565             Sched<[WriteSTIdx, ReadAdrBase]> {
3566     let Inst{13} = 0b0;
3567   }
3568
3569   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3570   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3571                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3572                 []>,
3573             Sched<[WriteSTIdx, ReadAdrBase]> {
3574     let Inst{13} = 0b1;
3575   }
3576
3577   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3578 }
3579
3580 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3581 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
3582                      string asm, list<dag> pat>
3583     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
3584       Sched<[WriteLD]> {
3585   bits<5> Rt;
3586   bits<5> Rn;
3587   bits<5> Rm;
3588   bits<2> extend;
3589   let Inst{31-30} = sz;
3590   let Inst{29-27} = 0b111;
3591   let Inst{26}    = V;
3592   let Inst{25-24} = 0b00;
3593   let Inst{23-22} = opc;
3594   let Inst{21}    = 1;
3595   let Inst{20-16} = Rm;
3596   let Inst{15}    = extend{1}; // sign extend Rm?
3597   let Inst{14}    = 1;
3598   let Inst{12}    = extend{0}; // do shift?
3599   let Inst{11-10} = 0b10;
3600   let Inst{9-5}   = Rn;
3601   let Inst{4-0}   = Rt;
3602 }
3603
3604 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
3605   def roW : BasePrefetchRO<sz, V, opc, (outs),
3606                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3607                 asm, [(AArch64Prefetch imm:$Rt,
3608                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3609                                                     ro_Wextend64:$extend))]> {
3610     let Inst{13} = 0b0;
3611   }
3612
3613   def roX : BasePrefetchRO<sz, V, opc, (outs),
3614                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3615                 asm,  [(AArch64Prefetch imm:$Rt,
3616                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3617                                                      ro_Xextend64:$extend))]> {
3618     let Inst{13} = 0b1;
3619   }
3620
3621   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3622                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3623                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3624 }
3625
3626 //---
3627 // Load/store unscaled immediate
3628 //---
3629
3630 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3631 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3632 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3633 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3634 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3635
3636 def gi_am_unscaled8 :
3637     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
3638     GIComplexPatternEquiv<am_unscaled8>;
3639 def gi_am_unscaled16 :
3640     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
3641     GIComplexPatternEquiv<am_unscaled16>;
3642 def gi_am_unscaled32 :
3643     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
3644     GIComplexPatternEquiv<am_unscaled32>;
3645 def gi_am_unscaled64 :
3646     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
3647     GIComplexPatternEquiv<am_unscaled64>;
3648 def gi_am_unscaled128 :
3649     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
3650     GIComplexPatternEquiv<am_unscaled128>;
3651
3652
3653 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3654                            string asm, list<dag> pattern>
3655     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3656   bits<5> Rt;
3657   bits<5> Rn;
3658   bits<9> offset;
3659   let Inst{31-30} = sz;
3660   let Inst{29-27} = 0b111;
3661   let Inst{26}    = V;
3662   let Inst{25-24} = 0b00;
3663   let Inst{23-22} = opc;
3664   let Inst{21}    = 0;
3665   let Inst{20-12} = offset;
3666   let Inst{11-10} = 0b00;
3667   let Inst{9-5}   = Rn;
3668   let Inst{4-0}   = Rt;
3669
3670   let DecoderMethod = "DecodeSignedLdStInstruction";
3671 }
3672
3673 // Armv8.4 LDAPR & STLR with Immediate Offset instruction
3674 multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3675                               RegisterOperand regtype > {
3676   def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),
3677                                (ins GPR64sp:$Rn, simm9:$offset), asm, []>,
3678           Sched<[WriteST]> {
3679     let Inst{29} = 0;
3680     let Inst{24} = 1;
3681   }
3682   def : InstAlias<asm # "\t$Rt, [$Rn]",
3683                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3684 }
3685
3686 multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3687                                RegisterOperand regtype > {
3688   def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),
3689                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3690                                asm, []>,
3691           Sched<[WriteST]> {
3692     let Inst{29} = 0;
3693     let Inst{24} = 1;
3694   }
3695   def : InstAlias<asm # "\t$Rt, [$Rn]",
3696                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3697 }
3698
3699 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3700                    string asm, list<dag> pattern> {
3701   let AddedComplexity = 1 in // try this before LoadUI
3702   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3703                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3704           Sched<[WriteLD]>;
3705
3706   def : InstAlias<asm # "\t$Rt, [$Rn]",
3707                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3708 }
3709
3710 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3711                          string asm, list<dag> pattern> {
3712   let AddedComplexity = 1 in // try this before StoreUI
3713   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3714                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3715                                asm, pattern>,
3716           Sched<[WriteST]>;
3717
3718   def : InstAlias<asm # "\t$Rt, [$Rn]",
3719                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3720 }
3721
3722 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3723                             list<dag> pat> {
3724   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3725   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3726                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3727                                asm, pat>,
3728           Sched<[WriteLD]>;
3729
3730   def : InstAlias<asm # "\t$Rt, [$Rn]",
3731                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3732 }
3733
3734 //---
3735 // Load/store unscaled immediate, unprivileged
3736 //---
3737
3738 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3739                                 dag oops, dag iops, string asm>
3740     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3741   bits<5> Rt;
3742   bits<5> Rn;
3743   bits<9> offset;
3744   let Inst{31-30} = sz;
3745   let Inst{29-27} = 0b111;
3746   let Inst{26}    = V;
3747   let Inst{25-24} = 0b00;
3748   let Inst{23-22} = opc;
3749   let Inst{21}    = 0;
3750   let Inst{20-12} = offset;
3751   let Inst{11-10} = 0b10;
3752   let Inst{9-5}   = Rn;
3753   let Inst{4-0}   = Rt;
3754
3755   let DecoderMethod = "DecodeSignedLdStInstruction";
3756 }
3757
3758 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3759                             RegisterClass regtype, string asm> {
3760   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3761   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3762                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
3763           Sched<[WriteLD]>;
3764
3765   def : InstAlias<asm # "\t$Rt, [$Rn]",
3766                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3767 }
3768
3769 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3770                              RegisterClass regtype, string asm> {
3771   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3772   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3773                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3774                                  asm>,
3775           Sched<[WriteST]>;
3776
3777   def : InstAlias<asm # "\t$Rt, [$Rn]",
3778                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3779 }
3780
3781 //---
3782 // Load/store pre-indexed
3783 //---
3784
3785 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3786                           string asm, string cstr, list<dag> pat>
3787     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3788   bits<5> Rt;
3789   bits<5> Rn;
3790   bits<9> offset;
3791   let Inst{31-30} = sz;
3792   let Inst{29-27} = 0b111;
3793   let Inst{26}    = V;
3794   let Inst{25-24} = 0;
3795   let Inst{23-22} = opc;
3796   let Inst{21}    = 0;
3797   let Inst{20-12} = offset;
3798   let Inst{11-10} = 0b11;
3799   let Inst{9-5}   = Rn;
3800   let Inst{4-0}   = Rt;
3801
3802   let DecoderMethod = "DecodeSignedLdStInstruction";
3803 }
3804
3805 let hasSideEffects = 0 in {
3806 let mayStore = 0, mayLoad = 1 in
3807 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3808              string asm>
3809     : BaseLoadStorePreIdx<sz, V, opc,
3810                      (outs GPR64sp:$wback, regtype:$Rt),
3811                      (ins GPR64sp:$Rn, simm9:$offset), asm,
3812                      "$Rn = $wback,@earlyclobber $wback", []>,
3813       Sched<[WriteLD, WriteAdr]>;
3814
3815 let mayStore = 1, mayLoad = 0 in
3816 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3817                   string asm, SDPatternOperator storeop, ValueType Ty>
3818     : BaseLoadStorePreIdx<sz, V, opc,
3819                       (outs GPR64sp:$wback),
3820                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3821                       asm, "$Rn = $wback,@earlyclobber $wback",
3822       [(set GPR64sp:$wback,
3823             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3824       Sched<[WriteAdr, WriteST]>;
3825 } // hasSideEffects = 0
3826
3827 //---
3828 // Load/store post-indexed
3829 //---
3830
3831 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3832                           string asm, string cstr, list<dag> pat>
3833     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3834   bits<5> Rt;
3835   bits<5> Rn;
3836   bits<9> offset;
3837   let Inst{31-30} = sz;
3838   let Inst{29-27} = 0b111;
3839   let Inst{26}    = V;
3840   let Inst{25-24} = 0b00;
3841   let Inst{23-22} = opc;
3842   let Inst{21}    = 0b0;
3843   let Inst{20-12} = offset;
3844   let Inst{11-10} = 0b01;
3845   let Inst{9-5}   = Rn;
3846   let Inst{4-0}   = Rt;
3847
3848   let DecoderMethod = "DecodeSignedLdStInstruction";
3849 }
3850
3851 let hasSideEffects = 0 in {
3852 let mayStore = 0, mayLoad = 1 in
3853 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3854              string asm>
3855     : BaseLoadStorePostIdx<sz, V, opc,
3856                       (outs GPR64sp:$wback, regtype:$Rt),
3857                       (ins GPR64sp:$Rn, simm9:$offset),
3858                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
3859       Sched<[WriteLD, WriteAdr]>;
3860
3861 let mayStore = 1, mayLoad = 0 in
3862 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3863                    string asm, SDPatternOperator storeop, ValueType Ty>
3864     : BaseLoadStorePostIdx<sz, V, opc,
3865                       (outs GPR64sp:$wback),
3866                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3867                        asm, "$Rn = $wback,@earlyclobber $wback",
3868       [(set GPR64sp:$wback,
3869             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3870     Sched<[WriteAdr, WriteST]>;
3871 } // hasSideEffects = 0
3872
3873
3874 //---
3875 // Load/store pair
3876 //---
3877
3878 // (indexed, offset)
3879
3880 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3881                               string asm>
3882     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3883   bits<5> Rt;
3884   bits<5> Rt2;
3885   bits<5> Rn;
3886   bits<7> offset;
3887   let Inst{31-30} = opc;
3888   let Inst{29-27} = 0b101;
3889   let Inst{26}    = V;
3890   let Inst{25-23} = 0b010;
3891   let Inst{22}    = L;
3892   let Inst{21-15} = offset;
3893   let Inst{14-10} = Rt2;
3894   let Inst{9-5}   = Rn;
3895   let Inst{4-0}   = Rt;
3896
3897   let DecoderMethod = "DecodePairLdStInstruction";
3898 }
3899
3900 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,
3901                           Operand indextype, string asm> {
3902   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3903   def i : BaseLoadStorePairOffset<opc, V, 1,
3904                                   (outs regtype:$Rt, regtype:$Rt2),
3905                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
3906           Sched<[WriteLD, WriteLDHi]>;
3907
3908   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3909                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3910                                                   GPR64sp:$Rn, 0)>;
3911 }
3912
3913
3914 multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
3915                            Operand indextype, string asm> {
3916   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3917   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3918                                   (ins regtype:$Rt, regtype:$Rt2,
3919                                        GPR64sp:$Rn, indextype:$offset),
3920                                   asm>,
3921           Sched<[WriteSTP]>;
3922
3923   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3924                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3925                                                   GPR64sp:$Rn, 0)>;
3926 }
3927
3928 // (pre-indexed)
3929 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3930                               string asm>
3931     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3932   bits<5> Rt;
3933   bits<5> Rt2;
3934   bits<5> Rn;
3935   bits<7> offset;
3936   let Inst{31-30} = opc;
3937   let Inst{29-27} = 0b101;
3938   let Inst{26}    = V;
3939   let Inst{25-23} = 0b011;
3940   let Inst{22}    = L;
3941   let Inst{21-15} = offset;
3942   let Inst{14-10} = Rt2;
3943   let Inst{9-5}   = Rn;
3944   let Inst{4-0}   = Rt;
3945
3946   let DecoderMethod = "DecodePairLdStInstruction";
3947 }
3948
3949 let hasSideEffects = 0 in {
3950 let mayStore = 0, mayLoad = 1 in
3951 class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
3952                      Operand indextype, string asm>
3953     : BaseLoadStorePairPreIdx<opc, V, 1,
3954                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3955                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
3956       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3957
3958 let mayStore = 1, mayLoad = 0 in
3959 class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
3960                       Operand indextype, string asm>
3961     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3962                              (ins regtype:$Rt, regtype:$Rt2,
3963                                   GPR64sp:$Rn, indextype:$offset),
3964                              asm>,
3965       Sched<[WriteAdr, WriteSTP]>;
3966 } // hasSideEffects = 0
3967
3968 // (post-indexed)
3969
3970 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3971                               string asm>
3972     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3973   bits<5> Rt;
3974   bits<5> Rt2;
3975   bits<5> Rn;
3976   bits<7> offset;
3977   let Inst{31-30} = opc;
3978   let Inst{29-27} = 0b101;
3979   let Inst{26}    = V;
3980   let Inst{25-23} = 0b001;
3981   let Inst{22}    = L;
3982   let Inst{21-15} = offset;
3983   let Inst{14-10} = Rt2;
3984   let Inst{9-5}   = Rn;
3985   let Inst{4-0}   = Rt;
3986
3987   let DecoderMethod = "DecodePairLdStInstruction";
3988 }
3989
3990 let hasSideEffects = 0 in {
3991 let mayStore = 0, mayLoad = 1 in
3992 class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
3993                       Operand idxtype, string asm>
3994     : BaseLoadStorePairPostIdx<opc, V, 1,
3995                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3996                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3997       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3998
3999 let mayStore = 1, mayLoad = 0 in
4000 class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4001                        Operand idxtype, string asm>
4002     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
4003                              (ins regtype:$Rt, regtype:$Rt2,
4004                                   GPR64sp:$Rn, idxtype:$offset),
4005                              asm>,
4006       Sched<[WriteAdr, WriteSTP]>;
4007 } // hasSideEffects = 0
4008
4009 //  (no-allocate)
4010
4011 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
4012                               string asm>
4013     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4014   bits<5> Rt;
4015   bits<5> Rt2;
4016   bits<5> Rn;
4017   bits<7> offset;
4018   let Inst{31-30} = opc;
4019   let Inst{29-27} = 0b101;
4020   let Inst{26}    = V;
4021   let Inst{25-23} = 0b000;
4022   let Inst{22}    = L;
4023   let Inst{21-15} = offset;
4024   let Inst{14-10} = Rt2;
4025   let Inst{9-5}   = Rn;
4026   let Inst{4-0}   = Rt;
4027
4028   let DecoderMethod = "DecodePairLdStInstruction";
4029 }
4030
4031 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
4032                            Operand indextype, string asm> {
4033   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4034   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
4035                                    (outs regtype:$Rt, regtype:$Rt2),
4036                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
4037           Sched<[WriteLD, WriteLDHi]>;
4038
4039
4040   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4041                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4042                                                   GPR64sp:$Rn, 0)>;
4043 }
4044
4045 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
4046                       Operand indextype, string asm> {
4047   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
4048   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
4049                                    (ins regtype:$Rt, regtype:$Rt2,
4050                                         GPR64sp:$Rn, indextype:$offset),
4051                                    asm>,
4052           Sched<[WriteSTP]>;
4053
4054   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4055                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4056                                                   GPR64sp:$Rn, 0)>;
4057 }
4058
4059 //---
4060 // Load/store exclusive
4061 //---
4062
4063 // True exclusive operations write to and/or read from the system's exclusive
4064 // monitors, which as far as a compiler is concerned can be modelled as a
4065 // random shared memory address. Hence LoadExclusive mayStore.
4066 //
4067 // Since these instructions have the undefined register bits set to 1 in
4068 // their canonical form, we need a post encoder method to set those bits
4069 // to 1 when encoding these instructions. We do this using the
4070 // fixLoadStoreExclusive function. This function has template parameters:
4071 //
4072 // fixLoadStoreExclusive<int hasRs, int hasRt2>
4073 //
4074 // hasRs indicates that the instruction uses the Rs field, so we won't set
4075 // it to 1 (and the same for Rt2). We don't need template parameters for
4076 // the other register fields since Rt and Rn are always used.
4077 //
4078 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
4079 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4080                              dag oops, dag iops, string asm, string operands>
4081     : I<oops, iops, asm, operands, "", []> {
4082   let Inst{31-30} = sz;
4083   let Inst{29-24} = 0b001000;
4084   let Inst{23}    = o2;
4085   let Inst{22}    = L;
4086   let Inst{21}    = o1;
4087   let Inst{15}    = o0;
4088
4089   let DecoderMethod = "DecodeExclusiveLdStInstruction";
4090 }
4091
4092 // Neither Rs nor Rt2 operands.
4093 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4094                                dag oops, dag iops, string asm, string operands>
4095     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
4096   bits<5> Rt;
4097   bits<5> Rn;
4098   let Inst{20-16} = 0b11111;
4099   let Unpredictable{20-16} = 0b11111;
4100   let Inst{14-10} = 0b11111;
4101   let Unpredictable{14-10} = 0b11111;
4102   let Inst{9-5} = Rn;
4103   let Inst{4-0} = Rt;
4104
4105   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
4106 }
4107
4108 // Simple load acquires don't set the exclusive monitor
4109 let mayLoad = 1, mayStore = 0 in
4110 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4111                   RegisterClass regtype, string asm>
4112     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4113                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4114       Sched<[WriteLD]>;
4115
4116 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4117                     RegisterClass regtype, string asm>
4118     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4119                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4120       Sched<[WriteLD]>;
4121
4122 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4123                        RegisterClass regtype, string asm>
4124     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4125                              (outs regtype:$Rt, regtype:$Rt2),
4126                              (ins GPR64sp0:$Rn), asm,
4127                              "\t$Rt, $Rt2, [$Rn]">,
4128       Sched<[WriteLD, WriteLDHi]> {
4129   bits<5> Rt;
4130   bits<5> Rt2;
4131   bits<5> Rn;
4132   let Inst{14-10} = Rt2;
4133   let Inst{9-5} = Rn;
4134   let Inst{4-0} = Rt;
4135
4136   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
4137 }
4138
4139 // Simple store release operations do not check the exclusive monitor.
4140 let mayLoad = 0, mayStore = 1 in
4141 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4142                    RegisterClass regtype, string asm>
4143     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
4144                                (ins regtype:$Rt, GPR64sp0:$Rn),
4145                                asm, "\t$Rt, [$Rn]">,
4146       Sched<[WriteST]>;
4147
4148 let mayLoad = 1, mayStore = 1 in
4149 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4150                      RegisterClass regtype, string asm>
4151     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
4152                              (ins regtype:$Rt, GPR64sp0:$Rn),
4153                              asm, "\t$Ws, $Rt, [$Rn]">,
4154       Sched<[WriteSTX]> {
4155   bits<5> Ws;
4156   bits<5> Rt;
4157   bits<5> Rn;
4158   let Inst{20-16} = Ws;
4159   let Inst{9-5} = Rn;
4160   let Inst{4-0} = Rt;
4161
4162   let Constraints = "@earlyclobber $Ws";
4163   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
4164 }
4165
4166 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4167                          RegisterClass regtype, string asm>
4168     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4169                              (outs GPR32:$Ws),
4170                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
4171                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
4172       Sched<[WriteSTX]> {
4173   bits<5> Ws;
4174   bits<5> Rt;
4175   bits<5> Rt2;
4176   bits<5> Rn;
4177   let Inst{20-16} = Ws;
4178   let Inst{14-10} = Rt2;
4179   let Inst{9-5} = Rn;
4180   let Inst{4-0} = Rt;
4181
4182   let Constraints = "@earlyclobber $Ws";
4183 }
4184
4185 // Armv8.5-A Memory Tagging Extension
4186 class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn,
4187                  string asm_opnds, string cstr, dag oops, dag iops>
4188     : I<oops, iops, asm_insn, asm_opnds, cstr, []>,
4189       Sched<[]> {
4190   bits<5> Rn;
4191
4192   let Inst{31-24} = 0b11011001;
4193   let Inst{23-22} = opc1;
4194   let Inst{21}    = 1;
4195   // Inst{20-12} defined by subclass
4196   let Inst{11-10} = opc2;
4197   let Inst{9-5}   = Rn;
4198   // Inst{4-0} defined by subclass
4199 }
4200
4201 class MemTagVector<bit Load, string asm_insn, string asm_opnds,
4202                    dag oops, dag iops>
4203     : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,
4204                   "", oops, iops> {
4205   bits<5> Rt;
4206
4207   let Inst{20-12} = 0b000000000;
4208   let Inst{4-0}   = Rt;
4209
4210   let mayLoad = Load;
4211 }
4212
4213 class MemTagLoad<string asm_insn, string asm_opnds>
4214     : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback",
4215                  (outs GPR64:$wback),
4216                  (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> {
4217   bits<5> Rt;
4218   bits<9> offset;
4219
4220   let Inst{20-12} = offset;
4221   let Inst{4-0}   = Rt;
4222
4223   let mayLoad = 1;
4224 }
4225
4226 class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn,
4227                      string asm_opnds, string cstr, dag oops, dag iops>
4228     : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> {
4229   bits<5> Rt;
4230   bits<9> offset;
4231
4232   let Inst{20-12} = offset;
4233   let Inst{4-0}   = Rt;
4234
4235   let mayStore = 1;
4236 }
4237
4238 multiclass MemTagStore<bits<2> opc1, string insn> {
4239   def Offset :
4240     BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",
4241                     (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4242   def PreIndex :
4243     BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",
4244                     "$Rn = $wback",
4245                     (outs GPR64sp:$wback),
4246                     (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4247   def PostIndex :
4248     BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",
4249                     "$Rn = $wback",
4250                     (outs GPR64sp:$wback),
4251                     (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4252
4253   def : InstAlias<insn # "\t$Rt, [$Rn]",
4254                   (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>;
4255 }
4256
4257 //---
4258 // Exception generation
4259 //---
4260
4261 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
4262 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
4263     : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>,
4264       Sched<[WriteSys]> {
4265   bits<16> imm;
4266   let Inst{31-24} = 0b11010100;
4267   let Inst{23-21} = op1;
4268   let Inst{20-5}  = imm;
4269   let Inst{4-2}   = 0b000;
4270   let Inst{1-0}   = ll;
4271 }
4272
4273 //---
4274 // UDF : Permanently UNDEFINED instructions.  Format: Opc = 0x0000, 16 bit imm.
4275 //--
4276 let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in {
4277 class UDFType<bits<16> opc, string asm>
4278   : I<(outs), (ins uimm16:$imm),
4279        asm, "\t$imm", "", []>,
4280     Sched<[]> {
4281   bits<16> imm;
4282   let Inst{31-16} = opc;
4283   let Inst{15-0} = imm;
4284 }
4285 }
4286 let Predicates = [HasFPARMv8] in {
4287
4288 //---
4289 // Floating point to integer conversion
4290 //---
4291
4292 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
4293                       RegisterClass srcType, RegisterClass dstType,
4294                       string asm, list<dag> pattern>
4295     : I<(outs dstType:$Rd), (ins srcType:$Rn),
4296          asm, "\t$Rd, $Rn", "", pattern>,
4297       Sched<[WriteFCvt]> {
4298   bits<5> Rd;
4299   bits<5> Rn;
4300   let Inst{30-29} = 0b00;
4301   let Inst{28-24} = 0b11110;
4302   let Inst{23-22} = type;
4303   let Inst{21}    = 1;
4304   let Inst{20-19} = rmode;
4305   let Inst{18-16} = opcode;
4306   let Inst{15-10} = 0;
4307   let Inst{9-5}   = Rn;
4308   let Inst{4-0}   = Rd;
4309 }
4310
4311 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4312 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
4313                       RegisterClass srcType, RegisterClass dstType,
4314                       Operand immType, string asm, list<dag> pattern>
4315     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4316          asm, "\t$Rd, $Rn, $scale", "", pattern>,
4317       Sched<[WriteFCvt]> {
4318   bits<5> Rd;
4319   bits<5> Rn;
4320   bits<6> scale;
4321   let Inst{30-29} = 0b00;
4322   let Inst{28-24} = 0b11110;
4323   let Inst{23-22} = type;
4324   let Inst{21}    = 0;
4325   let Inst{20-19} = rmode;
4326   let Inst{18-16} = opcode;
4327   let Inst{15-10} = scale;
4328   let Inst{9-5}   = Rn;
4329   let Inst{4-0}   = Rd;
4330 }
4331
4332 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
4333            SDPatternOperator OpN> {
4334   // Unscaled half-precision to 32-bit
4335   def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
4336                                      [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
4337     let Inst{31} = 0; // 32-bit GPR flag
4338     let Predicates = [HasFullFP16];
4339   }
4340
4341   // Unscaled half-precision to 64-bit
4342   def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
4343                                      [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
4344     let Inst{31} = 1; // 64-bit GPR flag
4345     let Predicates = [HasFullFP16];
4346   }
4347
4348   // Unscaled single-precision to 32-bit
4349   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
4350                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
4351     let Inst{31} = 0; // 32-bit GPR flag
4352   }
4353
4354   // Unscaled single-precision to 64-bit
4355   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
4356                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
4357     let Inst{31} = 1; // 64-bit GPR flag
4358   }
4359
4360   // Unscaled double-precision to 32-bit
4361   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
4362                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4363     let Inst{31} = 0; // 32-bit GPR flag
4364   }
4365
4366   // Unscaled double-precision to 64-bit
4367   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
4368                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4369     let Inst{31} = 1; // 64-bit GPR flag
4370   }
4371 }
4372
4373 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
4374                              SDPatternOperator OpN> {
4375   // Scaled half-precision to 32-bit
4376   def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
4377                               fixedpoint_f16_i32, asm,
4378               [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
4379                                           fixedpoint_f16_i32:$scale)))]> {
4380     let Inst{31} = 0; // 32-bit GPR flag
4381     let scale{5} = 1;
4382     let Predicates = [HasFullFP16];
4383   }
4384
4385   // Scaled half-precision to 64-bit
4386   def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
4387                               fixedpoint_f16_i64, asm,
4388               [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
4389                                           fixedpoint_f16_i64:$scale)))]> {
4390     let Inst{31} = 1; // 64-bit GPR flag
4391     let Predicates = [HasFullFP16];
4392   }
4393
4394   // Scaled single-precision to 32-bit
4395   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
4396                               fixedpoint_f32_i32, asm,
4397               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
4398                                           fixedpoint_f32_i32:$scale)))]> {
4399     let Inst{31} = 0; // 32-bit GPR flag
4400     let scale{5} = 1;
4401   }
4402
4403   // Scaled single-precision to 64-bit
4404   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
4405                               fixedpoint_f32_i64, asm,
4406               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
4407                                           fixedpoint_f32_i64:$scale)))]> {
4408     let Inst{31} = 1; // 64-bit GPR flag
4409   }
4410
4411   // Scaled double-precision to 32-bit
4412   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
4413                               fixedpoint_f64_i32, asm,
4414               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
4415                                           fixedpoint_f64_i32:$scale)))]> {
4416     let Inst{31} = 0; // 32-bit GPR flag
4417     let scale{5} = 1;
4418   }
4419
4420   // Scaled double-precision to 64-bit
4421   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
4422                               fixedpoint_f64_i64, asm,
4423               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
4424                                           fixedpoint_f64_i64:$scale)))]> {
4425     let Inst{31} = 1; // 64-bit GPR flag
4426   }
4427 }
4428
4429 //---
4430 // Integer to floating point conversion
4431 //---
4432
4433 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
4434 class BaseIntegerToFP<bit isUnsigned,
4435                       RegisterClass srcType, RegisterClass dstType,
4436                       Operand immType, string asm, list<dag> pattern>
4437     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4438          asm, "\t$Rd, $Rn, $scale", "", pattern>,
4439       Sched<[WriteFCvt]> {
4440   bits<5> Rd;
4441   bits<5> Rn;
4442   bits<6> scale;
4443   let Inst{30-24} = 0b0011110;
4444   let Inst{21-17} = 0b00001;
4445   let Inst{16}    = isUnsigned;
4446   let Inst{15-10} = scale;
4447   let Inst{9-5}   = Rn;
4448   let Inst{4-0}   = Rd;
4449 }
4450
4451 class BaseIntegerToFPUnscaled<bit isUnsigned,
4452                       RegisterClass srcType, RegisterClass dstType,
4453                       ValueType dvt, string asm, SDNode node>
4454     : I<(outs dstType:$Rd), (ins srcType:$Rn),
4455          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
4456       Sched<[WriteFCvt]> {
4457   bits<5> Rd;
4458   bits<5> Rn;
4459   bits<6> scale;
4460   let Inst{30-24} = 0b0011110;
4461   let Inst{21-17} = 0b10001;
4462   let Inst{16}    = isUnsigned;
4463   let Inst{15-10} = 0b000000;
4464   let Inst{9-5}   = Rn;
4465   let Inst{4-0}   = Rd;
4466 }
4467
4468 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
4469   // Unscaled
4470   def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
4471     let Inst{31} = 0; // 32-bit GPR flag
4472     let Inst{23-22} = 0b11; // 16-bit FPR flag
4473     let Predicates = [HasFullFP16];
4474   }
4475
4476   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
4477     let Inst{31} = 0; // 32-bit GPR flag
4478     let Inst{23-22} = 0b00; // 32-bit FPR flag
4479   }
4480
4481   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
4482     let Inst{31} = 0; // 32-bit GPR flag
4483     let Inst{23-22} = 0b01; // 64-bit FPR flag
4484   }
4485
4486   def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
4487     let Inst{31} = 1; // 64-bit GPR flag
4488     let Inst{23-22} = 0b11; // 16-bit FPR flag
4489     let Predicates = [HasFullFP16];
4490   }
4491
4492   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
4493     let Inst{31} = 1; // 64-bit GPR flag
4494     let Inst{23-22} = 0b00; // 32-bit FPR flag
4495   }
4496
4497   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
4498     let Inst{31} = 1; // 64-bit GPR flag
4499     let Inst{23-22} = 0b01; // 64-bit FPR flag
4500   }
4501
4502   // Scaled
4503   def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
4504                              [(set FPR16:$Rd,
4505                                    (fdiv (node GPR32:$Rn),
4506                                          fixedpoint_f16_i32:$scale))]> {
4507     let Inst{31} = 0; // 32-bit GPR flag
4508     let Inst{23-22} = 0b11; // 16-bit FPR flag
4509     let scale{5} = 1;
4510     let Predicates = [HasFullFP16];
4511   }
4512
4513   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
4514                              [(set FPR32:$Rd,
4515                                    (fdiv (node GPR32:$Rn),
4516                                          fixedpoint_f32_i32:$scale))]> {
4517     let Inst{31} = 0; // 32-bit GPR flag
4518     let Inst{23-22} = 0b00; // 32-bit FPR flag
4519     let scale{5} = 1;
4520   }
4521
4522   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
4523                              [(set FPR64:$Rd,
4524                                    (fdiv (node GPR32:$Rn),
4525                                          fixedpoint_f64_i32:$scale))]> {
4526     let Inst{31} = 0; // 32-bit GPR flag
4527     let Inst{23-22} = 0b01; // 64-bit FPR flag
4528     let scale{5} = 1;
4529   }
4530
4531   def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
4532                              [(set FPR16:$Rd,
4533                                    (fdiv (node GPR64:$Rn),
4534                                          fixedpoint_f16_i64:$scale))]> {
4535     let Inst{31} = 1; // 64-bit GPR flag
4536     let Inst{23-22} = 0b11; // 16-bit FPR flag
4537     let Predicates = [HasFullFP16];
4538   }
4539
4540   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
4541                              [(set FPR32:$Rd,
4542                                    (fdiv (node GPR64:$Rn),
4543                                          fixedpoint_f32_i64:$scale))]> {
4544     let Inst{31} = 1; // 64-bit GPR flag
4545     let Inst{23-22} = 0b00; // 32-bit FPR flag
4546   }
4547
4548   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
4549                              [(set FPR64:$Rd,
4550                                    (fdiv (node GPR64:$Rn),
4551                                          fixedpoint_f64_i64:$scale))]> {
4552     let Inst{31} = 1; // 64-bit GPR flag
4553     let Inst{23-22} = 0b01; // 64-bit FPR flag
4554   }
4555 }
4556
4557 //---
4558 // Unscaled integer <-> floating point conversion (i.e. FMOV)
4559 //---
4560
4561 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4562 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
4563                       RegisterClass srcType, RegisterClass dstType,
4564                       string asm>
4565     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
4566         // We use COPY_TO_REGCLASS for these bitconvert operations.
4567         // copyPhysReg() expands the resultant COPY instructions after
4568         // regalloc is done. This gives greater freedom for the allocator
4569         // and related passes (coalescing, copy propagation, et. al.) to
4570         // be more effective.
4571         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
4572       Sched<[WriteFCopy]> {
4573   bits<5> Rd;
4574   bits<5> Rn;
4575   let Inst{30-24} = 0b0011110;
4576   let Inst{21}    = 1;
4577   let Inst{20-19} = rmode;
4578   let Inst{18-16} = opcode;
4579   let Inst{15-10} = 0b000000;
4580   let Inst{9-5}   = Rn;
4581   let Inst{4-0}   = Rd;
4582 }
4583
4584 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4585 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
4586                      RegisterClass srcType, RegisterOperand dstType, string asm,
4587                      string kind>
4588     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4589         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
4590       Sched<[WriteFCopy]> {
4591   bits<5> Rd;
4592   bits<5> Rn;
4593   let Inst{30-23} = 0b00111101;
4594   let Inst{21}    = 1;
4595   let Inst{20-19} = rmode;
4596   let Inst{18-16} = opcode;
4597   let Inst{15-10} = 0b000000;
4598   let Inst{9-5}   = Rn;
4599   let Inst{4-0}   = Rd;
4600
4601   let DecoderMethod =  "DecodeFMOVLaneInstruction";
4602 }
4603
4604 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4605 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
4606                      RegisterOperand srcType, RegisterClass dstType, string asm,
4607                      string kind>
4608     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4609         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
4610       Sched<[WriteFCopy]> {
4611   bits<5> Rd;
4612   bits<5> Rn;
4613   let Inst{30-23} = 0b00111101;
4614   let Inst{21}    = 1;
4615   let Inst{20-19} = rmode;
4616   let Inst{18-16} = opcode;
4617   let Inst{15-10} = 0b000000;
4618   let Inst{9-5}   = Rn;
4619   let Inst{4-0}   = Rd;
4620
4621   let DecoderMethod =  "DecodeFMOVLaneInstruction";
4622 }
4623
4624
4625 multiclass UnscaledConversion<string asm> {
4626   def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
4627     let Inst{31} = 0; // 32-bit GPR flag
4628     let Inst{23-22} = 0b11; // 16-bit FPR flag
4629     let Predicates = [HasFullFP16];
4630   }
4631
4632   def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
4633     let Inst{31} = 1; // 64-bit GPR flag
4634     let Inst{23-22} = 0b11; // 16-bit FPR flag
4635     let Predicates = [HasFullFP16];
4636   }
4637
4638   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
4639     let Inst{31} = 0; // 32-bit GPR flag
4640     let Inst{23-22} = 0b00; // 32-bit FPR flag
4641   }
4642
4643   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
4644     let Inst{31} = 1; // 64-bit GPR flag
4645     let Inst{23-22} = 0b01; // 64-bit FPR flag
4646   }
4647
4648   def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
4649     let Inst{31} = 0; // 32-bit GPR flag
4650     let Inst{23-22} = 0b11; // 16-bit FPR flag
4651     let Predicates = [HasFullFP16];
4652   }
4653
4654   def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
4655     let Inst{31} = 1; // 64-bit GPR flag
4656     let Inst{23-22} = 0b11; // 16-bit FPR flag
4657     let Predicates = [HasFullFP16];
4658   }
4659
4660   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
4661     let Inst{31} = 0; // 32-bit GPR flag
4662     let Inst{23-22} = 0b00; // 32-bit FPR flag
4663   }
4664
4665   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
4666     let Inst{31} = 1; // 64-bit GPR flag
4667     let Inst{23-22} = 0b01; // 64-bit FPR flag
4668   }
4669
4670   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
4671                                              asm, ".d"> {
4672     let Inst{31} = 1;
4673     let Inst{22} = 0;
4674   }
4675
4676   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
4677                                                asm, ".d"> {
4678     let Inst{31} = 1;
4679     let Inst{22} = 0;
4680   }
4681 }
4682
4683 //---
4684 // Floating point conversion
4685 //---
4686
4687 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
4688                        RegisterClass srcType, string asm, list<dag> pattern>
4689     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
4690       Sched<[WriteFCvt]> {
4691   bits<5> Rd;
4692   bits<5> Rn;
4693   let Inst{31-24} = 0b00011110;
4694   let Inst{23-22} = type;
4695   let Inst{21-17} = 0b10001;
4696   let Inst{16-15} = opcode;
4697   let Inst{14-10} = 0b10000;
4698   let Inst{9-5}   = Rn;
4699   let Inst{4-0}   = Rd;
4700 }
4701
4702 multiclass FPConversion<string asm> {
4703   // Double-precision to Half-precision
4704   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4705                              [(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
4706
4707   // Double-precision to Single-precision
4708   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4709                              [(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
4710
4711   // Half-precision to Double-precision
4712   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
4713                              [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>;
4714
4715   // Half-precision to Single-precision
4716   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
4717                              [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>;
4718
4719   // Single-precision to Double-precision
4720   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
4721                              [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
4722
4723   // Single-precision to Half-precision
4724   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4725                              [(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
4726 }
4727
4728 //---
4729 // Single operand floating point data processing
4730 //---
4731
4732 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4733 class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype,
4734                               ValueType vt, string asm, SDPatternOperator node>
4735     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
4736          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
4737       Sched<[WriteF]> {
4738   bits<5> Rd;
4739   bits<5> Rn;
4740   let Inst{31-24} = 0b00011110;
4741   let Inst{21}    = 0b1;
4742   let Inst{20-15} = opcode;
4743   let Inst{14-10} = 0b10000;
4744   let Inst{9-5}   = Rn;
4745   let Inst{4-0}   = Rd;
4746 }
4747
4748 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4749                                SDPatternOperator node = null_frag> {
4750
4751   def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> {
4752     let Inst{23-22} = 0b11; // 16-bit size flag
4753     let Predicates = [HasFullFP16];
4754   }
4755
4756   def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {
4757     let Inst{23-22} = 0b00; // 32-bit size flag
4758   }
4759
4760   def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {
4761     let Inst{23-22} = 0b01; // 64-bit size flag
4762   }
4763 }
4764
4765 multiclass SingleOperandFPNo16<bits<6> opcode, string asm,
4766                   SDPatternOperator node = null_frag>{
4767
4768   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4769     let Inst{23-22} = 0b00; // 32-bit registers
4770   }
4771
4772   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4773     let Inst{23-22} = 0b01; // 64-bit registers
4774   }
4775 }
4776
4777 // FRInt[32|64][Z|N] instructions
4778 multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> :
4779       SingleOperandFPNo16<{0b0100,opcode}, asm, node>;
4780
4781 //---
4782 // Two operand floating point data processing
4783 //---
4784
4785 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4786 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4787                            string asm, list<dag> pat>
4788     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4789          asm, "\t$Rd, $Rn, $Rm", "", pat>,
4790       Sched<[WriteF]> {
4791   bits<5> Rd;
4792   bits<5> Rn;
4793   bits<5> Rm;
4794   let Inst{31-24} = 0b00011110;
4795   let Inst{21}    = 1;
4796   let Inst{20-16} = Rm;
4797   let Inst{15-12} = opcode;
4798   let Inst{11-10} = 0b10;
4799   let Inst{9-5}   = Rn;
4800   let Inst{4-0}   = Rd;
4801 }
4802
4803 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4804                             SDPatternOperator node = null_frag> {
4805   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4806                          [(set (f16 FPR16:$Rd),
4807                                (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4808     let Inst{23-22} = 0b11; // 16-bit size flag
4809     let Predicates = [HasFullFP16];
4810   }
4811
4812   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4813                          [(set (f32 FPR32:$Rd),
4814                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4815     let Inst{23-22} = 0b00; // 32-bit size flag
4816   }
4817
4818   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4819                          [(set (f64 FPR64:$Rd),
4820                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4821     let Inst{23-22} = 0b01; // 64-bit size flag
4822   }
4823 }
4824
4825 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4826   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4827                   [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4828     let Inst{23-22} = 0b11; // 16-bit size flag
4829     let Predicates = [HasFullFP16];
4830   }
4831
4832   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4833                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4834     let Inst{23-22} = 0b00; // 32-bit size flag
4835   }
4836
4837   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4838                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4839     let Inst{23-22} = 0b01; // 64-bit size flag
4840   }
4841 }
4842
4843
4844 //---
4845 // Three operand floating point data processing
4846 //---
4847
4848 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4849                              RegisterClass regtype, string asm, list<dag> pat>
4850     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4851          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4852       Sched<[WriteFMul]> {
4853   bits<5> Rd;
4854   bits<5> Rn;
4855   bits<5> Rm;
4856   bits<5> Ra;
4857   let Inst{31-24} = 0b00011111;
4858   let Inst{21}    = isNegated;
4859   let Inst{20-16} = Rm;
4860   let Inst{15}    = isSub;
4861   let Inst{14-10} = Ra;
4862   let Inst{9-5}   = Rn;
4863   let Inst{4-0}   = Rd;
4864 }
4865
4866 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4867                               SDPatternOperator node> {
4868   def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4869             [(set FPR16:$Rd,
4870                   (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4871     let Inst{23-22} = 0b11; // 16-bit size flag
4872     let Predicates = [HasFullFP16];
4873   }
4874
4875   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4876             [(set FPR32:$Rd,
4877                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4878     let Inst{23-22} = 0b00; // 32-bit size flag
4879   }
4880
4881   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4882             [(set FPR64:$Rd,
4883                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
4884     let Inst{23-22} = 0b01; // 64-bit size flag
4885   }
4886 }
4887
4888 //---
4889 // Floating point data comparisons
4890 //---
4891
4892 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4893 class BaseOneOperandFPComparison<bit signalAllNans,
4894                                  RegisterClass regtype, string asm,
4895                                  list<dag> pat>
4896     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4897       Sched<[WriteFCmp]> {
4898   bits<5> Rn;
4899   let Inst{31-24} = 0b00011110;
4900   let Inst{21}    = 1;
4901
4902   let Inst{15-10} = 0b001000;
4903   let Inst{9-5}   = Rn;
4904   let Inst{4}     = signalAllNans;
4905   let Inst{3-0}   = 0b1000;
4906
4907   // Rm should be 0b00000 canonically, but we need to accept any value.
4908   let PostEncoderMethod = "fixOneOperandFPComparison";
4909 }
4910
4911 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4912 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4913                                 string asm, list<dag> pat>
4914     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4915       Sched<[WriteFCmp]> {
4916   bits<5> Rm;
4917   bits<5> Rn;
4918   let Inst{31-24} = 0b00011110;
4919   let Inst{21}    = 1;
4920   let Inst{20-16} = Rm;
4921   let Inst{15-10} = 0b001000;
4922   let Inst{9-5}   = Rn;
4923   let Inst{4}     = signalAllNans;
4924   let Inst{3-0}   = 0b0000;
4925 }
4926
4927 multiclass FPComparison<bit signalAllNans, string asm,
4928                         SDPatternOperator OpNode = null_frag> {
4929   let Defs = [NZCV] in {
4930   def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4931       [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4932     let Inst{23-22} = 0b11;
4933     let Predicates = [HasFullFP16];
4934   }
4935
4936   def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4937       [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4938     let Inst{23-22} = 0b11;
4939     let Predicates = [HasFullFP16];
4940   }
4941
4942   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4943       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4944     let Inst{23-22} = 0b00;
4945   }
4946
4947   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4948       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4949     let Inst{23-22} = 0b00;
4950   }
4951
4952   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4953       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4954     let Inst{23-22} = 0b01;
4955   }
4956
4957   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4958       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4959     let Inst{23-22} = 0b01;
4960   }
4961   } // Defs = [NZCV]
4962 }
4963
4964 //---
4965 // Floating point conditional comparisons
4966 //---
4967
4968 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4969 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4970                            string mnemonic, list<dag> pat>
4971     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4972          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4973       Sched<[WriteFCmp]> {
4974   let Uses = [NZCV];
4975   let Defs = [NZCV];
4976
4977   bits<5> Rn;
4978   bits<5> Rm;
4979   bits<4> nzcv;
4980   bits<4> cond;
4981
4982   let Inst{31-24} = 0b00011110;
4983   let Inst{21}    = 1;
4984   let Inst{20-16} = Rm;
4985   let Inst{15-12} = cond;
4986   let Inst{11-10} = 0b01;
4987   let Inst{9-5}   = Rn;
4988   let Inst{4}     = signalAllNans;
4989   let Inst{3-0}   = nzcv;
4990 }
4991
4992 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4993                             SDPatternOperator OpNode = null_frag> {
4994   def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,
4995       [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),
4996                           (i32 imm:$cond), NZCV))]> {
4997     let Inst{23-22} = 0b11;
4998     let Predicates = [HasFullFP16];
4999   }
5000
5001   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
5002       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
5003                           (i32 imm:$cond), NZCV))]> {
5004     let Inst{23-22} = 0b00;
5005   }
5006
5007   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
5008       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
5009                           (i32 imm:$cond), NZCV))]> {
5010     let Inst{23-22} = 0b01;
5011   }
5012 }
5013
5014 //---
5015 // Floating point conditional select
5016 //---
5017
5018 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
5019     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
5020          asm, "\t$Rd, $Rn, $Rm, $cond", "",
5021          [(set regtype:$Rd,
5022                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
5023                           (i32 imm:$cond), NZCV))]>,
5024       Sched<[WriteF]> {
5025   bits<5> Rd;
5026   bits<5> Rn;
5027   bits<5> Rm;
5028   bits<4> cond;
5029
5030   let Inst{31-24} = 0b00011110;
5031   let Inst{21}    = 1;
5032   let Inst{20-16} = Rm;
5033   let Inst{15-12} = cond;
5034   let Inst{11-10} = 0b11;
5035   let Inst{9-5}   = Rn;
5036   let Inst{4-0}   = Rd;
5037 }
5038
5039 multiclass FPCondSelect<string asm> {
5040   let Uses = [NZCV] in {
5041   def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
5042     let Inst{23-22} = 0b11;
5043     let Predicates = [HasFullFP16];
5044   }
5045
5046   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
5047     let Inst{23-22} = 0b00;
5048   }
5049
5050   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
5051     let Inst{23-22} = 0b01;
5052   }
5053   } // Uses = [NZCV]
5054 }
5055
5056 //---
5057 // Floating move immediate
5058 //---
5059
5060 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
5061   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
5062       [(set regtype:$Rd, fpimmtype:$imm)]>,
5063     Sched<[WriteFImm]> {
5064   bits<5> Rd;
5065   bits<8> imm;
5066   let Inst{31-24} = 0b00011110;
5067   let Inst{21}    = 1;
5068   let Inst{20-13} = imm;
5069   let Inst{12-5}  = 0b10000000;
5070   let Inst{4-0}   = Rd;
5071 }
5072
5073 multiclass FPMoveImmediate<string asm> {
5074   def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
5075     let Inst{23-22} = 0b11;
5076     let Predicates = [HasFullFP16];
5077   }
5078
5079   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
5080     let Inst{23-22} = 0b00;
5081   }
5082
5083   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
5084     let Inst{23-22} = 0b01;
5085   }
5086 }
5087 } // end of 'let Predicates = [HasFPARMv8]'
5088
5089 //----------------------------------------------------------------------------
5090 // AdvSIMD
5091 //----------------------------------------------------------------------------
5092
5093 let Predicates = [HasNEON] in {
5094
5095 //----------------------------------------------------------------------------
5096 // AdvSIMD three register vector instructions
5097 //----------------------------------------------------------------------------
5098
5099 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5100 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
5101                         RegisterOperand regtype, string asm, string kind,
5102                         list<dag> pattern>
5103   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5104       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5105       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
5106     Sched<[WriteV]> {
5107   bits<5> Rd;
5108   bits<5> Rn;
5109   bits<5> Rm;
5110   let Inst{31}    = 0;
5111   let Inst{30}    = Q;
5112   let Inst{29}    = U;
5113   let Inst{28-24} = 0b01110;
5114   let Inst{23-21} = size;
5115   let Inst{20-16} = Rm;
5116   let Inst{15-11} = opcode;
5117   let Inst{10}    = 1;
5118   let Inst{9-5}   = Rn;
5119   let Inst{4-0}   = Rd;
5120 }
5121
5122 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5123 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
5124                         RegisterOperand regtype, string asm, string kind,
5125                         list<dag> pattern>
5126   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
5127       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5128       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5129     Sched<[WriteV]> {
5130   bits<5> Rd;
5131   bits<5> Rn;
5132   bits<5> Rm;
5133   let Inst{31}    = 0;
5134   let Inst{30}    = Q;
5135   let Inst{29}    = U;
5136   let Inst{28-24} = 0b01110;
5137   let Inst{23-21} = size;
5138   let Inst{20-16} = Rm;
5139   let Inst{15-11} = opcode;
5140   let Inst{10}    = 1;
5141   let Inst{9-5}   = Rn;
5142   let Inst{4-0}   = Rd;
5143 }
5144
5145 // All operand sizes distinguished in the encoding.
5146 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
5147                                SDPatternOperator OpNode> {
5148   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5149                                       asm, ".8b",
5150          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5151   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5152                                       asm, ".16b",
5153          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5154   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5155                                       asm, ".4h",
5156          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5157   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5158                                       asm, ".8h",
5159          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5160   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5161                                       asm, ".2s",
5162          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5163   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5164                                       asm, ".4s",
5165          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5166   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
5167                                       asm, ".2d",
5168          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5169 }
5170
5171 multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> {
5172   def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)),
5173           (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>;
5174   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5175           (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>;
5176   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5177           (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>;
5178
5179   def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)),
5180           (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>;
5181   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5182           (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>;
5183   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5184           (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>;
5185   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5186           (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>;
5187 }
5188
5189 // As above, but D sized elements unsupported.
5190 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
5191                                   SDPatternOperator OpNode> {
5192   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5193                                       asm, ".8b",
5194         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
5195   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5196                                       asm, ".16b",
5197         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
5198   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5199                                       asm, ".4h",
5200         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
5201   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5202                                       asm, ".8h",
5203         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
5204   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5205                                       asm, ".2s",
5206         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
5207   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5208                                       asm, ".4s",
5209         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
5210 }
5211
5212 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
5213                                   SDPatternOperator OpNode> {
5214   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
5215                                       asm, ".8b",
5216       [(set (v8i8 V64:$dst),
5217             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5218   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
5219                                       asm, ".16b",
5220       [(set (v16i8 V128:$dst),
5221             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5222   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
5223                                       asm, ".4h",
5224       [(set (v4i16 V64:$dst),
5225             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5226   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
5227                                       asm, ".8h",
5228       [(set (v8i16 V128:$dst),
5229             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5230   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
5231                                       asm, ".2s",
5232       [(set (v2i32 V64:$dst),
5233             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5234   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
5235                                       asm, ".4s",
5236       [(set (v4i32 V128:$dst),
5237             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5238 }
5239
5240 // As above, but only B sized elements supported.
5241 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
5242                                 SDPatternOperator OpNode> {
5243   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5244                                       asm, ".8b",
5245     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5246   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5247                                       asm, ".16b",
5248     [(set (v16i8 V128:$Rd),
5249           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5250 }
5251
5252 // As above, but only floating point elements supported.
5253 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
5254                                  string asm, SDPatternOperator OpNode> {
5255   let Predicates = [HasNEON, HasFullFP16] in {
5256   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5257                                       asm, ".4h",
5258         [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5259   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5260                                       asm, ".8h",
5261         [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5262   } // Predicates = [HasNEON, HasFullFP16]
5263   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5264                                       asm, ".2s",
5265         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5266   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5267                                       asm, ".4s",
5268         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5269   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5270                                       asm, ".2d",
5271         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5272 }
5273
5274 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
5275                                     string asm,
5276                                     SDPatternOperator OpNode> {
5277   let Predicates = [HasNEON, HasFullFP16] in {
5278   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5279                                       asm, ".4h",
5280         [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5281   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5282                                       asm, ".8h",
5283         [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5284   } // Predicates = [HasNEON, HasFullFP16]
5285   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5286                                       asm, ".2s",
5287         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5288   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5289                                       asm, ".4s",
5290         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5291   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5292                                       asm, ".2d",
5293         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5294 }
5295
5296 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
5297                                  string asm, SDPatternOperator OpNode> {
5298   let Predicates = [HasNEON, HasFullFP16] in {
5299   def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
5300                                       asm, ".4h",
5301      [(set (v4f16 V64:$dst),
5302            (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5303   def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
5304                                       asm, ".8h",
5305      [(set (v8f16 V128:$dst),
5306            (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5307   } // Predicates = [HasNEON, HasFullFP16]
5308   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
5309                                       asm, ".2s",
5310      [(set (v2f32 V64:$dst),
5311            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5312   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
5313                                       asm, ".4s",
5314      [(set (v4f32 V128:$dst),
5315            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5316   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
5317                                       asm, ".2d",
5318      [(set (v2f64 V128:$dst),
5319            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5320 }
5321
5322 // As above, but D and B sized elements unsupported.
5323 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
5324                                 SDPatternOperator OpNode> {
5325   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5326                                       asm, ".4h",
5327         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5328   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5329                                       asm, ".8h",
5330         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5331   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5332                                       asm, ".2s",
5333         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5334   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5335                                       asm, ".4s",
5336         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5337 }
5338
5339 // Logical three vector ops share opcode bits, and only use B sized elements.
5340 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
5341                                   SDPatternOperator OpNode = null_frag> {
5342   def v8i8  : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
5343                                      asm, ".8b",
5344                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
5345   def v16i8  : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
5346                                      asm, ".16b",
5347                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
5348
5349   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5350           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5351   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5352           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5353   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
5354           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5355
5356   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5357       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5358   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5359       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5360   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5361       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5362 }
5363
5364 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
5365                                   string asm, SDPatternOperator OpNode> {
5366   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
5367                                      asm, ".8b",
5368              [(set (v8i8 V64:$dst),
5369                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5370   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
5371                                      asm, ".16b",
5372              [(set (v16i8 V128:$dst),
5373                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5374                            (v16i8 V128:$Rm)))]>;
5375
5376   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5377                            (v4i16 V64:$RHS))),
5378           (!cast<Instruction>(NAME#"v8i8")
5379             V64:$LHS, V64:$MHS, V64:$RHS)>;
5380   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5381                            (v2i32 V64:$RHS))),
5382           (!cast<Instruction>(NAME#"v8i8")
5383             V64:$LHS, V64:$MHS, V64:$RHS)>;
5384   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5385                            (v1i64 V64:$RHS))),
5386           (!cast<Instruction>(NAME#"v8i8")
5387             V64:$LHS, V64:$MHS, V64:$RHS)>;
5388
5389   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5390                            (v8i16 V128:$RHS))),
5391       (!cast<Instruction>(NAME#"v16i8")
5392         V128:$LHS, V128:$MHS, V128:$RHS)>;
5393   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5394                            (v4i32 V128:$RHS))),
5395       (!cast<Instruction>(NAME#"v16i8")
5396         V128:$LHS, V128:$MHS, V128:$RHS)>;
5397   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5398                            (v2i64 V128:$RHS))),
5399       (!cast<Instruction>(NAME#"v16i8")
5400         V128:$LHS, V128:$MHS, V128:$RHS)>;
5401 }
5402
5403 // ARMv8.2-A Dot Product Instructions (Vector): These instructions extract
5404 // bytes from S-sized elements.
5405 class BaseSIMDThreeSameVectorDot<bit Q, bit U, string asm, string kind1,
5406                                  string kind2, RegisterOperand RegType,
5407                                  ValueType AccumType, ValueType InputType,
5408                                  SDPatternOperator OpNode> :
5409         BaseSIMDThreeSameVectorTied<Q, U, 0b100, 0b10010, RegType, asm, kind1,
5410         [(set (AccumType RegType:$dst),
5411               (OpNode (AccumType RegType:$Rd),
5412                       (InputType RegType:$Rn),
5413                       (InputType RegType:$Rm)))]> {
5414   let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5415 }
5416
5417 multiclass SIMDThreeSameVectorDot<bit U, string asm, SDPatternOperator OpNode> {
5418   def v8i8  : BaseSIMDThreeSameVectorDot<0, U, asm, ".2s", ".8b", V64,
5419                                          v2i32, v8i8, OpNode>;
5420   def v16i8 : BaseSIMDThreeSameVectorDot<1, U, asm, ".4s", ".16b", V128,
5421                                          v4i32, v16i8, OpNode>;
5422 }
5423
5424 // ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions
5425 // select inputs from 4H vectors and accumulate outputs to a 2S vector (or from
5426 // 8H to 4S, when Q=1).
5427 class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1,
5428                                  string kind2, RegisterOperand RegType,
5429                                  ValueType AccumType, ValueType InputType,
5430                                  SDPatternOperator OpNode> :
5431         BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1,
5432                 [(set (AccumType RegType:$dst),
5433               (OpNode (AccumType RegType:$Rd),
5434                       (InputType RegType:$Rn),
5435                       (InputType RegType:$Rm)))]> {
5436   let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5437   let Inst{13} = b13;
5438 }
5439
5440 multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,
5441                                   SDPatternOperator OpNode> {
5442   def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64,
5443                                          v2f32, v4f16, OpNode>;
5444   def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128,
5445                                          v4f32, v8f16, OpNode>;
5446 }
5447
5448
5449 //----------------------------------------------------------------------------
5450 // AdvSIMD two register vector instructions.
5451 //----------------------------------------------------------------------------
5452
5453 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5454 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5455                             bits<2> size2, RegisterOperand regtype, string asm,
5456                             string dstkind, string srckind, list<dag> pattern>
5457   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5458       "{\t$Rd" # dstkind # ", $Rn" # srckind #
5459       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
5460     Sched<[WriteV]> {
5461   bits<5> Rd;
5462   bits<5> Rn;
5463   let Inst{31}    = 0;
5464   let Inst{30}    = Q;
5465   let Inst{29}    = U;
5466   let Inst{28-24} = 0b01110;
5467   let Inst{23-22} = size;
5468   let Inst{21} = 0b1;
5469   let Inst{20-19} = size2;
5470   let Inst{18-17} = 0b00;
5471   let Inst{16-12} = opcode;
5472   let Inst{11-10} = 0b10;
5473   let Inst{9-5}   = Rn;
5474   let Inst{4-0}   = Rd;
5475 }
5476
5477 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5478 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5479                                 bits<2> size2, RegisterOperand regtype,
5480                                 string asm, string dstkind, string srckind,
5481                                 list<dag> pattern>
5482   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
5483       "{\t$Rd" # dstkind # ", $Rn" # srckind #
5484       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5485     Sched<[WriteV]> {
5486   bits<5> Rd;
5487   bits<5> Rn;
5488   let Inst{31}    = 0;
5489   let Inst{30}    = Q;
5490   let Inst{29}    = U;
5491   let Inst{28-24} = 0b01110;
5492   let Inst{23-22} = size;
5493   let Inst{21} = 0b1;
5494   let Inst{20-19} = size2;
5495   let Inst{18-17} = 0b00;
5496   let Inst{16-12} = opcode;
5497   let Inst{11-10} = 0b10;
5498   let Inst{9-5}   = Rn;
5499   let Inst{4-0}   = Rd;
5500 }
5501
5502 // Supports B, H, and S element sizes.
5503 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
5504                             SDPatternOperator OpNode> {
5505   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5506                                       asm, ".8b", ".8b",
5507                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5508   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5509                                       asm, ".16b", ".16b",
5510                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5511   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5512                                       asm, ".4h", ".4h",
5513                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5514   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5515                                       asm, ".8h", ".8h",
5516                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5517   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5518                                       asm, ".2s", ".2s",
5519                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5520   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5521                                       asm, ".4s", ".4s",
5522                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5523 }
5524
5525 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
5526                             RegisterOperand regtype, string asm, string dstkind,
5527                             string srckind, string amount>
5528   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
5529       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
5530       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
5531     Sched<[WriteV]> {
5532   bits<5> Rd;
5533   bits<5> Rn;
5534   let Inst{31}    = 0;
5535   let Inst{30}    = Q;
5536   let Inst{29-24} = 0b101110;
5537   let Inst{23-22} = size;
5538   let Inst{21-10} = 0b100001001110;
5539   let Inst{9-5}   = Rn;
5540   let Inst{4-0}   = Rd;
5541 }
5542
5543 multiclass SIMDVectorLShiftLongBySizeBHS {
5544   let hasSideEffects = 0 in {
5545   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
5546                                              "shll", ".8h",  ".8b", "8">;
5547   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
5548                                              "shll2", ".8h", ".16b", "8">;
5549   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
5550                                              "shll", ".4s",  ".4h", "16">;
5551   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
5552                                              "shll2", ".4s", ".8h", "16">;
5553   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
5554                                              "shll", ".2d",  ".2s", "32">;
5555   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
5556                                              "shll2", ".2d", ".4s", "32">;
5557   }
5558 }
5559
5560 // Supports all element sizes.
5561 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
5562                              SDPatternOperator OpNode> {
5563   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5564                                       asm, ".4h", ".8b",
5565                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5566   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5567                                       asm, ".8h", ".16b",
5568                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5569   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5570                                       asm, ".2s", ".4h",
5571                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5572   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5573                                       asm, ".4s", ".8h",
5574                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5575   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5576                                       asm, ".1d", ".2s",
5577                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5578   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5579                                       asm, ".2d", ".4s",
5580                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5581 }
5582
5583 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
5584                                  SDPatternOperator OpNode> {
5585   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5586                                           asm, ".4h", ".8b",
5587       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
5588                                       (v8i8 V64:$Rn)))]>;
5589   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5590                                           asm, ".8h", ".16b",
5591       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
5592                                       (v16i8 V128:$Rn)))]>;
5593   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5594                                           asm, ".2s", ".4h",
5595       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
5596                                       (v4i16 V64:$Rn)))]>;
5597   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5598                                           asm, ".4s", ".8h",
5599       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
5600                                       (v8i16 V128:$Rn)))]>;
5601   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5602                                           asm, ".1d", ".2s",
5603       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
5604                                       (v2i32 V64:$Rn)))]>;
5605   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5606                                           asm, ".2d", ".4s",
5607       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
5608                                       (v4i32 V128:$Rn)))]>;
5609 }
5610
5611 // Supports all element sizes, except 1xD.
5612 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
5613                                   SDPatternOperator OpNode> {
5614   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5615                                     asm, ".8b", ".8b",
5616     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
5617   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5618                                     asm, ".16b", ".16b",
5619     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
5620   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5621                                     asm, ".4h", ".4h",
5622     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
5623   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5624                                     asm, ".8h", ".8h",
5625     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
5626   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5627                                     asm, ".2s", ".2s",
5628     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
5629   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5630                                     asm, ".4s", ".4s",
5631     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
5632   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
5633                                     asm, ".2d", ".2d",
5634     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
5635 }
5636
5637 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
5638                              SDPatternOperator OpNode = null_frag> {
5639   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5640                                 asm, ".8b", ".8b",
5641     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5642   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5643                                 asm, ".16b", ".16b",
5644     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5645   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5646                                 asm, ".4h", ".4h",
5647     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5648   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5649                                 asm, ".8h", ".8h",
5650     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5651   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5652                                 asm, ".2s", ".2s",
5653     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5654   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5655                                 asm, ".4s", ".4s",
5656     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5657   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5658                                 asm, ".2d", ".2d",
5659     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5660 }
5661
5662
5663 // Supports only B element sizes.
5664 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5665                           SDPatternOperator OpNode> {
5666   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5667                                 asm, ".8b", ".8b",
5668                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5669   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5670                                 asm, ".16b", ".16b",
5671                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5672
5673 }
5674
5675 // Supports only B and H element sizes.
5676 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5677                                 SDPatternOperator OpNode> {
5678   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5679                                 asm, ".8b", ".8b",
5680                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5681   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5682                                 asm, ".16b", ".16b",
5683                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5684   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5685                                 asm, ".4h", ".4h",
5686                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5687   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5688                                 asm, ".8h", ".8h",
5689                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5690 }
5691
5692 // Supports H, S and D element sizes, uses high bit of the size field
5693 // as an extra opcode bit.
5694 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5695                            SDPatternOperator OpNode> {
5696   let Predicates = [HasNEON, HasFullFP16] in {
5697   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5698                                 asm, ".4h", ".4h",
5699                           [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5700   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5701                                 asm, ".8h", ".8h",
5702                           [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5703   } // Predicates = [HasNEON, HasFullFP16]
5704   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5705                                 asm, ".2s", ".2s",
5706                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5707   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5708                                 asm, ".4s", ".4s",
5709                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5710   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5711                                 asm, ".2d", ".2d",
5712                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5713 }
5714
5715 // Supports only S and D element sizes
5716 multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm,
5717                            SDPatternOperator OpNode = null_frag> {
5718
5719   def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64,
5720                                 asm, ".2s", ".2s",
5721                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5722   def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,
5723                                 asm, ".4s", ".4s",
5724                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5725   def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,
5726                                 asm, ".2d", ".2d",
5727                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5728 }
5729
5730 multiclass FRIntNNTVector<bit U, bit op, string asm,
5731                           SDPatternOperator OpNode = null_frag> :
5732            SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>;
5733
5734 // Supports only S element size.
5735 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5736                            SDPatternOperator OpNode> {
5737   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5738                                 asm, ".2s", ".2s",
5739                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5740   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5741                                 asm, ".4s", ".4s",
5742                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5743 }
5744
5745
5746 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5747                            SDPatternOperator OpNode> {
5748   let Predicates = [HasNEON, HasFullFP16] in {
5749   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5750                                 asm, ".4h", ".4h",
5751                           [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5752   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5753                                 asm, ".8h", ".8h",
5754                           [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5755   } // Predicates = [HasNEON, HasFullFP16]
5756   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5757                                 asm, ".2s", ".2s",
5758                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5759   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5760                                 asm, ".4s", ".4s",
5761                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5762   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5763                                 asm, ".2d", ".2d",
5764                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5765 }
5766
5767 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
5768                            SDPatternOperator OpNode> {
5769   let Predicates = [HasNEON, HasFullFP16] in {
5770   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5771                                 asm, ".4h", ".4h",
5772                           [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5773   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5774                                 asm, ".8h", ".8h",
5775                           [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5776   } // Predicates = [HasNEON, HasFullFP16]
5777   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5778                                 asm, ".2s", ".2s",
5779                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5780   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5781                                 asm, ".4s", ".4s",
5782                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5783   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5784                                 asm, ".2d", ".2d",
5785                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5786 }
5787
5788
5789 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5790                            RegisterOperand inreg, RegisterOperand outreg,
5791                            string asm, string outkind, string inkind,
5792                            list<dag> pattern>
5793   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
5794       "{\t$Rd" # outkind # ", $Rn" # inkind #
5795       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
5796     Sched<[WriteV]> {
5797   bits<5> Rd;
5798   bits<5> Rn;
5799   let Inst{31}    = 0;
5800   let Inst{30}    = Q;
5801   let Inst{29}    = U;
5802   let Inst{28-24} = 0b01110;
5803   let Inst{23-22} = size;
5804   let Inst{21-17} = 0b10000;
5805   let Inst{16-12} = opcode;
5806   let Inst{11-10} = 0b10;
5807   let Inst{9-5}   = Rn;
5808   let Inst{4-0}   = Rd;
5809 }
5810
5811 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5812                            RegisterOperand inreg, RegisterOperand outreg,
5813                            string asm, string outkind, string inkind,
5814                            list<dag> pattern>
5815   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
5816       "{\t$Rd" # outkind # ", $Rn" # inkind #
5817       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5818     Sched<[WriteV]> {
5819   bits<5> Rd;
5820   bits<5> Rn;
5821   let Inst{31}    = 0;
5822   let Inst{30}    = Q;
5823   let Inst{29}    = U;
5824   let Inst{28-24} = 0b01110;
5825   let Inst{23-22} = size;
5826   let Inst{21-17} = 0b10000;
5827   let Inst{16-12} = opcode;
5828   let Inst{11-10} = 0b10;
5829   let Inst{9-5}   = Rn;
5830   let Inst{4-0}   = Rd;
5831 }
5832
5833 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
5834                               SDPatternOperator OpNode> {
5835   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
5836                                       asm, ".8b", ".8h",
5837         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5838   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
5839                                       asm#"2", ".16b", ".8h", []>;
5840   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
5841                                       asm, ".4h", ".4s",
5842         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5843   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
5844                                       asm#"2", ".8h", ".4s", []>;
5845   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
5846                                       asm, ".2s", ".2d",
5847         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5848   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
5849                                       asm#"2", ".4s", ".2d", []>;
5850
5851   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
5852             (!cast<Instruction>(NAME # "v16i8")
5853                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5854   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
5855             (!cast<Instruction>(NAME # "v8i16")
5856                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5857   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
5858             (!cast<Instruction>(NAME # "v4i32")
5859                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5860 }
5861
5862 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
5863                            bits<5> opcode, RegisterOperand regtype, string asm,
5864                            string kind, string zero, ValueType dty,
5865                            ValueType sty, SDNode OpNode>
5866   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5867       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5868       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5869       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5870     Sched<[WriteV]> {
5871   bits<5> Rd;
5872   bits<5> Rn;
5873   let Inst{31}    = 0;
5874   let Inst{30}    = Q;
5875   let Inst{29}    = U;
5876   let Inst{28-24} = 0b01110;
5877   let Inst{23-22} = size;
5878   let Inst{21} = 0b1;
5879   let Inst{20-19} = size2;
5880   let Inst{18-17} = 0b00;
5881   let Inst{16-12} = opcode;
5882   let Inst{11-10} = 0b10;
5883   let Inst{9-5}   = Rn;
5884   let Inst{4-0}   = Rd;
5885 }
5886
5887 // Comparisons support all element sizes, except 1xD.
5888 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5889                             SDNode OpNode> {
5890   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
5891                                      asm, ".8b", "0",
5892                                      v8i8, v8i8, OpNode>;
5893   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
5894                                      asm, ".16b", "0",
5895                                      v16i8, v16i8, OpNode>;
5896   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
5897                                      asm, ".4h", "0",
5898                                      v4i16, v4i16, OpNode>;
5899   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
5900                                      asm, ".8h", "0",
5901                                      v8i16, v8i16, OpNode>;
5902   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
5903                                      asm, ".2s", "0",
5904                                      v2i32, v2i32, OpNode>;
5905   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
5906                                      asm, ".4s", "0",
5907                                      v4i32, v4i32, OpNode>;
5908   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
5909                                      asm, ".2d", "0",
5910                                      v2i64, v2i64, OpNode>;
5911 }
5912
5913 // FP Comparisons support only S and D element sizes (and H for v8.2a).
5914 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5915                               string asm, SDNode OpNode> {
5916
5917   let Predicates = [HasNEON, HasFullFP16] in {
5918   def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5919                                      asm, ".4h", "0.0",
5920                                      v4i16, v4f16, OpNode>;
5921   def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5922                                      asm, ".8h", "0.0",
5923                                      v8i16, v8f16, OpNode>;
5924   } // Predicates = [HasNEON, HasFullFP16]
5925   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
5926                                      asm, ".2s", "0.0",
5927                                      v2i32, v2f32, OpNode>;
5928   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
5929                                      asm, ".4s", "0.0",
5930                                      v4i32, v4f32, OpNode>;
5931   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
5932                                      asm, ".2d", "0.0",
5933                                      v2i64, v2f64, OpNode>;
5934
5935   let Predicates = [HasNEON, HasFullFP16] in {
5936   def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5937                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5938   def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5939                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5940   }
5941   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
5942                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5943   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
5944                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5945   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
5946                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5947   let Predicates = [HasNEON, HasFullFP16] in {
5948   def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5949                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5950   def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5951                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5952   }
5953   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
5954                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5955   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
5956                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5957   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
5958                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5959 }
5960
5961 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5962 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5963                              RegisterOperand outtype, RegisterOperand intype,
5964                              string asm, string VdTy, string VnTy,
5965                              list<dag> pattern>
5966   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5967       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5968     Sched<[WriteV]> {
5969   bits<5> Rd;
5970   bits<5> Rn;
5971   let Inst{31}    = 0;
5972   let Inst{30}    = Q;
5973   let Inst{29}    = U;
5974   let Inst{28-24} = 0b01110;
5975   let Inst{23-22} = size;
5976   let Inst{21-17} = 0b10000;
5977   let Inst{16-12} = opcode;
5978   let Inst{11-10} = 0b10;
5979   let Inst{9-5}   = Rn;
5980   let Inst{4-0}   = Rd;
5981 }
5982
5983 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5984                              RegisterOperand outtype, RegisterOperand intype,
5985                              string asm, string VdTy, string VnTy,
5986                              list<dag> pattern>
5987   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5988       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5989     Sched<[WriteV]> {
5990   bits<5> Rd;
5991   bits<5> Rn;
5992   let Inst{31}    = 0;
5993   let Inst{30}    = Q;
5994   let Inst{29}    = U;
5995   let Inst{28-24} = 0b01110;
5996   let Inst{23-22} = size;
5997   let Inst{21-17} = 0b10000;
5998   let Inst{16-12} = opcode;
5999   let Inst{11-10} = 0b10;
6000   let Inst{9-5}   = Rn;
6001   let Inst{4-0}   = Rd;
6002 }
6003
6004 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
6005   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
6006                                     asm, ".4s", ".4h", []>;
6007   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
6008                                     asm#"2", ".4s", ".8h", []>;
6009   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
6010                                     asm, ".2d", ".2s", []>;
6011   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
6012                                     asm#"2", ".2d", ".4s", []>;
6013 }
6014
6015 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
6016   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
6017                                     asm, ".4h", ".4s", []>;
6018   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
6019                                     asm#"2", ".8h", ".4s", []>;
6020   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6021                                     asm, ".2s", ".2d", []>;
6022   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6023                                     asm#"2", ".4s", ".2d", []>;
6024 }
6025
6026 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
6027                                      Intrinsic OpNode> {
6028   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6029                                      asm, ".2s", ".2d",
6030                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6031   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6032                                     asm#"2", ".4s", ".2d", []>;
6033
6034   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
6035             (!cast<Instruction>(NAME # "v4f32")
6036                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6037 }
6038
6039 //----------------------------------------------------------------------------
6040 // AdvSIMD three register different-size vector instructions.
6041 //----------------------------------------------------------------------------
6042
6043 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6044 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
6045                       RegisterOperand outtype, RegisterOperand intype1,
6046                       RegisterOperand intype2, string asm,
6047                       string outkind, string inkind1, string inkind2,
6048                       list<dag> pattern>
6049   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
6050       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6051       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
6052     Sched<[WriteV]> {
6053   bits<5> Rd;
6054   bits<5> Rn;
6055   bits<5> Rm;
6056   let Inst{31}    = 0;
6057   let Inst{30}    = size{0};
6058   let Inst{29}    = U;
6059   let Inst{28-24} = 0b01110;
6060   let Inst{23-22} = size{2-1};
6061   let Inst{21}    = 1;
6062   let Inst{20-16} = Rm;
6063   let Inst{15-12} = opcode;
6064   let Inst{11-10} = 0b00;
6065   let Inst{9-5}   = Rn;
6066   let Inst{4-0}   = Rd;
6067 }
6068
6069 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6070 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
6071                       RegisterOperand outtype, RegisterOperand intype1,
6072                       RegisterOperand intype2, string asm,
6073                       string outkind, string inkind1, string inkind2,
6074                       list<dag> pattern>
6075   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
6076       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6077       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
6078     Sched<[WriteV]> {
6079   bits<5> Rd;
6080   bits<5> Rn;
6081   bits<5> Rm;
6082   let Inst{31}    = 0;
6083   let Inst{30}    = size{0};
6084   let Inst{29}    = U;
6085   let Inst{28-24} = 0b01110;
6086   let Inst{23-22} = size{2-1};
6087   let Inst{21}    = 1;
6088   let Inst{20-16} = Rm;
6089   let Inst{15-12} = opcode;
6090   let Inst{11-10} = 0b00;
6091   let Inst{9-5}   = Rn;
6092   let Inst{4-0}   = Rd;
6093 }
6094
6095 // FIXME: TableGen doesn't know how to deal with expanded types that also
6096 //        change the element count (in this case, placing the results in
6097 //        the high elements of the result register rather than the low
6098 //        elements). Until that's fixed, we can't code-gen those.
6099 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
6100                                     Intrinsic IntOp> {
6101   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6102                                                   V64, V128, V128,
6103                                                   asm, ".8b", ".8h", ".8h",
6104      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
6105   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6106                                                   V128, V128, V128,
6107                                                   asm#"2", ".16b", ".8h", ".8h",
6108      []>;
6109   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6110                                                   V64, V128, V128,
6111                                                   asm, ".4h", ".4s", ".4s",
6112      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
6113   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6114                                                   V128, V128, V128,
6115                                                   asm#"2", ".8h", ".4s", ".4s",
6116      []>;
6117   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6118                                                   V64, V128, V128,
6119                                                   asm, ".2s", ".2d", ".2d",
6120      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
6121   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6122                                                   V128, V128, V128,
6123                                                   asm#"2", ".4s", ".2d", ".2d",
6124      []>;
6125
6126
6127   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
6128   // a version attached to an instruction.
6129   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
6130                                                    (v8i16 V128:$Rm))),
6131             (!cast<Instruction>(NAME # "v8i16_v16i8")
6132                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6133                 V128:$Rn, V128:$Rm)>;
6134   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
6135                                                     (v4i32 V128:$Rm))),
6136             (!cast<Instruction>(NAME # "v4i32_v8i16")
6137                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6138                 V128:$Rn, V128:$Rm)>;
6139   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
6140                                                     (v2i64 V128:$Rm))),
6141             (!cast<Instruction>(NAME # "v2i64_v4i32")
6142                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6143                 V128:$Rn, V128:$Rm)>;
6144 }
6145
6146 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
6147                                       Intrinsic IntOp> {
6148   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6149                                             V128, V64, V64,
6150                                             asm, ".8h", ".8b", ".8b",
6151       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6152   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6153                                             V128, V128, V128,
6154                                             asm#"2", ".8h", ".16b", ".16b", []>;
6155   let Predicates = [HasAES] in {
6156     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
6157                                               V128, V64, V64,
6158                                               asm, ".1q", ".1d", ".1d", []>;
6159     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
6160                                               V128, V128, V128,
6161                                               asm#"2", ".1q", ".2d", ".2d", []>;
6162   }
6163
6164   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
6165                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
6166       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
6167 }
6168
6169 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
6170                                  SDPatternOperator OpNode> {
6171   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6172                                                   V128, V64, V64,
6173                                                   asm, ".4s", ".4h", ".4h",
6174       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6175   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6176                                                   V128, V128, V128,
6177                                                   asm#"2", ".4s", ".8h", ".8h",
6178       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6179                                       (extract_high_v8i16 V128:$Rm)))]>;
6180   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6181                                                   V128, V64, V64,
6182                                                   asm, ".2d", ".2s", ".2s",
6183       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6184   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6185                                                   V128, V128, V128,
6186                                                   asm#"2", ".2d", ".4s", ".4s",
6187       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6188                                       (extract_high_v4i32 V128:$Rm)))]>;
6189 }
6190
6191 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
6192                                   SDPatternOperator OpNode = null_frag> {
6193   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6194                                                   V128, V64, V64,
6195                                                   asm, ".8h", ".8b", ".8b",
6196       [(set (v8i16 V128:$Rd),
6197             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
6198   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6199                                                  V128, V128, V128,
6200                                                  asm#"2", ".8h", ".16b", ".16b",
6201       [(set (v8i16 V128:$Rd),
6202             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6203                                 (extract_high_v16i8 V128:$Rm)))))]>;
6204   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6205                                                   V128, V64, V64,
6206                                                   asm, ".4s", ".4h", ".4h",
6207       [(set (v4i32 V128:$Rd),
6208             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
6209   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6210                                                   V128, V128, V128,
6211                                                   asm#"2", ".4s", ".8h", ".8h",
6212       [(set (v4i32 V128:$Rd),
6213             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6214                                   (extract_high_v8i16 V128:$Rm)))))]>;
6215   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6216                                                   V128, V64, V64,
6217                                                   asm, ".2d", ".2s", ".2s",
6218       [(set (v2i64 V128:$Rd),
6219             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
6220   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6221                                                   V128, V128, V128,
6222                                                   asm#"2", ".2d", ".4s", ".4s",
6223       [(set (v2i64 V128:$Rd),
6224             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6225                                  (extract_high_v4i32 V128:$Rm)))))]>;
6226 }
6227
6228 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
6229                                           string asm,
6230                                           SDPatternOperator OpNode> {
6231   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6232                                                   V128, V64, V64,
6233                                                   asm, ".8h", ".8b", ".8b",
6234     [(set (v8i16 V128:$dst),
6235           (add (v8i16 V128:$Rd),
6236                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
6237   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6238                                                  V128, V128, V128,
6239                                                  asm#"2", ".8h", ".16b", ".16b",
6240     [(set (v8i16 V128:$dst),
6241           (add (v8i16 V128:$Rd),
6242                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6243                                    (extract_high_v16i8 V128:$Rm))))))]>;
6244   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6245                                                   V128, V64, V64,
6246                                                   asm, ".4s", ".4h", ".4h",
6247     [(set (v4i32 V128:$dst),
6248           (add (v4i32 V128:$Rd),
6249                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
6250   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6251                                                   V128, V128, V128,
6252                                                   asm#"2", ".4s", ".8h", ".8h",
6253     [(set (v4i32 V128:$dst),
6254           (add (v4i32 V128:$Rd),
6255                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6256                                     (extract_high_v8i16 V128:$Rm))))))]>;
6257   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6258                                                   V128, V64, V64,
6259                                                   asm, ".2d", ".2s", ".2s",
6260     [(set (v2i64 V128:$dst),
6261           (add (v2i64 V128:$Rd),
6262                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
6263   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6264                                                   V128, V128, V128,
6265                                                   asm#"2", ".2d", ".4s", ".4s",
6266     [(set (v2i64 V128:$dst),
6267           (add (v2i64 V128:$Rd),
6268                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6269                                     (extract_high_v4i32 V128:$Rm))))))]>;
6270 }
6271
6272 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
6273                                   SDPatternOperator OpNode = null_frag> {
6274   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6275                                                   V128, V64, V64,
6276                                                   asm, ".8h", ".8b", ".8b",
6277       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6278   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6279                                                  V128, V128, V128,
6280                                                  asm#"2", ".8h", ".16b", ".16b",
6281       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
6282                                       (extract_high_v16i8 V128:$Rm)))]>;
6283   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6284                                                   V128, V64, V64,
6285                                                   asm, ".4s", ".4h", ".4h",
6286       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6287   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6288                                                   V128, V128, V128,
6289                                                   asm#"2", ".4s", ".8h", ".8h",
6290       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6291                                       (extract_high_v8i16 V128:$Rm)))]>;
6292   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6293                                                   V128, V64, V64,
6294                                                   asm, ".2d", ".2s", ".2s",
6295       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6296   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6297                                                   V128, V128, V128,
6298                                                   asm#"2", ".2d", ".4s", ".4s",
6299       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6300                                       (extract_high_v4i32 V128:$Rm)))]>;
6301 }
6302
6303 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
6304                                       string asm,
6305                                       SDPatternOperator OpNode> {
6306   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6307                                                   V128, V64, V64,
6308                                                   asm, ".8h", ".8b", ".8b",
6309     [(set (v8i16 V128:$dst),
6310           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6311   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6312                                                  V128, V128, V128,
6313                                                  asm#"2", ".8h", ".16b", ".16b",
6314     [(set (v8i16 V128:$dst),
6315           (OpNode (v8i16 V128:$Rd),
6316                   (extract_high_v16i8 V128:$Rn),
6317                   (extract_high_v16i8 V128:$Rm)))]>;
6318   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6319                                                   V128, V64, V64,
6320                                                   asm, ".4s", ".4h", ".4h",
6321     [(set (v4i32 V128:$dst),
6322           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6323   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6324                                                   V128, V128, V128,
6325                                                   asm#"2", ".4s", ".8h", ".8h",
6326     [(set (v4i32 V128:$dst),
6327           (OpNode (v4i32 V128:$Rd),
6328                   (extract_high_v8i16 V128:$Rn),
6329                   (extract_high_v8i16 V128:$Rm)))]>;
6330   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6331                                                   V128, V64, V64,
6332                                                   asm, ".2d", ".2s", ".2s",
6333     [(set (v2i64 V128:$dst),
6334           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6335   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6336                                                   V128, V128, V128,
6337                                                   asm#"2", ".2d", ".4s", ".4s",
6338     [(set (v2i64 V128:$dst),
6339           (OpNode (v2i64 V128:$Rd),
6340                   (extract_high_v4i32 V128:$Rn),
6341                   (extract_high_v4i32 V128:$Rm)))]>;
6342 }
6343
6344 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
6345                                            SDPatternOperator Accum> {
6346   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6347                                                   V128, V64, V64,
6348                                                   asm, ".4s", ".4h", ".4h",
6349     [(set (v4i32 V128:$dst),
6350           (Accum (v4i32 V128:$Rd),
6351                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6352                                                 (v4i16 V64:$Rm)))))]>;
6353   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6354                                                   V128, V128, V128,
6355                                                   asm#"2", ".4s", ".8h", ".8h",
6356     [(set (v4i32 V128:$dst),
6357           (Accum (v4i32 V128:$Rd),
6358                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
6359                                             (extract_high_v8i16 V128:$Rm)))))]>;
6360   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6361                                                   V128, V64, V64,
6362                                                   asm, ".2d", ".2s", ".2s",
6363     [(set (v2i64 V128:$dst),
6364           (Accum (v2i64 V128:$Rd),
6365                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
6366                                                 (v2i32 V64:$Rm)))))]>;
6367   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6368                                                   V128, V128, V128,
6369                                                   asm#"2", ".2d", ".4s", ".4s",
6370     [(set (v2i64 V128:$dst),
6371           (Accum (v2i64 V128:$Rd),
6372                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
6373                                             (extract_high_v4i32 V128:$Rm)))))]>;
6374 }
6375
6376 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
6377                                   SDPatternOperator OpNode> {
6378   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6379                                                   V128, V128, V64,
6380                                                   asm, ".8h", ".8h", ".8b",
6381        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
6382   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6383                                                   V128, V128, V128,
6384                                                   asm#"2", ".8h", ".8h", ".16b",
6385        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
6386                                        (extract_high_v16i8 V128:$Rm)))]>;
6387   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6388                                                   V128, V128, V64,
6389                                                   asm, ".4s", ".4s", ".4h",
6390        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
6391   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6392                                                   V128, V128, V128,
6393                                                   asm#"2", ".4s", ".4s", ".8h",
6394        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
6395                                        (extract_high_v8i16 V128:$Rm)))]>;
6396   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6397                                                   V128, V128, V64,
6398                                                   asm, ".2d", ".2d", ".2s",
6399        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
6400   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6401                                                   V128, V128, V128,
6402                                                   asm#"2", ".2d", ".2d", ".4s",
6403        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
6404                                        (extract_high_v4i32 V128:$Rm)))]>;
6405 }
6406
6407 //----------------------------------------------------------------------------
6408 // AdvSIMD bitwise extract from vector
6409 //----------------------------------------------------------------------------
6410
6411 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
6412                              string asm, string kind>
6413   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
6414       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
6415       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
6416       [(set (vty regtype:$Rd),
6417             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
6418     Sched<[WriteV]> {
6419   bits<5> Rd;
6420   bits<5> Rn;
6421   bits<5> Rm;
6422   bits<4> imm;
6423   let Inst{31}    = 0;
6424   let Inst{30}    = size;
6425   let Inst{29-21} = 0b101110000;
6426   let Inst{20-16} = Rm;
6427   let Inst{15}    = 0;
6428   let Inst{14-11} = imm;
6429   let Inst{10}    = 0;
6430   let Inst{9-5}   = Rn;
6431   let Inst{4-0}   = Rd;
6432 }
6433
6434
6435 multiclass SIMDBitwiseExtract<string asm> {
6436   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
6437     let imm{3} = 0;
6438   }
6439   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
6440 }
6441
6442 //----------------------------------------------------------------------------
6443 // AdvSIMD zip vector
6444 //----------------------------------------------------------------------------
6445
6446 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
6447                         string asm, string kind, SDNode OpNode, ValueType valty>
6448   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6449       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
6450       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
6451       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
6452     Sched<[WriteV]> {
6453   bits<5> Rd;
6454   bits<5> Rn;
6455   bits<5> Rm;
6456   let Inst{31}    = 0;
6457   let Inst{30}    = size{0};
6458   let Inst{29-24} = 0b001110;
6459   let Inst{23-22} = size{2-1};
6460   let Inst{21}    = 0;
6461   let Inst{20-16} = Rm;
6462   let Inst{15}    = 0;
6463   let Inst{14-12} = opc;
6464   let Inst{11-10} = 0b10;
6465   let Inst{9-5}   = Rn;
6466   let Inst{4-0}   = Rd;
6467 }
6468
6469 multiclass SIMDZipVector<bits<3>opc, string asm,
6470                          SDNode OpNode> {
6471   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
6472       asm, ".8b", OpNode, v8i8>;
6473   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
6474       asm, ".16b", OpNode, v16i8>;
6475   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
6476       asm, ".4h", OpNode, v4i16>;
6477   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
6478       asm, ".8h", OpNode, v8i16>;
6479   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
6480       asm, ".2s", OpNode, v2i32>;
6481   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
6482       asm, ".4s", OpNode, v4i32>;
6483   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
6484       asm, ".2d", OpNode, v2i64>;
6485
6486   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
6487         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
6488   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
6489         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
6490   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
6491         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
6492   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
6493         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
6494   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
6495         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
6496 }
6497
6498 //----------------------------------------------------------------------------
6499 // AdvSIMD three register scalar instructions
6500 //----------------------------------------------------------------------------
6501
6502 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6503 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
6504                         RegisterClass regtype, string asm,
6505                         list<dag> pattern>
6506   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6507       "\t$Rd, $Rn, $Rm", "", pattern>,
6508     Sched<[WriteV]> {
6509   bits<5> Rd;
6510   bits<5> Rn;
6511   bits<5> Rm;
6512   let Inst{31-30} = 0b01;
6513   let Inst{29}    = U;
6514   let Inst{28-24} = 0b11110;
6515   let Inst{23-21} = size;
6516   let Inst{20-16} = Rm;
6517   let Inst{15-11} = opcode;
6518   let Inst{10}    = 1;
6519   let Inst{9-5}   = Rn;
6520   let Inst{4-0}   = Rd;
6521 }
6522
6523 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6524 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
6525                         dag oops, dag iops, string asm,
6526             list<dag> pattern>
6527   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
6528     Sched<[WriteV]> {
6529   bits<5> Rd;
6530   bits<5> Rn;
6531   bits<5> Rm;
6532   let Inst{31-30} = 0b01;
6533   let Inst{29}    = U;
6534   let Inst{28-24} = 0b11110;
6535   let Inst{23-22} = size;
6536   let Inst{21}    = R;
6537   let Inst{20-16} = Rm;
6538   let Inst{15-11} = opcode;
6539   let Inst{10}    = 1;
6540   let Inst{9-5}   = Rn;
6541   let Inst{4-0}   = Rd;
6542 }
6543
6544 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
6545                             SDPatternOperator OpNode> {
6546   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6547     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6548 }
6549
6550 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
6551                                SDPatternOperator OpNode> {
6552   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6553     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6554   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
6555   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6556   def v1i8   : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
6557
6558   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
6559             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
6560   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
6561             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
6562 }
6563
6564 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
6565                              SDPatternOperator OpNode> {
6566   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
6567                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6568   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6569 }
6570
6571 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
6572                                  SDPatternOperator OpNode = null_frag> {
6573   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
6574                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
6575                                      asm, []>;
6576   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
6577                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
6578                                      asm, []>;
6579 }
6580
6581 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
6582                              SDPatternOperator OpNode = null_frag> {
6583   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6584     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6585       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6586     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6587       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6588     let Predicates = [HasNEON, HasFullFP16] in {
6589     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6590       [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
6591     } // Predicates = [HasNEON, HasFullFP16]
6592   }
6593
6594   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6595             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6596 }
6597
6598 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
6599                                 SDPatternOperator OpNode = null_frag> {
6600   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6601     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6602       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6603     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6604       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
6605     let Predicates = [HasNEON, HasFullFP16] in {
6606     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6607       []>;
6608     } // Predicates = [HasNEON, HasFullFP16]
6609   }
6610
6611   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6612             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6613 }
6614
6615 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
6616               dag oops, dag iops, string asm, string cstr, list<dag> pat>
6617   : I<oops, iops, asm,
6618       "\t$Rd, $Rn, $Rm", cstr, pat>,
6619     Sched<[WriteV]> {
6620   bits<5> Rd;
6621   bits<5> Rn;
6622   bits<5> Rm;
6623   let Inst{31-30} = 0b01;
6624   let Inst{29}    = U;
6625   let Inst{28-24} = 0b11110;
6626   let Inst{23-22} = size;
6627   let Inst{21}    = 1;
6628   let Inst{20-16} = Rm;
6629   let Inst{15-11} = opcode;
6630   let Inst{10}    = 0;
6631   let Inst{9-5}   = Rn;
6632   let Inst{4-0}   = Rd;
6633 }
6634
6635 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6636 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
6637                                   SDPatternOperator OpNode = null_frag> {
6638   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6639                                       (outs FPR32:$Rd),
6640                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
6641   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6642                                       (outs FPR64:$Rd),
6643                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
6644             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6645 }
6646
6647 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6648 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
6649                                   SDPatternOperator OpNode = null_frag> {
6650   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6651                                       (outs FPR32:$dst),
6652                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
6653                                       asm, "$Rd = $dst", []>;
6654   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6655                                       (outs FPR64:$dst),
6656                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
6657                                       asm, "$Rd = $dst",
6658             [(set (i64 FPR64:$dst),
6659                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6660 }
6661
6662 //----------------------------------------------------------------------------
6663 // AdvSIMD two register scalar instructions
6664 //----------------------------------------------------------------------------
6665
6666 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6667 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6668                         RegisterClass regtype, RegisterClass regtype2,
6669                         string asm, list<dag> pat>
6670   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6671       "\t$Rd, $Rn", "", pat>,
6672     Sched<[WriteV]> {
6673   bits<5> Rd;
6674   bits<5> Rn;
6675   let Inst{31-30} = 0b01;
6676   let Inst{29}    = U;
6677   let Inst{28-24} = 0b11110;
6678   let Inst{23-22} = size;
6679   let Inst{21} = 0b1;
6680   let Inst{20-19} = size2;
6681   let Inst{18-17} = 0b00;
6682   let Inst{16-12} = opcode;
6683   let Inst{11-10} = 0b10;
6684   let Inst{9-5}   = Rn;
6685   let Inst{4-0}   = Rd;
6686 }
6687
6688 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6689 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6690                         RegisterClass regtype, RegisterClass regtype2,
6691                         string asm, list<dag> pat>
6692   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6693       "\t$Rd, $Rn", "$Rd = $dst", pat>,
6694     Sched<[WriteV]> {
6695   bits<5> Rd;
6696   bits<5> Rn;
6697   let Inst{31-30} = 0b01;
6698   let Inst{29}    = U;
6699   let Inst{28-24} = 0b11110;
6700   let Inst{23-22} = size;
6701   let Inst{21-17} = 0b10000;
6702   let Inst{16-12} = opcode;
6703   let Inst{11-10} = 0b10;
6704   let Inst{9-5}   = Rn;
6705   let Inst{4-0}   = Rd;
6706 }
6707
6708
6709 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6710 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6711                         RegisterClass regtype, string asm, string zero>
6712   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6713       "\t$Rd, $Rn, #" # zero, "", []>,
6714     Sched<[WriteV]> {
6715   bits<5> Rd;
6716   bits<5> Rn;
6717   let Inst{31-30} = 0b01;
6718   let Inst{29}    = U;
6719   let Inst{28-24} = 0b11110;
6720   let Inst{23-22} = size;
6721   let Inst{21} = 0b1;
6722   let Inst{20-19} = size2;
6723   let Inst{18-17} = 0b00;
6724   let Inst{16-12} = opcode;
6725   let Inst{11-10} = 0b10;
6726   let Inst{9-5}   = Rn;
6727   let Inst{4-0}   = Rd;
6728 }
6729
6730 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6731   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6732      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6733     Sched<[WriteV]> {
6734   bits<5> Rd;
6735   bits<5> Rn;
6736   let Inst{31-17} = 0b011111100110000;
6737   let Inst{16-12} = opcode;
6738   let Inst{11-10} = 0b10;
6739   let Inst{9-5}   = Rn;
6740   let Inst{4-0}   = Rd;
6741 }
6742
6743 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6744                              SDPatternOperator OpNode> {
6745   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6746
6747   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6748             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6749 }
6750
6751 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6752                               SDPatternOperator OpNode> {
6753   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
6754   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
6755   let Predicates = [HasNEON, HasFullFP16] in {
6756   def v1i16rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
6757   }
6758
6759   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6760                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
6761   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6762                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
6763   let Predicates = [HasNEON, HasFullFP16] in {
6764   def : InstAlias<asm # "\t$Rd, $Rn, #0",
6765                   (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
6766   }
6767
6768   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
6769             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6770 }
6771
6772 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
6773                           SDPatternOperator OpNode = null_frag> {
6774   def v1i64       : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6775     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
6776
6777   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
6778             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
6779 }
6780
6781 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
6782   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
6783   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
6784   let Predicates = [HasNEON, HasFullFP16] in {
6785   def v1f16       : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
6786   }
6787 }
6788
6789 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
6790                               SDPatternOperator OpNode> {
6791   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
6792                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
6793   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
6794                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
6795   let Predicates = [HasNEON, HasFullFP16] in {
6796   def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
6797                                 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
6798   }
6799 }
6800
6801 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
6802                              SDPatternOperator OpNode = null_frag> {
6803   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6804     def v1i64  : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6805            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6806     def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
6807            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
6808     def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
6809     def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
6810   }
6811
6812   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
6813             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
6814 }
6815
6816 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
6817                                  Intrinsic OpNode> {
6818   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6819     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
6820         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
6821     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
6822         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
6823     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
6824     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
6825   }
6826
6827   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
6828             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
6829 }
6830
6831
6832
6833 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6834 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
6835                                  SDPatternOperator OpNode = null_frag> {
6836   def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
6837         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6838   def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
6839   def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
6840 }
6841
6842 //----------------------------------------------------------------------------
6843 // AdvSIMD scalar pairwise instructions
6844 //----------------------------------------------------------------------------
6845
6846 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6847 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
6848                         RegisterOperand regtype, RegisterOperand vectype,
6849                         string asm, string kind>
6850   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6851       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
6852     Sched<[WriteV]> {
6853   bits<5> Rd;
6854   bits<5> Rn;
6855   let Inst{31-30} = 0b01;
6856   let Inst{29}    = U;
6857   let Inst{28-24} = 0b11110;
6858   let Inst{23-22} = size;
6859   let Inst{21-17} = 0b11000;
6860   let Inst{16-12} = opcode;
6861   let Inst{11-10} = 0b10;
6862   let Inst{9-5}   = Rn;
6863   let Inst{4-0}   = Rd;
6864 }
6865
6866 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6867   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6868                                       asm, ".2d">;
6869 }
6870
6871 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6872   let Predicates = [HasNEON, HasFullFP16] in {
6873   def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6874                                       asm, ".2h">;
6875   }
6876   def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
6877                                       asm, ".2s">;
6878   def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
6879                                       asm, ".2d">;
6880 }
6881
6882 //----------------------------------------------------------------------------
6883 // AdvSIMD across lanes instructions
6884 //----------------------------------------------------------------------------
6885
6886 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6887 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6888                           RegisterClass regtype, RegisterOperand vectype,
6889                           string asm, string kind, list<dag> pattern>
6890   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6891       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6892     Sched<[WriteV]> {
6893   bits<5> Rd;
6894   bits<5> Rn;
6895   let Inst{31}    = 0;
6896   let Inst{30}    = Q;
6897   let Inst{29}    = U;
6898   let Inst{28-24} = 0b01110;
6899   let Inst{23-22} = size;
6900   let Inst{21-17} = 0b11000;
6901   let Inst{16-12} = opcode;
6902   let Inst{11-10} = 0b10;
6903   let Inst{9-5}   = Rn;
6904   let Inst{4-0}   = Rd;
6905 }
6906
6907 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6908                               string asm> {
6909   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
6910                                    asm, ".8b", []>;
6911   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
6912                                    asm, ".16b", []>;
6913   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6914                                    asm, ".4h", []>;
6915   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6916                                    asm, ".8h", []>;
6917   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6918                                    asm, ".4s", []>;
6919 }
6920
6921 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6922   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6923                                    asm, ".8b", []>;
6924   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6925                                    asm, ".16b", []>;
6926   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6927                                    asm, ".4h", []>;
6928   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6929                                    asm, ".8h", []>;
6930   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6931                                    asm, ".4s", []>;
6932 }
6933
6934 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
6935                             Intrinsic intOp> {
6936   let Predicates = [HasNEON, HasFullFP16] in {
6937   def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6938                                    asm, ".4h",
6939         [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6940   def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6941                                    asm, ".8h",
6942         [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6943   } // Predicates = [HasNEON, HasFullFP16]
6944   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6945                                    asm, ".4s",
6946         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6947 }
6948
6949 //----------------------------------------------------------------------------
6950 // AdvSIMD INS/DUP instructions
6951 //----------------------------------------------------------------------------
6952
6953 // FIXME: There has got to be a better way to factor these. ugh.
6954
6955 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6956                      string operands, string constraints, list<dag> pattern>
6957   : I<outs, ins, asm, operands, constraints, pattern>,
6958     Sched<[WriteV]> {
6959   bits<5> Rd;
6960   bits<5> Rn;
6961   let Inst{31} = 0;
6962   let Inst{30} = Q;
6963   let Inst{29} = op;
6964   let Inst{28-21} = 0b01110000;
6965   let Inst{15} = 0;
6966   let Inst{10} = 1;
6967   let Inst{9-5} = Rn;
6968   let Inst{4-0} = Rd;
6969 }
6970
6971 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6972                       RegisterOperand vecreg, RegisterClass regtype>
6973   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6974                    "{\t$Rd" # size # ", $Rn" #
6975                    "|" # size # "\t$Rd, $Rn}", "",
6976                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6977   let Inst{20-16} = imm5;
6978   let Inst{14-11} = 0b0001;
6979 }
6980
6981 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6982                          ValueType vectype, ValueType insreg,
6983                          RegisterOperand vecreg, Operand idxtype,
6984                          ValueType elttype, SDNode OpNode>
6985   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6986                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6987                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6988                  [(set (vectype vecreg:$Rd),
6989                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6990   let Inst{14-11} = 0b0000;
6991 }
6992
6993 class SIMDDup64FromElement
6994   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6995                        VectorIndexD, i64, AArch64duplane64> {
6996   bits<1> idx;
6997   let Inst{20} = idx;
6998   let Inst{19-16} = 0b1000;
6999 }
7000
7001 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
7002                            RegisterOperand vecreg>
7003   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
7004                        VectorIndexS, i64, AArch64duplane32> {
7005   bits<2> idx;
7006   let Inst{20-19} = idx;
7007   let Inst{18-16} = 0b100;
7008 }
7009
7010 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
7011                            RegisterOperand vecreg>
7012   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
7013                        VectorIndexH, i64, AArch64duplane16> {
7014   bits<3> idx;
7015   let Inst{20-18} = idx;
7016   let Inst{17-16} = 0b10;
7017 }
7018
7019 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
7020                           RegisterOperand vecreg>
7021   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
7022                        VectorIndexB, i64, AArch64duplane8> {
7023   bits<4> idx;
7024   let Inst{20-17} = idx;
7025   let Inst{16} = 1;
7026 }
7027
7028 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
7029                   Operand idxtype, string asm, list<dag> pattern>
7030   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
7031                    "{\t$Rd, $Rn" # size # "$idx" #
7032                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
7033   let Inst{14-11} = imm4;
7034 }
7035
7036 class SIMDSMov<bit Q, string size, RegisterClass regtype,
7037                Operand idxtype>
7038   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
7039 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
7040                Operand idxtype>
7041   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
7042       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
7043
7044 class SIMDMovAlias<string asm, string size, Instruction inst,
7045                    RegisterClass regtype, Operand idxtype>
7046     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
7047                     "|" # size # "\t$dst, $src$idx}",
7048                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
7049
7050 multiclass SMov {
7051   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
7052     bits<4> idx;
7053     let Inst{20-17} = idx;
7054     let Inst{16} = 1;
7055   }
7056   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
7057     bits<4> idx;
7058     let Inst{20-17} = idx;
7059     let Inst{16} = 1;
7060   }
7061   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
7062     bits<3> idx;
7063     let Inst{20-18} = idx;
7064     let Inst{17-16} = 0b10;
7065   }
7066   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
7067     bits<3> idx;
7068     let Inst{20-18} = idx;
7069     let Inst{17-16} = 0b10;
7070   }
7071   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
7072     bits<2> idx;
7073     let Inst{20-19} = idx;
7074     let Inst{18-16} = 0b100;
7075   }
7076 }
7077
7078 multiclass UMov {
7079   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
7080     bits<4> idx;
7081     let Inst{20-17} = idx;
7082     let Inst{16} = 1;
7083   }
7084   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
7085     bits<3> idx;
7086     let Inst{20-18} = idx;
7087     let Inst{17-16} = 0b10;
7088   }
7089   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
7090     bits<2> idx;
7091     let Inst{20-19} = idx;
7092     let Inst{18-16} = 0b100;
7093   }
7094   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
7095     bits<1> idx;
7096     let Inst{20} = idx;
7097     let Inst{19-16} = 0b1000;
7098   }
7099   def : SIMDMovAlias<"mov", ".s",
7100                      !cast<Instruction>(NAME#"vi32"),
7101                      GPR32, VectorIndexS>;
7102   def : SIMDMovAlias<"mov", ".d",
7103                      !cast<Instruction>(NAME#"vi64"),
7104                      GPR64, VectorIndexD>;
7105 }
7106
7107 class SIMDInsFromMain<string size, ValueType vectype,
7108                       RegisterClass regtype, Operand idxtype>
7109   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
7110                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
7111                    "{\t$Rd" # size # "$idx, $Rn" #
7112                    "|" # size # "\t$Rd$idx, $Rn}",
7113                    "$Rd = $dst",
7114             [(set V128:$dst,
7115               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
7116   let Inst{14-11} = 0b0011;
7117 }
7118
7119 class SIMDInsFromElement<string size, ValueType vectype,
7120                          ValueType elttype, Operand idxtype>
7121   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
7122                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
7123                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
7124                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
7125                    "$Rd = $dst",
7126          [(set V128:$dst,
7127                (vector_insert
7128                  (vectype V128:$Rd),
7129                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
7130                  idxtype:$idx))]>;
7131
7132 class SIMDInsMainMovAlias<string size, Instruction inst,
7133                           RegisterClass regtype, Operand idxtype>
7134     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
7135                         "|" # size #"\t$dst$idx, $src}",
7136                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
7137 class SIMDInsElementMovAlias<string size, Instruction inst,
7138                              Operand idxtype>
7139     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
7140                       # "|" # size #"\t$dst$idx, $src$idx2}",
7141                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
7142
7143
7144 multiclass SIMDIns {
7145   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
7146     bits<4> idx;
7147     let Inst{20-17} = idx;
7148     let Inst{16} = 1;
7149   }
7150   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
7151     bits<3> idx;
7152     let Inst{20-18} = idx;
7153     let Inst{17-16} = 0b10;
7154   }
7155   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
7156     bits<2> idx;
7157     let Inst{20-19} = idx;
7158     let Inst{18-16} = 0b100;
7159   }
7160   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
7161     bits<1> idx;
7162     let Inst{20} = idx;
7163     let Inst{19-16} = 0b1000;
7164   }
7165
7166   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
7167     bits<4> idx;
7168     bits<4> idx2;
7169     let Inst{20-17} = idx;
7170     let Inst{16} = 1;
7171     let Inst{14-11} = idx2;
7172   }
7173   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
7174     bits<3> idx;
7175     bits<3> idx2;
7176     let Inst{20-18} = idx;
7177     let Inst{17-16} = 0b10;
7178     let Inst{14-12} = idx2;
7179     let Inst{11} = {?};
7180   }
7181   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
7182     bits<2> idx;
7183     bits<2> idx2;
7184     let Inst{20-19} = idx;
7185     let Inst{18-16} = 0b100;
7186     let Inst{14-13} = idx2;
7187     let Inst{12-11} = {?,?};
7188   }
7189   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
7190     bits<1> idx;
7191     bits<1> idx2;
7192     let Inst{20} = idx;
7193     let Inst{19-16} = 0b1000;
7194     let Inst{14} = idx2;
7195     let Inst{13-11} = {?,?,?};
7196   }
7197
7198   // For all forms of the INS instruction, the "mov" mnemonic is the
7199   // preferred alias. Why they didn't just call the instruction "mov" in
7200   // the first place is a very good question indeed...
7201   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
7202                          GPR32, VectorIndexB>;
7203   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
7204                          GPR32, VectorIndexH>;
7205   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
7206                          GPR32, VectorIndexS>;
7207   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
7208                          GPR64, VectorIndexD>;
7209
7210   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
7211                          VectorIndexB>;
7212   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
7213                          VectorIndexH>;
7214   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
7215                          VectorIndexS>;
7216   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
7217                          VectorIndexD>;
7218 }
7219
7220 //----------------------------------------------------------------------------
7221 // AdvSIMD TBL/TBX
7222 //----------------------------------------------------------------------------
7223
7224 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7225 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7226                           RegisterOperand listtype, string asm, string kind>
7227   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
7228        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
7229     Sched<[WriteV]> {
7230   bits<5> Vd;
7231   bits<5> Vn;
7232   bits<5> Vm;
7233   let Inst{31}    = 0;
7234   let Inst{30}    = Q;
7235   let Inst{29-21} = 0b001110000;
7236   let Inst{20-16} = Vm;
7237   let Inst{15}    = 0;
7238   let Inst{14-13} = len;
7239   let Inst{12}    = op;
7240   let Inst{11-10} = 0b00;
7241   let Inst{9-5}   = Vn;
7242   let Inst{4-0}   = Vd;
7243 }
7244
7245 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7246 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7247                           RegisterOperand listtype, string asm, string kind>
7248   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
7249        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
7250     Sched<[WriteV]> {
7251   bits<5> Vd;
7252   bits<5> Vn;
7253   bits<5> Vm;
7254   let Inst{31}    = 0;
7255   let Inst{30}    = Q;
7256   let Inst{29-21} = 0b001110000;
7257   let Inst{20-16} = Vm;
7258   let Inst{15}    = 0;
7259   let Inst{14-13} = len;
7260   let Inst{12}    = op;
7261   let Inst{11-10} = 0b00;
7262   let Inst{9-5}   = Vn;
7263   let Inst{4-0}   = Vd;
7264 }
7265
7266 class SIMDTableLookupAlias<string asm, Instruction inst,
7267                           RegisterOperand vectype, RegisterOperand listtype>
7268     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
7269                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
7270
7271 multiclass SIMDTableLookup<bit op, string asm> {
7272   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
7273                                       asm, ".8b">;
7274   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
7275                                       asm, ".8b">;
7276   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
7277                                       asm, ".8b">;
7278   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
7279                                       asm, ".8b">;
7280   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
7281                                       asm, ".16b">;
7282   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
7283                                       asm, ".16b">;
7284   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
7285                                       asm, ".16b">;
7286   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
7287                                       asm, ".16b">;
7288
7289   def : SIMDTableLookupAlias<asm # ".8b",
7290                          !cast<Instruction>(NAME#"v8i8One"),
7291                          V64, VecListOne128>;
7292   def : SIMDTableLookupAlias<asm # ".8b",
7293                          !cast<Instruction>(NAME#"v8i8Two"),
7294                          V64, VecListTwo128>;
7295   def : SIMDTableLookupAlias<asm # ".8b",
7296                          !cast<Instruction>(NAME#"v8i8Three"),
7297                          V64, VecListThree128>;
7298   def : SIMDTableLookupAlias<asm # ".8b",
7299                          !cast<Instruction>(NAME#"v8i8Four"),
7300                          V64, VecListFour128>;
7301   def : SIMDTableLookupAlias<asm # ".16b",
7302                          !cast<Instruction>(NAME#"v16i8One"),
7303                          V128, VecListOne128>;
7304   def : SIMDTableLookupAlias<asm # ".16b",
7305                          !cast<Instruction>(NAME#"v16i8Two"),
7306                          V128, VecListTwo128>;
7307   def : SIMDTableLookupAlias<asm # ".16b",
7308                          !cast<Instruction>(NAME#"v16i8Three"),
7309                          V128, VecListThree128>;
7310   def : SIMDTableLookupAlias<asm # ".16b",
7311                          !cast<Instruction>(NAME#"v16i8Four"),
7312                          V128, VecListFour128>;
7313 }
7314
7315 multiclass SIMDTableLookupTied<bit op, string asm> {
7316   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
7317                                       asm, ".8b">;
7318   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
7319                                       asm, ".8b">;
7320   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
7321                                       asm, ".8b">;
7322   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
7323                                       asm, ".8b">;
7324   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
7325                                       asm, ".16b">;
7326   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
7327                                       asm, ".16b">;
7328   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
7329                                       asm, ".16b">;
7330   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
7331                                       asm, ".16b">;
7332
7333   def : SIMDTableLookupAlias<asm # ".8b",
7334                          !cast<Instruction>(NAME#"v8i8One"),
7335                          V64, VecListOne128>;
7336   def : SIMDTableLookupAlias<asm # ".8b",
7337                          !cast<Instruction>(NAME#"v8i8Two"),
7338                          V64, VecListTwo128>;
7339   def : SIMDTableLookupAlias<asm # ".8b",
7340                          !cast<Instruction>(NAME#"v8i8Three"),
7341                          V64, VecListThree128>;
7342   def : SIMDTableLookupAlias<asm # ".8b",
7343                          !cast<Instruction>(NAME#"v8i8Four"),
7344                          V64, VecListFour128>;
7345   def : SIMDTableLookupAlias<asm # ".16b",
7346                          !cast<Instruction>(NAME#"v16i8One"),
7347                          V128, VecListOne128>;
7348   def : SIMDTableLookupAlias<asm # ".16b",
7349                          !cast<Instruction>(NAME#"v16i8Two"),
7350                          V128, VecListTwo128>;
7351   def : SIMDTableLookupAlias<asm # ".16b",
7352                          !cast<Instruction>(NAME#"v16i8Three"),
7353                          V128, VecListThree128>;
7354   def : SIMDTableLookupAlias<asm # ".16b",
7355                          !cast<Instruction>(NAME#"v16i8Four"),
7356                          V128, VecListFour128>;
7357 }
7358
7359
7360 //----------------------------------------------------------------------------
7361 // AdvSIMD scalar CPY
7362 //----------------------------------------------------------------------------
7363 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7364 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
7365                         string kind, Operand idxtype>
7366   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
7367        "{\t$dst, $src" # kind # "$idx" #
7368        "|\t$dst, $src$idx}", "", []>,
7369     Sched<[WriteV]> {
7370   bits<5> dst;
7371   bits<5> src;
7372   let Inst{31-21} = 0b01011110000;
7373   let Inst{15-10} = 0b000001;
7374   let Inst{9-5}   = src;
7375   let Inst{4-0}   = dst;
7376 }
7377
7378 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
7379       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
7380     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
7381                     # "|\t$dst, $src$index}",
7382                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
7383
7384
7385 multiclass SIMDScalarCPY<string asm> {
7386   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
7387     bits<4> idx;
7388     let Inst{20-17} = idx;
7389     let Inst{16} = 1;
7390   }
7391   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
7392     bits<3> idx;
7393     let Inst{20-18} = idx;
7394     let Inst{17-16} = 0b10;
7395   }
7396   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
7397     bits<2> idx;
7398     let Inst{20-19} = idx;
7399     let Inst{18-16} = 0b100;
7400   }
7401   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
7402     bits<1> idx;
7403     let Inst{20} = idx;
7404     let Inst{19-16} = 0b1000;
7405   }
7406
7407   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
7408                                                           VectorIndexD:$idx)))),
7409             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
7410
7411   // 'DUP' mnemonic aliases.
7412   def : SIMDScalarCPYAlias<"dup", ".b",
7413                            !cast<Instruction>(NAME#"i8"),
7414                            FPR8, V128, VectorIndexB>;
7415   def : SIMDScalarCPYAlias<"dup", ".h",
7416                            !cast<Instruction>(NAME#"i16"),
7417                            FPR16, V128, VectorIndexH>;
7418   def : SIMDScalarCPYAlias<"dup", ".s",
7419                            !cast<Instruction>(NAME#"i32"),
7420                            FPR32, V128, VectorIndexS>;
7421   def : SIMDScalarCPYAlias<"dup", ".d",
7422                            !cast<Instruction>(NAME#"i64"),
7423                            FPR64, V128, VectorIndexD>;
7424 }
7425
7426 //----------------------------------------------------------------------------
7427 // AdvSIMD modified immediate instructions
7428 //----------------------------------------------------------------------------
7429
7430 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
7431                           string asm, string op_string,
7432                           string cstr, list<dag> pattern>
7433   : I<oops, iops, asm, op_string, cstr, pattern>,
7434     Sched<[WriteV]> {
7435   bits<5> Rd;
7436   bits<8> imm8;
7437   let Inst{31}    = 0;
7438   let Inst{30}    = Q;
7439   let Inst{29}    = op;
7440   let Inst{28-19} = 0b0111100000;
7441   let Inst{18-16} = imm8{7-5};
7442   let Inst{11} = op2;
7443   let Inst{10} = 1;
7444   let Inst{9-5}   = imm8{4-0};
7445   let Inst{4-0}   = Rd;
7446 }
7447
7448 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
7449                                 Operand immtype, dag opt_shift_iop,
7450                                 string opt_shift, string asm, string kind,
7451                                 list<dag> pattern>
7452   : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
7453                         !con((ins immtype:$imm8), opt_shift_iop), asm,
7454                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
7455                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7456                         "", pattern> {
7457   let DecoderMethod = "DecodeModImmInstruction";
7458 }
7459
7460 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
7461                                 Operand immtype, dag opt_shift_iop,
7462                                 string opt_shift, string asm, string kind,
7463                                 list<dag> pattern>
7464   : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
7465                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
7466                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
7467                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7468                         "$Rd = $dst", pattern> {
7469   let DecoderMethod = "DecodeModImmTiedInstruction";
7470 }
7471
7472 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
7473                                      RegisterOperand vectype, string asm,
7474                                      string kind, list<dag> pattern>
7475   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7476                               (ins logical_vec_shift:$shift),
7477                               "$shift", asm, kind, pattern> {
7478   bits<2> shift;
7479   let Inst{15}    = b15_b12{1};
7480   let Inst{14-13} = shift;
7481   let Inst{12}    = b15_b12{0};
7482 }
7483
7484 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
7485                                      RegisterOperand vectype, string asm,
7486                                      string kind, list<dag> pattern>
7487   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7488                               (ins logical_vec_shift:$shift),
7489                               "$shift", asm, kind, pattern> {
7490   bits<2> shift;
7491   let Inst{15}    = b15_b12{1};
7492   let Inst{14-13} = shift;
7493   let Inst{12}    = b15_b12{0};
7494 }
7495
7496
7497 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
7498                                          RegisterOperand vectype, string asm,
7499                                          string kind, list<dag> pattern>
7500   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7501                               (ins logical_vec_hw_shift:$shift),
7502                               "$shift", asm, kind, pattern> {
7503   bits<2> shift;
7504   let Inst{15} = b15_b12{1};
7505   let Inst{14} = 0;
7506   let Inst{13} = shift{0};
7507   let Inst{12} = b15_b12{0};
7508 }
7509
7510 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
7511                                          RegisterOperand vectype, string asm,
7512                                          string kind, list<dag> pattern>
7513   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7514                               (ins logical_vec_hw_shift:$shift),
7515                               "$shift", asm, kind, pattern> {
7516   bits<2> shift;
7517   let Inst{15} = b15_b12{1};
7518   let Inst{14} = 0;
7519   let Inst{13} = shift{0};
7520   let Inst{12} = b15_b12{0};
7521 }
7522
7523 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
7524                                       string asm> {
7525   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
7526                                                  asm, ".4h", []>;
7527   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
7528                                                  asm, ".8h", []>;
7529
7530   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
7531                                              asm, ".2s", []>;
7532   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
7533                                              asm, ".4s", []>;
7534 }
7535
7536 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
7537                                       bits<2> w_cmode, string asm,
7538                                       SDNode OpNode> {
7539   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
7540                                                  asm, ".4h",
7541              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
7542                                              imm0_255:$imm8,
7543                                              (i32 imm:$shift)))]>;
7544   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
7545                                                  asm, ".8h",
7546              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
7547                                               imm0_255:$imm8,
7548                                               (i32 imm:$shift)))]>;
7549
7550   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
7551                                              asm, ".2s",
7552              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
7553                                              imm0_255:$imm8,
7554                                              (i32 imm:$shift)))]>;
7555   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
7556                                              asm, ".4s",
7557              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
7558                                               imm0_255:$imm8,
7559                                               (i32 imm:$shift)))]>;
7560 }
7561
7562 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
7563                              RegisterOperand vectype, string asm,
7564                              string kind, list<dag> pattern>
7565   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7566                               (ins move_vec_shift:$shift),
7567                               "$shift", asm, kind, pattern> {
7568   bits<1> shift;
7569   let Inst{15-13} = cmode{3-1};
7570   let Inst{12}    = shift;
7571 }
7572
7573 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
7574                                    RegisterOperand vectype,
7575                                    Operand imm_type, string asm,
7576                                    string kind, list<dag> pattern>
7577   : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
7578                               asm, kind, pattern> {
7579   let Inst{15-12} = cmode;
7580 }
7581
7582 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
7583                                    list<dag> pattern>
7584   : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
7585                         "\t$Rd, $imm8", "", pattern> {
7586   let Inst{15-12} = cmode;
7587   let DecoderMethod = "DecodeModImmInstruction";
7588 }
7589
7590 //----------------------------------------------------------------------------
7591 // AdvSIMD indexed element
7592 //----------------------------------------------------------------------------
7593
7594 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7595 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7596                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
7597                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
7598                       string apple_kind, string dst_kind, string lhs_kind,
7599                       string rhs_kind, list<dag> pattern>
7600   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
7601       asm,
7602       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7603       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
7604     Sched<[WriteV]> {
7605   bits<5> Rd;
7606   bits<5> Rn;
7607   bits<5> Rm;
7608
7609   let Inst{31}    = 0;
7610   let Inst{30}    = Q;
7611   let Inst{29}    = U;
7612   let Inst{28}    = Scalar;
7613   let Inst{27-24} = 0b1111;
7614   let Inst{23-22} = size;
7615   // Bit 21 must be set by the derived class.
7616   let Inst{20-16} = Rm;
7617   let Inst{15-12} = opc;
7618   // Bit 11 must be set by the derived class.
7619   let Inst{10}    = 0;
7620   let Inst{9-5}   = Rn;
7621   let Inst{4-0}   = Rd;
7622 }
7623
7624 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7625 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7626                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
7627                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
7628                       string apple_kind, string dst_kind, string lhs_kind,
7629                       string rhs_kind, list<dag> pattern>
7630   : I<(outs dst_reg:$dst),
7631       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
7632       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7633       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
7634     Sched<[WriteV]> {
7635   bits<5> Rd;
7636   bits<5> Rn;
7637   bits<5> Rm;
7638
7639   let Inst{31}    = 0;
7640   let Inst{30}    = Q;
7641   let Inst{29}    = U;
7642   let Inst{28}    = Scalar;
7643   let Inst{27-24} = 0b1111;
7644   let Inst{23-22} = size;
7645   // Bit 21 must be set by the derived class.
7646   let Inst{20-16} = Rm;
7647   let Inst{15-12} = opc;
7648   // Bit 11 must be set by the derived class.
7649   let Inst{10}    = 0;
7650   let Inst{9-5}   = Rn;
7651   let Inst{4-0}   = Rd;
7652 }
7653
7654 // ARMv8.2-A Dot Product Instructions (Indexed)
7655 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, string asm, string dst_kind,
7656                                       string lhs_kind, string rhs_kind,
7657                                       RegisterOperand RegType,
7658                                       ValueType AccumType, ValueType InputType,
7659                                       SDPatternOperator OpNode> :
7660         BaseSIMDIndexedTied<Q, U, 0b0, 0b10, 0b1110, RegType, RegType, V128,
7661                             VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
7662         [(set (AccumType RegType:$dst),
7663               (AccumType (OpNode (AccumType RegType:$Rd),
7664                                  (InputType RegType:$Rn),
7665                                  (InputType (bitconvert (AccumType
7666                                     (AArch64duplane32 (v4i32 V128:$Rm),
7667                                         VectorIndexS:$idx)))))))]> {
7668   bits<2> idx;
7669   let Inst{21}    = idx{0};  // L
7670   let Inst{11}    = idx{1};  // H
7671 }
7672
7673 multiclass SIMDThreeSameVectorDotIndex<bit U, string asm,
7674                                        SDPatternOperator OpNode> {
7675   def v8i8  : BaseSIMDThreeSameVectorDotIndex<0, U, asm, ".2s", ".8b", ".4b",
7676                                               V64, v2i32, v8i8, OpNode>;
7677   def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, asm, ".4s", ".16b", ".4b",
7678                                               V128, v4i32, v16i8, OpNode>;
7679 }
7680
7681 // ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed)
7682 class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm,
7683                                       string dst_kind, string lhs_kind,
7684                                       string rhs_kind, RegisterOperand RegType,
7685                                       ValueType AccumType, ValueType InputType,
7686                                       SDPatternOperator OpNode> :
7687         BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128,
7688                             VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind,
7689           [(set (AccumType RegType:$dst),
7690                 (AccumType (OpNode (AccumType RegType:$Rd),
7691                                    (InputType RegType:$Rn),
7692                                    (InputType (AArch64duplane16 (v8f16 V128:$Rm),
7693                                                 VectorIndexH:$idx)))))]> {
7694   // idx = H:L:M
7695   bits<3> idx;
7696   let Inst{11} = idx{2}; // H
7697   let Inst{21} = idx{1}; // L
7698   let Inst{20} = idx{0}; // M
7699 }
7700
7701 multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm,
7702                                        SDPatternOperator OpNode> {
7703   def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h",
7704                                               V64, v2f32, v4f16, OpNode>;
7705   def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h",
7706                                               V128, v4f32, v8f16, OpNode>;
7707 }
7708
7709 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
7710                          SDPatternOperator OpNode> {
7711   let Predicates = [HasNEON, HasFullFP16] in {
7712   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
7713                                       V64, V64,
7714                                       V128_lo, VectorIndexH,
7715                                       asm, ".4h", ".4h", ".4h", ".h",
7716     [(set (v4f16 V64:$Rd),
7717         (OpNode (v4f16 V64:$Rn),
7718          (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7719     bits<3> idx;
7720     let Inst{11} = idx{2};
7721     let Inst{21} = idx{1};
7722     let Inst{20} = idx{0};
7723   }
7724
7725   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
7726                                       V128, V128,
7727                                       V128_lo, VectorIndexH,
7728                                       asm, ".8h", ".8h", ".8h", ".h",
7729     [(set (v8f16 V128:$Rd),
7730         (OpNode (v8f16 V128:$Rn),
7731          (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7732     bits<3> idx;
7733     let Inst{11} = idx{2};
7734     let Inst{21} = idx{1};
7735     let Inst{20} = idx{0};
7736   }
7737   } // Predicates = [HasNEON, HasFullFP16]
7738
7739   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7740                                       V64, V64,
7741                                       V128, VectorIndexS,
7742                                       asm, ".2s", ".2s", ".2s", ".s",
7743     [(set (v2f32 V64:$Rd),
7744         (OpNode (v2f32 V64:$Rn),
7745          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7746     bits<2> idx;
7747     let Inst{11} = idx{1};
7748     let Inst{21} = idx{0};
7749   }
7750
7751   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7752                                       V128, V128,
7753                                       V128, VectorIndexS,
7754                                       asm, ".4s", ".4s", ".4s", ".s",
7755     [(set (v4f32 V128:$Rd),
7756         (OpNode (v4f32 V128:$Rn),
7757          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7758     bits<2> idx;
7759     let Inst{11} = idx{1};
7760     let Inst{21} = idx{0};
7761   }
7762
7763   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
7764                                       V128, V128,
7765                                       V128, VectorIndexD,
7766                                       asm, ".2d", ".2d", ".2d", ".d",
7767     [(set (v2f64 V128:$Rd),
7768         (OpNode (v2f64 V128:$Rn),
7769          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
7770     bits<1> idx;
7771     let Inst{11} = idx{0};
7772     let Inst{21} = 0;
7773   }
7774
7775   let Predicates = [HasNEON, HasFullFP16] in {
7776   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
7777                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7778                                       asm, ".h", "", "", ".h",
7779     [(set (f16 FPR16Op:$Rd),
7780           (OpNode (f16 FPR16Op:$Rn),
7781                   (f16 (vector_extract (v8f16 V128_lo:$Rm),
7782                                        VectorIndexH:$idx))))]> {
7783     bits<3> idx;
7784     let Inst{11} = idx{2};
7785     let Inst{21} = idx{1};
7786     let Inst{20} = idx{0};
7787   }
7788   } // Predicates = [HasNEON, HasFullFP16]
7789
7790   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7791                                       FPR32Op, FPR32Op, V128, VectorIndexS,
7792                                       asm, ".s", "", "", ".s",
7793     [(set (f32 FPR32Op:$Rd),
7794           (OpNode (f32 FPR32Op:$Rn),
7795                   (f32 (vector_extract (v4f32 V128:$Rm),
7796                                        VectorIndexS:$idx))))]> {
7797     bits<2> idx;
7798     let Inst{11} = idx{1};
7799     let Inst{21} = idx{0};
7800   }
7801
7802   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
7803                                       FPR64Op, FPR64Op, V128, VectorIndexD,
7804                                       asm, ".d", "", "", ".d",
7805     [(set (f64 FPR64Op:$Rd),
7806           (OpNode (f64 FPR64Op:$Rn),
7807                   (f64 (vector_extract (v2f64 V128:$Rm),
7808                                        VectorIndexD:$idx))))]> {
7809     bits<1> idx;
7810     let Inst{11} = idx{0};
7811     let Inst{21} = 0;
7812   }
7813 }
7814
7815 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
7816   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
7817   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7818                            (AArch64duplane32 (v4f32 V128:$Rm),
7819                                            VectorIndexS:$idx))),
7820             (!cast<Instruction>(INST # v2i32_indexed)
7821                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7822   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7823                            (AArch64dup (f32 FPR32Op:$Rm)))),
7824             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
7825                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7826
7827
7828   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
7829   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7830                            (AArch64duplane32 (v4f32 V128:$Rm),
7831                                            VectorIndexS:$idx))),
7832             (!cast<Instruction>(INST # "v4i32_indexed")
7833                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7834   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7835                            (AArch64dup (f32 FPR32Op:$Rm)))),
7836             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
7837                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7838
7839   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
7840   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7841                            (AArch64duplane64 (v2f64 V128:$Rm),
7842                                            VectorIndexD:$idx))),
7843             (!cast<Instruction>(INST # "v2i64_indexed")
7844                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7845   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7846                            (AArch64dup (f64 FPR64Op:$Rm)))),
7847             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
7848                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
7849
7850   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
7851   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7852                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
7853             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7854                 V128:$Rm, VectorIndexS:$idx)>;
7855   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7856                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
7857             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7858                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
7859
7860   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
7861   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
7862                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
7863             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
7864                 V128:$Rm, VectorIndexD:$idx)>;
7865 }
7866
7867 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
7868   let Predicates = [HasNEON, HasFullFP16] in {
7869   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
7870                                           V128_lo, VectorIndexH,
7871                                           asm, ".4h", ".4h", ".4h", ".h", []> {
7872     bits<3> idx;
7873     let Inst{11} = idx{2};
7874     let Inst{21} = idx{1};
7875     let Inst{20} = idx{0};
7876   }
7877
7878   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
7879                                           V128, V128,
7880                                           V128_lo, VectorIndexH,
7881                                           asm, ".8h", ".8h", ".8h", ".h", []> {
7882     bits<3> idx;
7883     let Inst{11} = idx{2};
7884     let Inst{21} = idx{1};
7885     let Inst{20} = idx{0};
7886   }
7887   } // Predicates = [HasNEON, HasFullFP16]
7888
7889   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
7890                                           V128, VectorIndexS,
7891                                           asm, ".2s", ".2s", ".2s", ".s", []> {
7892     bits<2> idx;
7893     let Inst{11} = idx{1};
7894     let Inst{21} = idx{0};
7895   }
7896
7897   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7898                                       V128, V128,
7899                                       V128, VectorIndexS,
7900                                       asm, ".4s", ".4s", ".4s", ".s", []> {
7901     bits<2> idx;
7902     let Inst{11} = idx{1};
7903     let Inst{21} = idx{0};
7904   }
7905
7906   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
7907                                       V128, V128,
7908                                       V128, VectorIndexD,
7909                                       asm, ".2d", ".2d", ".2d", ".d", []> {
7910     bits<1> idx;
7911     let Inst{11} = idx{0};
7912     let Inst{21} = 0;
7913   }
7914
7915   let Predicates = [HasNEON, HasFullFP16] in {
7916   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
7917                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7918                                       asm, ".h", "", "", ".h", []> {
7919     bits<3> idx;
7920     let Inst{11} = idx{2};
7921     let Inst{21} = idx{1};
7922     let Inst{20} = idx{0};
7923   }
7924   } // Predicates = [HasNEON, HasFullFP16]
7925
7926   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7927                                       FPR32Op, FPR32Op, V128, VectorIndexS,
7928                                       asm, ".s", "", "", ".s", []> {
7929     bits<2> idx;
7930     let Inst{11} = idx{1};
7931     let Inst{21} = idx{0};
7932   }
7933
7934   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7935                                       FPR64Op, FPR64Op, V128, VectorIndexD,
7936                                       asm, ".d", "", "", ".d", []> {
7937     bits<1> idx;
7938     let Inst{11} = idx{0};
7939     let Inst{21} = 0;
7940   }
7941 }
7942
7943 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7944                          SDPatternOperator OpNode> {
7945   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7946                                       V128_lo, VectorIndexH,
7947                                       asm, ".4h", ".4h", ".4h", ".h",
7948     [(set (v4i16 V64:$Rd),
7949         (OpNode (v4i16 V64:$Rn),
7950          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7951     bits<3> idx;
7952     let Inst{11} = idx{2};
7953     let Inst{21} = idx{1};
7954     let Inst{20} = idx{0};
7955   }
7956
7957   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7958                                       V128, V128,
7959                                       V128_lo, VectorIndexH,
7960                                       asm, ".8h", ".8h", ".8h", ".h",
7961     [(set (v8i16 V128:$Rd),
7962        (OpNode (v8i16 V128:$Rn),
7963          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7964     bits<3> idx;
7965     let Inst{11} = idx{2};
7966     let Inst{21} = idx{1};
7967     let Inst{20} = idx{0};
7968   }
7969
7970   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7971                                       V64, V64,
7972                                       V128, VectorIndexS,
7973                                       asm, ".2s", ".2s", ".2s",  ".s",
7974     [(set (v2i32 V64:$Rd),
7975        (OpNode (v2i32 V64:$Rn),
7976           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7977     bits<2> idx;
7978     let Inst{11} = idx{1};
7979     let Inst{21} = idx{0};
7980   }
7981
7982   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7983                                       V128, V128,
7984                                       V128, VectorIndexS,
7985                                       asm, ".4s", ".4s", ".4s", ".s",
7986     [(set (v4i32 V128:$Rd),
7987        (OpNode (v4i32 V128:$Rn),
7988           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7989     bits<2> idx;
7990     let Inst{11} = idx{1};
7991     let Inst{21} = idx{0};
7992   }
7993
7994   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7995                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7996                                       asm, ".h", "", "", ".h", []> {
7997     bits<3> idx;
7998     let Inst{11} = idx{2};
7999     let Inst{21} = idx{1};
8000     let Inst{20} = idx{0};
8001   }
8002
8003   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8004                                       FPR32Op, FPR32Op, V128, VectorIndexS,
8005                                       asm, ".s", "", "", ".s",
8006       [(set (i32 FPR32Op:$Rd),
8007             (OpNode FPR32Op:$Rn,
8008                     (i32 (vector_extract (v4i32 V128:$Rm),
8009                                          VectorIndexS:$idx))))]> {
8010     bits<2> idx;
8011     let Inst{11} = idx{1};
8012     let Inst{21} = idx{0};
8013   }
8014 }
8015
8016 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
8017                                SDPatternOperator OpNode> {
8018   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8019                                       V64, V64,
8020                                       V128_lo, VectorIndexH,
8021                                       asm, ".4h", ".4h", ".4h", ".h",
8022     [(set (v4i16 V64:$Rd),
8023         (OpNode (v4i16 V64:$Rn),
8024          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8025     bits<3> idx;
8026     let Inst{11} = idx{2};
8027     let Inst{21} = idx{1};
8028     let Inst{20} = idx{0};
8029   }
8030
8031   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8032                                       V128, V128,
8033                                       V128_lo, VectorIndexH,
8034                                       asm, ".8h", ".8h", ".8h", ".h",
8035     [(set (v8i16 V128:$Rd),
8036        (OpNode (v8i16 V128:$Rn),
8037          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8038     bits<3> idx;
8039     let Inst{11} = idx{2};
8040     let Inst{21} = idx{1};
8041     let Inst{20} = idx{0};
8042   }
8043
8044   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8045                                       V64, V64,
8046                                       V128, VectorIndexS,
8047                                       asm, ".2s", ".2s", ".2s", ".s",
8048     [(set (v2i32 V64:$Rd),
8049        (OpNode (v2i32 V64:$Rn),
8050           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8051     bits<2> idx;
8052     let Inst{11} = idx{1};
8053     let Inst{21} = idx{0};
8054   }
8055
8056   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8057                                       V128, V128,
8058                                       V128, VectorIndexS,
8059                                       asm, ".4s", ".4s", ".4s", ".s",
8060     [(set (v4i32 V128:$Rd),
8061        (OpNode (v4i32 V128:$Rn),
8062           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8063     bits<2> idx;
8064     let Inst{11} = idx{1};
8065     let Inst{21} = idx{0};
8066   }
8067 }
8068
8069 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
8070                                    SDPatternOperator OpNode> {
8071   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
8072                                           V128_lo, VectorIndexH,
8073                                           asm, ".4h", ".4h", ".4h", ".h",
8074     [(set (v4i16 V64:$dst),
8075         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
8076          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8077     bits<3> idx;
8078     let Inst{11} = idx{2};
8079     let Inst{21} = idx{1};
8080     let Inst{20} = idx{0};
8081   }
8082
8083   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8084                                       V128, V128,
8085                                       V128_lo, VectorIndexH,
8086                                       asm, ".8h", ".8h", ".8h", ".h",
8087     [(set (v8i16 V128:$dst),
8088        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8089          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8090     bits<3> idx;
8091     let Inst{11} = idx{2};
8092     let Inst{21} = idx{1};
8093     let Inst{20} = idx{0};
8094   }
8095
8096   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8097                                       V64, V64,
8098                                       V128, VectorIndexS,
8099                                       asm, ".2s", ".2s", ".2s", ".s",
8100     [(set (v2i32 V64:$dst),
8101        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8102           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8103     bits<2> idx;
8104     let Inst{11} = idx{1};
8105     let Inst{21} = idx{0};
8106   }
8107
8108   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8109                                       V128, V128,
8110                                       V128, VectorIndexS,
8111                                       asm, ".4s", ".4s", ".4s", ".s",
8112     [(set (v4i32 V128:$dst),
8113        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8114           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8115     bits<2> idx;
8116     let Inst{11} = idx{1};
8117     let Inst{21} = idx{0};
8118   }
8119 }
8120
8121 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
8122                              SDPatternOperator OpNode> {
8123   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8124                                       V128, V64,
8125                                       V128_lo, VectorIndexH,
8126                                       asm, ".4s", ".4s", ".4h", ".h",
8127     [(set (v4i32 V128:$Rd),
8128         (OpNode (v4i16 V64:$Rn),
8129          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8130     bits<3> idx;
8131     let Inst{11} = idx{2};
8132     let Inst{21} = idx{1};
8133     let Inst{20} = idx{0};
8134   }
8135
8136   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8137                                       V128, V128,
8138                                       V128_lo, VectorIndexH,
8139                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8140     [(set (v4i32 V128:$Rd),
8141           (OpNode (extract_high_v8i16 V128:$Rn),
8142                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8143                                                       VectorIndexH:$idx))))]> {
8144
8145     bits<3> idx;
8146     let Inst{11} = idx{2};
8147     let Inst{21} = idx{1};
8148     let Inst{20} = idx{0};
8149   }
8150
8151   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8152                                       V128, V64,
8153                                       V128, VectorIndexS,
8154                                       asm, ".2d", ".2d", ".2s", ".s",
8155     [(set (v2i64 V128:$Rd),
8156         (OpNode (v2i32 V64:$Rn),
8157          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8158     bits<2> idx;
8159     let Inst{11} = idx{1};
8160     let Inst{21} = idx{0};
8161   }
8162
8163   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8164                                       V128, V128,
8165                                       V128, VectorIndexS,
8166                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8167     [(set (v2i64 V128:$Rd),
8168           (OpNode (extract_high_v4i32 V128:$Rn),
8169                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8170                                                       VectorIndexS:$idx))))]> {
8171     bits<2> idx;
8172     let Inst{11} = idx{1};
8173     let Inst{21} = idx{0};
8174   }
8175
8176   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
8177                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8178                                       asm, ".h", "", "", ".h", []> {
8179     bits<3> idx;
8180     let Inst{11} = idx{2};
8181     let Inst{21} = idx{1};
8182     let Inst{20} = idx{0};
8183   }
8184
8185   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8186                                       FPR64Op, FPR32Op, V128, VectorIndexS,
8187                                       asm, ".s", "", "", ".s", []> {
8188     bits<2> idx;
8189     let Inst{11} = idx{1};
8190     let Inst{21} = idx{0};
8191   }
8192 }
8193
8194 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
8195                                        SDPatternOperator Accum> {
8196   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8197                                       V128, V64,
8198                                       V128_lo, VectorIndexH,
8199                                       asm, ".4s", ".4s", ".4h", ".h",
8200     [(set (v4i32 V128:$dst),
8201           (Accum (v4i32 V128:$Rd),
8202                  (v4i32 (int_aarch64_neon_sqdmull
8203                              (v4i16 V64:$Rn),
8204                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8205                                                     VectorIndexH:$idx))))))]> {
8206     bits<3> idx;
8207     let Inst{11} = idx{2};
8208     let Inst{21} = idx{1};
8209     let Inst{20} = idx{0};
8210   }
8211
8212   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
8213   // intermediate EXTRACT_SUBREG would be untyped.
8214   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8215                 (i32 (vector_extract (v4i32
8216                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
8217                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8218                                                     VectorIndexH:$idx)))),
8219                          (i64 0))))),
8220             (EXTRACT_SUBREG
8221                 (!cast<Instruction>(NAME # v4i16_indexed)
8222                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
8223                     V128_lo:$Rm, VectorIndexH:$idx),
8224                 ssub)>;
8225
8226   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8227                                       V128, V128,
8228                                       V128_lo, VectorIndexH,
8229                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8230     [(set (v4i32 V128:$dst),
8231           (Accum (v4i32 V128:$Rd),
8232                  (v4i32 (int_aarch64_neon_sqdmull
8233                             (extract_high_v8i16 V128:$Rn),
8234                             (extract_high_v8i16
8235                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8236                                                 VectorIndexH:$idx))))))]> {
8237     bits<3> idx;
8238     let Inst{11} = idx{2};
8239     let Inst{21} = idx{1};
8240     let Inst{20} = idx{0};
8241   }
8242
8243   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8244                                       V128, V64,
8245                                       V128, VectorIndexS,
8246                                       asm, ".2d", ".2d", ".2s", ".s",
8247     [(set (v2i64 V128:$dst),
8248         (Accum (v2i64 V128:$Rd),
8249                (v2i64 (int_aarch64_neon_sqdmull
8250                           (v2i32 V64:$Rn),
8251                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8252                                                  VectorIndexS:$idx))))))]> {
8253     bits<2> idx;
8254     let Inst{11} = idx{1};
8255     let Inst{21} = idx{0};
8256   }
8257
8258   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8259                                       V128, V128,
8260                                       V128, VectorIndexS,
8261                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8262     [(set (v2i64 V128:$dst),
8263           (Accum (v2i64 V128:$Rd),
8264                  (v2i64 (int_aarch64_neon_sqdmull
8265                             (extract_high_v4i32 V128:$Rn),
8266                             (extract_high_v4i32
8267                                 (AArch64duplane32 (v4i32 V128:$Rm),
8268                                                 VectorIndexS:$idx))))))]> {
8269     bits<2> idx;
8270     let Inst{11} = idx{1};
8271     let Inst{21} = idx{0};
8272   }
8273
8274   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8275                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8276                                       asm, ".h", "", "", ".h", []> {
8277     bits<3> idx;
8278     let Inst{11} = idx{2};
8279     let Inst{21} = idx{1};
8280     let Inst{20} = idx{0};
8281   }
8282
8283
8284   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8285                                       FPR64Op, FPR32Op, V128, VectorIndexS,
8286                                       asm, ".s", "", "", ".s",
8287     [(set (i64 FPR64Op:$dst),
8288           (Accum (i64 FPR64Op:$Rd),
8289                  (i64 (int_aarch64_neon_sqdmulls_scalar
8290                             (i32 FPR32Op:$Rn),
8291                             (i32 (vector_extract (v4i32 V128:$Rm),
8292                                                  VectorIndexS:$idx))))))]> {
8293
8294     bits<2> idx;
8295     let Inst{11} = idx{1};
8296     let Inst{21} = idx{0};
8297   }
8298 }
8299
8300 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
8301                                    SDPatternOperator OpNode> {
8302   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8303   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8304                                       V128, V64,
8305                                       V128_lo, VectorIndexH,
8306                                       asm, ".4s", ".4s", ".4h", ".h",
8307     [(set (v4i32 V128:$Rd),
8308         (OpNode (v4i16 V64:$Rn),
8309          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8310     bits<3> idx;
8311     let Inst{11} = idx{2};
8312     let Inst{21} = idx{1};
8313     let Inst{20} = idx{0};
8314   }
8315
8316   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8317                                       V128, V128,
8318                                       V128_lo, VectorIndexH,
8319                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8320     [(set (v4i32 V128:$Rd),
8321           (OpNode (extract_high_v8i16 V128:$Rn),
8322                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8323                                                       VectorIndexH:$idx))))]> {
8324
8325     bits<3> idx;
8326     let Inst{11} = idx{2};
8327     let Inst{21} = idx{1};
8328     let Inst{20} = idx{0};
8329   }
8330
8331   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8332                                       V128, V64,
8333                                       V128, VectorIndexS,
8334                                       asm, ".2d", ".2d", ".2s", ".s",
8335     [(set (v2i64 V128:$Rd),
8336         (OpNode (v2i32 V64:$Rn),
8337          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8338     bits<2> idx;
8339     let Inst{11} = idx{1};
8340     let Inst{21} = idx{0};
8341   }
8342
8343   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8344                                       V128, V128,
8345                                       V128, VectorIndexS,
8346                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8347     [(set (v2i64 V128:$Rd),
8348           (OpNode (extract_high_v4i32 V128:$Rn),
8349                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8350                                                       VectorIndexS:$idx))))]> {
8351     bits<2> idx;
8352     let Inst{11} = idx{1};
8353     let Inst{21} = idx{0};
8354   }
8355   }
8356 }
8357
8358 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
8359                                        SDPatternOperator OpNode> {
8360   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8361   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8362                                       V128, V64,
8363                                       V128_lo, VectorIndexH,
8364                                       asm, ".4s", ".4s", ".4h", ".h",
8365     [(set (v4i32 V128:$dst),
8366         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
8367          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8368     bits<3> idx;
8369     let Inst{11} = idx{2};
8370     let Inst{21} = idx{1};
8371     let Inst{20} = idx{0};
8372   }
8373
8374   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8375                                       V128, V128,
8376                                       V128_lo, VectorIndexH,
8377                                       asm#"2", ".4s", ".4s", ".8h", ".h",
8378     [(set (v4i32 V128:$dst),
8379           (OpNode (v4i32 V128:$Rd),
8380                   (extract_high_v8i16 V128:$Rn),
8381                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8382                                                       VectorIndexH:$idx))))]> {
8383     bits<3> idx;
8384     let Inst{11} = idx{2};
8385     let Inst{21} = idx{1};
8386     let Inst{20} = idx{0};
8387   }
8388
8389   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8390                                       V128, V64,
8391                                       V128, VectorIndexS,
8392                                       asm, ".2d", ".2d", ".2s", ".s",
8393     [(set (v2i64 V128:$dst),
8394         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
8395          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8396     bits<2> idx;
8397     let Inst{11} = idx{1};
8398     let Inst{21} = idx{0};
8399   }
8400
8401   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8402                                       V128, V128,
8403                                       V128, VectorIndexS,
8404                                       asm#"2", ".2d", ".2d", ".4s", ".s",
8405     [(set (v2i64 V128:$dst),
8406           (OpNode (v2i64 V128:$Rd),
8407                   (extract_high_v4i32 V128:$Rn),
8408                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8409                                                       VectorIndexS:$idx))))]> {
8410     bits<2> idx;
8411     let Inst{11} = idx{1};
8412     let Inst{21} = idx{0};
8413   }
8414   }
8415 }
8416
8417 //----------------------------------------------------------------------------
8418 // AdvSIMD scalar shift by immediate
8419 //----------------------------------------------------------------------------
8420
8421 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8422 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
8423                      RegisterClass regtype1, RegisterClass regtype2,
8424                      Operand immtype, string asm, list<dag> pattern>
8425   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
8426       asm, "\t$Rd, $Rn, $imm", "", pattern>,
8427     Sched<[WriteV]> {
8428   bits<5> Rd;
8429   bits<5> Rn;
8430   bits<7> imm;
8431   let Inst{31-30} = 0b01;
8432   let Inst{29}    = U;
8433   let Inst{28-23} = 0b111110;
8434   let Inst{22-16} = fixed_imm;
8435   let Inst{15-11} = opc;
8436   let Inst{10}    = 1;
8437   let Inst{9-5} = Rn;
8438   let Inst{4-0} = Rd;
8439 }
8440
8441 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8442 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
8443                      RegisterClass regtype1, RegisterClass regtype2,
8444                      Operand immtype, string asm, list<dag> pattern>
8445   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
8446       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
8447     Sched<[WriteV]> {
8448   bits<5> Rd;
8449   bits<5> Rn;
8450   bits<7> imm;
8451   let Inst{31-30} = 0b01;
8452   let Inst{29}    = U;
8453   let Inst{28-23} = 0b111110;
8454   let Inst{22-16} = fixed_imm;
8455   let Inst{15-11} = opc;
8456   let Inst{10}    = 1;
8457   let Inst{9-5} = Rn;
8458   let Inst{4-0} = Rd;
8459 }
8460
8461
8462 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
8463   let Predicates = [HasNEON, HasFullFP16] in {
8464   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8465                               FPR16, FPR16, vecshiftR16, asm, []> {
8466     let Inst{19-16} = imm{3-0};
8467   }
8468   } // Predicates = [HasNEON, HasFullFP16]
8469   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8470                               FPR32, FPR32, vecshiftR32, asm, []> {
8471     let Inst{20-16} = imm{4-0};
8472   }
8473   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8474                               FPR64, FPR64, vecshiftR64, asm, []> {
8475     let Inst{21-16} = imm{5-0};
8476   }
8477 }
8478
8479 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
8480                              SDPatternOperator OpNode> {
8481   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8482                               FPR64, FPR64, vecshiftR64, asm,
8483   [(set (i64 FPR64:$Rd),
8484      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
8485     let Inst{21-16} = imm{5-0};
8486   }
8487
8488   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
8489             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
8490 }
8491
8492 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
8493                                  SDPatternOperator OpNode = null_frag> {
8494   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8495                               FPR64, FPR64, vecshiftR64, asm,
8496   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
8497                                                    (i32 vecshiftR64:$imm)))]> {
8498     let Inst{21-16} = imm{5-0};
8499   }
8500
8501   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
8502                            (i32 vecshiftR64:$imm))),
8503             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
8504                                             vecshiftR64:$imm)>;
8505 }
8506
8507 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
8508                              SDPatternOperator OpNode> {
8509   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8510                               FPR64, FPR64, vecshiftL64, asm,
8511     [(set (v1i64 FPR64:$Rd),
8512        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8513     let Inst{21-16} = imm{5-0};
8514   }
8515 }
8516
8517 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8518 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
8519   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8520                               FPR64, FPR64, vecshiftL64, asm, []> {
8521     let Inst{21-16} = imm{5-0};
8522   }
8523 }
8524
8525 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8526 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
8527                                SDPatternOperator OpNode = null_frag> {
8528   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8529                               FPR8, FPR16, vecshiftR8, asm, []> {
8530     let Inst{18-16} = imm{2-0};
8531   }
8532
8533   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8534                               FPR16, FPR32, vecshiftR16, asm, []> {
8535     let Inst{19-16} = imm{3-0};
8536   }
8537
8538   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8539                               FPR32, FPR64, vecshiftR32, asm,
8540     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
8541     let Inst{20-16} = imm{4-0};
8542   }
8543 }
8544
8545 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
8546                                 SDPatternOperator OpNode> {
8547   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8548                               FPR8, FPR8, vecshiftL8, asm, []> {
8549     let Inst{18-16} = imm{2-0};
8550   }
8551
8552   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8553                               FPR16, FPR16, vecshiftL16, asm, []> {
8554     let Inst{19-16} = imm{3-0};
8555   }
8556
8557   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8558                               FPR32, FPR32, vecshiftL32, asm,
8559     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
8560     let Inst{20-16} = imm{4-0};
8561   }
8562
8563   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8564                               FPR64, FPR64, vecshiftL64, asm,
8565     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8566     let Inst{21-16} = imm{5-0};
8567   }
8568
8569   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
8570             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
8571 }
8572
8573 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
8574   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8575                               FPR8, FPR8, vecshiftR8, asm, []> {
8576     let Inst{18-16} = imm{2-0};
8577   }
8578
8579   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8580                               FPR16, FPR16, vecshiftR16, asm, []> {
8581     let Inst{19-16} = imm{3-0};
8582   }
8583
8584   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8585                               FPR32, FPR32, vecshiftR32, asm, []> {
8586     let Inst{20-16} = imm{4-0};
8587   }
8588
8589   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8590                               FPR64, FPR64, vecshiftR64, asm, []> {
8591     let Inst{21-16} = imm{5-0};
8592   }
8593 }
8594
8595 //----------------------------------------------------------------------------
8596 // AdvSIMD vector x indexed element
8597 //----------------------------------------------------------------------------
8598
8599 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8600 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8601                      RegisterOperand dst_reg, RegisterOperand src_reg,
8602                      Operand immtype,
8603                      string asm, string dst_kind, string src_kind,
8604                      list<dag> pattern>
8605   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
8606       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8607            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
8608     Sched<[WriteV]> {
8609   bits<5> Rd;
8610   bits<5> Rn;
8611   let Inst{31}    = 0;
8612   let Inst{30}    = Q;
8613   let Inst{29}    = U;
8614   let Inst{28-23} = 0b011110;
8615   let Inst{22-16} = fixed_imm;
8616   let Inst{15-11} = opc;
8617   let Inst{10}    = 1;
8618   let Inst{9-5}   = Rn;
8619   let Inst{4-0}   = Rd;
8620 }
8621
8622 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8623 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8624                      RegisterOperand vectype1, RegisterOperand vectype2,
8625                      Operand immtype,
8626                      string asm, string dst_kind, string src_kind,
8627                      list<dag> pattern>
8628   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
8629       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8630            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
8631     Sched<[WriteV]> {
8632   bits<5> Rd;
8633   bits<5> Rn;
8634   let Inst{31}    = 0;
8635   let Inst{30}    = Q;
8636   let Inst{29}    = U;
8637   let Inst{28-23} = 0b011110;
8638   let Inst{22-16} = fixed_imm;
8639   let Inst{15-11} = opc;
8640   let Inst{10}    = 1;
8641   let Inst{9-5}   = Rn;
8642   let Inst{4-0}   = Rd;
8643 }
8644
8645 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
8646                               Intrinsic OpNode> {
8647   let Predicates = [HasNEON, HasFullFP16] in {
8648   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8649                                   V64, V64, vecshiftR16,
8650                                   asm, ".4h", ".4h",
8651       [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
8652     bits<4> imm;
8653     let Inst{19-16} = imm;
8654   }
8655
8656   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8657                                   V128, V128, vecshiftR16,
8658                                   asm, ".8h", ".8h",
8659       [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
8660     bits<4> imm;
8661     let Inst{19-16} = imm;
8662   }
8663   } // Predicates = [HasNEON, HasFullFP16]
8664   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8665                                   V64, V64, vecshiftR32,
8666                                   asm, ".2s", ".2s",
8667       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
8668     bits<5> imm;
8669     let Inst{20-16} = imm;
8670   }
8671
8672   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8673                                   V128, V128, vecshiftR32,
8674                                   asm, ".4s", ".4s",
8675       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
8676     bits<5> imm;
8677     let Inst{20-16} = imm;
8678   }
8679
8680   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8681                                   V128, V128, vecshiftR64,
8682                                   asm, ".2d", ".2d",
8683       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
8684     bits<6> imm;
8685     let Inst{21-16} = imm;
8686   }
8687 }
8688
8689 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
8690                                   Intrinsic OpNode> {
8691   let Predicates = [HasNEON, HasFullFP16] in {
8692   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8693                                   V64, V64, vecshiftR16,
8694                                   asm, ".4h", ".4h",
8695       [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
8696     bits<4> imm;
8697     let Inst{19-16} = imm;
8698   }
8699
8700   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8701                                   V128, V128, vecshiftR16,
8702                                   asm, ".8h", ".8h",
8703       [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
8704     bits<4> imm;
8705     let Inst{19-16} = imm;
8706   }
8707   } // Predicates = [HasNEON, HasFullFP16]
8708
8709   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8710                                   V64, V64, vecshiftR32,
8711                                   asm, ".2s", ".2s",
8712       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
8713     bits<5> imm;
8714     let Inst{20-16} = imm;
8715   }
8716
8717   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8718                                   V128, V128, vecshiftR32,
8719                                   asm, ".4s", ".4s",
8720       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
8721     bits<5> imm;
8722     let Inst{20-16} = imm;
8723   }
8724
8725   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8726                                   V128, V128, vecshiftR64,
8727                                   asm, ".2d", ".2d",
8728       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
8729     bits<6> imm;
8730     let Inst{21-16} = imm;
8731   }
8732 }
8733
8734 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
8735                                      SDPatternOperator OpNode> {
8736   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8737                                   V64, V128, vecshiftR16Narrow,
8738                                   asm, ".8b", ".8h",
8739       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
8740     bits<3> imm;
8741     let Inst{18-16} = imm;
8742   }
8743
8744   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8745                                   V128, V128, vecshiftR16Narrow,
8746                                   asm#"2", ".16b", ".8h", []> {
8747     bits<3> imm;
8748     let Inst{18-16} = imm;
8749     let hasSideEffects = 0;
8750   }
8751
8752   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8753                                   V64, V128, vecshiftR32Narrow,
8754                                   asm, ".4h", ".4s",
8755       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
8756     bits<4> imm;
8757     let Inst{19-16} = imm;
8758   }
8759
8760   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8761                                   V128, V128, vecshiftR32Narrow,
8762                                   asm#"2", ".8h", ".4s", []> {
8763     bits<4> imm;
8764     let Inst{19-16} = imm;
8765     let hasSideEffects = 0;
8766   }
8767
8768   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8769                                   V64, V128, vecshiftR64Narrow,
8770                                   asm, ".2s", ".2d",
8771       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
8772     bits<5> imm;
8773     let Inst{20-16} = imm;
8774   }
8775
8776   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8777                                   V128, V128, vecshiftR64Narrow,
8778                                   asm#"2", ".4s", ".2d", []> {
8779     bits<5> imm;
8780     let Inst{20-16} = imm;
8781     let hasSideEffects = 0;
8782   }
8783
8784   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
8785   // themselves, so put them here instead.
8786
8787   // Patterns involving what's effectively an insert high and a normal
8788   // intrinsic, represented by CONCAT_VECTORS.
8789   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
8790                                                    vecshiftR16Narrow:$imm)),
8791             (!cast<Instruction>(NAME # "v16i8_shift")
8792                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8793                 V128:$Rn, vecshiftR16Narrow:$imm)>;
8794   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
8795                                                      vecshiftR32Narrow:$imm)),
8796             (!cast<Instruction>(NAME # "v8i16_shift")
8797                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8798                 V128:$Rn, vecshiftR32Narrow:$imm)>;
8799   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
8800                                                      vecshiftR64Narrow:$imm)),
8801             (!cast<Instruction>(NAME # "v4i32_shift")
8802                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8803                 V128:$Rn, vecshiftR64Narrow:$imm)>;
8804 }
8805
8806 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
8807                                 SDPatternOperator OpNode> {
8808   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8809                                   V64, V64, vecshiftL8,
8810                                   asm, ".8b", ".8b",
8811                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8812                        (i32 vecshiftL8:$imm)))]> {
8813     bits<3> imm;
8814     let Inst{18-16} = imm;
8815   }
8816
8817   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8818                                   V128, V128, vecshiftL8,
8819                                   asm, ".16b", ".16b",
8820              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8821                    (i32 vecshiftL8:$imm)))]> {
8822     bits<3> imm;
8823     let Inst{18-16} = imm;
8824   }
8825
8826   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8827                                   V64, V64, vecshiftL16,
8828                                   asm, ".4h", ".4h",
8829               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8830                     (i32 vecshiftL16:$imm)))]> {
8831     bits<4> imm;
8832     let Inst{19-16} = imm;
8833   }
8834
8835   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8836                                   V128, V128, vecshiftL16,
8837                                   asm, ".8h", ".8h",
8838             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8839                   (i32 vecshiftL16:$imm)))]> {
8840     bits<4> imm;
8841     let Inst{19-16} = imm;
8842   }
8843
8844   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8845                                   V64, V64, vecshiftL32,
8846                                   asm, ".2s", ".2s",
8847               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8848                     (i32 vecshiftL32:$imm)))]> {
8849     bits<5> imm;
8850     let Inst{20-16} = imm;
8851   }
8852
8853   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8854                                   V128, V128, vecshiftL32,
8855                                   asm, ".4s", ".4s",
8856             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8857                   (i32 vecshiftL32:$imm)))]> {
8858     bits<5> imm;
8859     let Inst{20-16} = imm;
8860   }
8861
8862   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8863                                   V128, V128, vecshiftL64,
8864                                   asm, ".2d", ".2d",
8865             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8866                   (i32 vecshiftL64:$imm)))]> {
8867     bits<6> imm;
8868     let Inst{21-16} = imm;
8869   }
8870 }
8871
8872 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
8873                                 SDPatternOperator OpNode> {
8874   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8875                                   V64, V64, vecshiftR8,
8876                                   asm, ".8b", ".8b",
8877                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8878                        (i32 vecshiftR8:$imm)))]> {
8879     bits<3> imm;
8880     let Inst{18-16} = imm;
8881   }
8882
8883   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8884                                   V128, V128, vecshiftR8,
8885                                   asm, ".16b", ".16b",
8886              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8887                    (i32 vecshiftR8:$imm)))]> {
8888     bits<3> imm;
8889     let Inst{18-16} = imm;
8890   }
8891
8892   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8893                                   V64, V64, vecshiftR16,
8894                                   asm, ".4h", ".4h",
8895               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8896                     (i32 vecshiftR16:$imm)))]> {
8897     bits<4> imm;
8898     let Inst{19-16} = imm;
8899   }
8900
8901   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8902                                   V128, V128, vecshiftR16,
8903                                   asm, ".8h", ".8h",
8904             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8905                   (i32 vecshiftR16:$imm)))]> {
8906     bits<4> imm;
8907     let Inst{19-16} = imm;
8908   }
8909
8910   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8911                                   V64, V64, vecshiftR32,
8912                                   asm, ".2s", ".2s",
8913               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8914                     (i32 vecshiftR32:$imm)))]> {
8915     bits<5> imm;
8916     let Inst{20-16} = imm;
8917   }
8918
8919   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8920                                   V128, V128, vecshiftR32,
8921                                   asm, ".4s", ".4s",
8922             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8923                   (i32 vecshiftR32:$imm)))]> {
8924     bits<5> imm;
8925     let Inst{20-16} = imm;
8926   }
8927
8928   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8929                                   V128, V128, vecshiftR64,
8930                                   asm, ".2d", ".2d",
8931             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8932                   (i32 vecshiftR64:$imm)))]> {
8933     bits<6> imm;
8934     let Inst{21-16} = imm;
8935   }
8936 }
8937
8938 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8939 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8940                                     SDPatternOperator OpNode = null_frag> {
8941   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8942                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
8943                  [(set (v8i8 V64:$dst),
8944                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8945                            (i32 vecshiftR8:$imm)))]> {
8946     bits<3> imm;
8947     let Inst{18-16} = imm;
8948   }
8949
8950   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8951                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
8952              [(set (v16i8 V128:$dst),
8953                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8954                        (i32 vecshiftR8:$imm)))]> {
8955     bits<3> imm;
8956     let Inst{18-16} = imm;
8957   }
8958
8959   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8960                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
8961               [(set (v4i16 V64:$dst),
8962                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8963                         (i32 vecshiftR16:$imm)))]> {
8964     bits<4> imm;
8965     let Inst{19-16} = imm;
8966   }
8967
8968   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8969                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
8970             [(set (v8i16 V128:$dst),
8971               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8972                       (i32 vecshiftR16:$imm)))]> {
8973     bits<4> imm;
8974     let Inst{19-16} = imm;
8975   }
8976
8977   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8978                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
8979               [(set (v2i32 V64:$dst),
8980                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8981                         (i32 vecshiftR32:$imm)))]> {
8982     bits<5> imm;
8983     let Inst{20-16} = imm;
8984   }
8985
8986   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8987                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
8988             [(set (v4i32 V128:$dst),
8989               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8990                       (i32 vecshiftR32:$imm)))]> {
8991     bits<5> imm;
8992     let Inst{20-16} = imm;
8993   }
8994
8995   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8996                                   V128, V128, vecshiftR64,
8997                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8998               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8999                       (i32 vecshiftR64:$imm)))]> {
9000     bits<6> imm;
9001     let Inst{21-16} = imm;
9002   }
9003 }
9004
9005 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
9006                                     SDPatternOperator OpNode = null_frag> {
9007   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
9008                                   V64, V64, vecshiftL8,
9009                                   asm, ".8b", ".8b",
9010                     [(set (v8i8 V64:$dst),
9011                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
9012                                   (i32 vecshiftL8:$imm)))]> {
9013     bits<3> imm;
9014     let Inst{18-16} = imm;
9015   }
9016
9017   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9018                                   V128, V128, vecshiftL8,
9019                                   asm, ".16b", ".16b",
9020                     [(set (v16i8 V128:$dst),
9021                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
9022                                   (i32 vecshiftL8:$imm)))]> {
9023     bits<3> imm;
9024     let Inst{18-16} = imm;
9025   }
9026
9027   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
9028                                   V64, V64, vecshiftL16,
9029                                   asm, ".4h", ".4h",
9030                     [(set (v4i16 V64:$dst),
9031                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
9032                                    (i32 vecshiftL16:$imm)))]> {
9033     bits<4> imm;
9034     let Inst{19-16} = imm;
9035   }
9036
9037   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9038                                   V128, V128, vecshiftL16,
9039                                   asm, ".8h", ".8h",
9040                     [(set (v8i16 V128:$dst),
9041                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9042                                   (i32 vecshiftL16:$imm)))]> {
9043     bits<4> imm;
9044     let Inst{19-16} = imm;
9045   }
9046
9047   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
9048                                   V64, V64, vecshiftL32,
9049                                   asm, ".2s", ".2s",
9050                     [(set (v2i32 V64:$dst),
9051                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9052                                   (i32 vecshiftL32:$imm)))]> {
9053     bits<5> imm;
9054     let Inst{20-16} = imm;
9055   }
9056
9057   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9058                                   V128, V128, vecshiftL32,
9059                                   asm, ".4s", ".4s",
9060                     [(set (v4i32 V128:$dst),
9061                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9062                                   (i32 vecshiftL32:$imm)))]> {
9063     bits<5> imm;
9064     let Inst{20-16} = imm;
9065   }
9066
9067   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
9068                                   V128, V128, vecshiftL64,
9069                                   asm, ".2d", ".2d",
9070                     [(set (v2i64 V128:$dst),
9071                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
9072                                   (i32 vecshiftL64:$imm)))]> {
9073     bits<6> imm;
9074     let Inst{21-16} = imm;
9075   }
9076 }
9077
9078 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
9079                                    SDPatternOperator OpNode> {
9080   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9081                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
9082       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
9083     bits<3> imm;
9084     let Inst{18-16} = imm;
9085   }
9086
9087   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9088                                   V128, V128, vecshiftL8,
9089                                   asm#"2", ".8h", ".16b",
9090       [(set (v8i16 V128:$Rd),
9091             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
9092     bits<3> imm;
9093     let Inst{18-16} = imm;
9094   }
9095
9096   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9097                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
9098       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
9099     bits<4> imm;
9100     let Inst{19-16} = imm;
9101   }
9102
9103   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9104                                   V128, V128, vecshiftL16,
9105                                   asm#"2", ".4s", ".8h",
9106       [(set (v4i32 V128:$Rd),
9107             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
9108
9109     bits<4> imm;
9110     let Inst{19-16} = imm;
9111   }
9112
9113   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9114                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
9115       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
9116     bits<5> imm;
9117     let Inst{20-16} = imm;
9118   }
9119
9120   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9121                                   V128, V128, vecshiftL32,
9122                                   asm#"2", ".2d", ".4s",
9123       [(set (v2i64 V128:$Rd),
9124             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
9125     bits<5> imm;
9126     let Inst{20-16} = imm;
9127   }
9128 }
9129
9130
9131 //---
9132 // Vector load/store
9133 //---
9134 // SIMD ldX/stX no-index memory references don't allow the optional
9135 // ", #0" constant and handle post-indexing explicitly, so we use
9136 // a more specialized parse method for them. Otherwise, it's the same as
9137 // the general GPR64sp handling.
9138
9139 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
9140                    string asm, dag oops, dag iops, list<dag> pattern>
9141   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
9142   bits<5> Vt;
9143   bits<5> Rn;
9144   let Inst{31} = 0;
9145   let Inst{30} = Q;
9146   let Inst{29-23} = 0b0011000;
9147   let Inst{22} = L;
9148   let Inst{21-16} = 0b000000;
9149   let Inst{15-12} = opcode;
9150   let Inst{11-10} = size;
9151   let Inst{9-5} = Rn;
9152   let Inst{4-0} = Vt;
9153 }
9154
9155 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
9156                        string asm, dag oops, dag iops>
9157   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
9158   bits<5> Vt;
9159   bits<5> Rn;
9160   bits<5> Xm;
9161   let Inst{31} = 0;
9162   let Inst{30} = Q;
9163   let Inst{29-23} = 0b0011001;
9164   let Inst{22} = L;
9165   let Inst{21} = 0;
9166   let Inst{20-16} = Xm;
9167   let Inst{15-12} = opcode;
9168   let Inst{11-10} = size;
9169   let Inst{9-5} = Rn;
9170   let Inst{4-0} = Vt;
9171 }
9172
9173 // The immediate form of AdvSIMD post-indexed addressing is encoded with
9174 // register post-index addressing from the zero register.
9175 multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
9176                            int Offset, int Size> {
9177   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
9178   //      "ld1\t$Vt, [$Rn], #16"
9179   // may get mapped to
9180   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
9181   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9182                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9183                       GPR64sp:$Rn,
9184                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9185                       XZR), 1>;
9186
9187   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
9188   //      "ld1.8b\t$Vt, [$Rn], #16"
9189   // may get mapped to
9190   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
9191   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9192                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9193                       GPR64sp:$Rn,
9194                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9195                       XZR), 0>;
9196
9197   // E.g. "ld1.8b { v0, v1 }, [x1]"
9198   //      "ld1\t$Vt, [$Rn]"
9199   // may get mapped to
9200   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
9201   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9202                   (!cast<Instruction>(BaseName # Count # "v" # layout)
9203                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9204                       GPR64sp:$Rn), 0>;
9205
9206   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
9207   //      "ld1\t$Vt, [$Rn], $Xm"
9208   // may get mapped to
9209   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
9210   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9211                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9212                       GPR64sp:$Rn,
9213                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9214                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9215 }
9216
9217 multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
9218                        int Offset128, int Offset64, bits<4> opcode> {
9219   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9220     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
9221                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
9222                            (ins GPR64sp:$Rn), []>;
9223     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
9224                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
9225                            (ins GPR64sp:$Rn), []>;
9226     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
9227                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
9228                            (ins GPR64sp:$Rn), []>;
9229     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
9230                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
9231                            (ins GPR64sp:$Rn), []>;
9232     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
9233                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
9234                            (ins GPR64sp:$Rn), []>;
9235     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
9236                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
9237                            (ins GPR64sp:$Rn), []>;
9238     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
9239                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
9240                            (ins GPR64sp:$Rn), []>;
9241
9242
9243     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
9244                        (outs GPR64sp:$wback,
9245                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
9246                        (ins GPR64sp:$Rn,
9247                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9248     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
9249                        (outs GPR64sp:$wback,
9250                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
9251                        (ins GPR64sp:$Rn,
9252                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9253     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
9254                        (outs GPR64sp:$wback,
9255                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
9256                        (ins GPR64sp:$Rn,
9257                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9258     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
9259                        (outs GPR64sp:$wback,
9260                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
9261                        (ins GPR64sp:$Rn,
9262                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9263     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
9264                        (outs GPR64sp:$wback,
9265                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
9266                        (ins GPR64sp:$Rn,
9267                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9268     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
9269                        (outs GPR64sp:$wback,
9270                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
9271                        (ins GPR64sp:$Rn,
9272                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9273     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
9274                        (outs GPR64sp:$wback,
9275                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
9276                        (ins GPR64sp:$Rn,
9277                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9278   }
9279
9280   defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9281   defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9282   defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9283   defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9284   defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9285   defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9286   defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9287 }
9288
9289 // Only ld1/st1 has a v1d version.
9290 multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
9291                        int Offset128, int Offset64, bits<4> opcode> {
9292   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
9293     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
9294                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9295                                  GPR64sp:$Rn), []>;
9296     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
9297                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9298                                 GPR64sp:$Rn), []>;
9299     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
9300                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9301                                 GPR64sp:$Rn), []>;
9302     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
9303                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9304                                 GPR64sp:$Rn), []>;
9305     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
9306                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9307                                 GPR64sp:$Rn), []>;
9308     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
9309                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9310                                 GPR64sp:$Rn), []>;
9311     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
9312                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9313                                 GPR64sp:$Rn), []>;
9314
9315     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
9316                        (outs GPR64sp:$wback),
9317                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9318                             GPR64sp:$Rn,
9319                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9320     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
9321                        (outs GPR64sp:$wback),
9322                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9323                             GPR64sp:$Rn,
9324                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9325     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
9326                        (outs GPR64sp:$wback),
9327                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9328                             GPR64sp:$Rn,
9329                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9330     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
9331                        (outs GPR64sp:$wback),
9332                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9333                             GPR64sp:$Rn,
9334                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9335     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
9336                        (outs GPR64sp:$wback),
9337                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9338                             GPR64sp:$Rn,
9339                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9340     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
9341                        (outs GPR64sp:$wback),
9342                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9343                             GPR64sp:$Rn,
9344                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9345     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
9346                        (outs GPR64sp:$wback),
9347                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9348                             GPR64sp:$Rn,
9349                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9350   }
9351
9352   defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9353   defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9354   defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9355   defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9356   defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9357   defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9358   defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9359 }
9360
9361 multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
9362                        int Offset128, int Offset64, bits<4> opcode>
9363   : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9364
9365   // LD1 instructions have extra "1d" variants.
9366   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9367     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
9368                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
9369                            (ins GPR64sp:$Rn), []>;
9370
9371     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
9372                        (outs GPR64sp:$wback,
9373                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
9374                        (ins GPR64sp:$Rn,
9375                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9376   }
9377
9378   defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9379 }
9380
9381 multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
9382                        int Offset128, int Offset64, bits<4> opcode>
9383   : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9384
9385   // ST1 instructions have extra "1d" variants.
9386   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
9387     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
9388                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9389                                 GPR64sp:$Rn), []>;
9390
9391     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
9392                        (outs GPR64sp:$wback),
9393                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9394                             GPR64sp:$Rn,
9395                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9396   }
9397
9398   defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9399 }
9400
9401 multiclass SIMDLd1Multiple<string asm> {
9402   defm One   : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8,  0b0111>;
9403   defm Two   : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9404   defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9405   defm Four  : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9406 }
9407
9408 multiclass SIMDSt1Multiple<string asm> {
9409   defm One   : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8,  0b0111>;
9410   defm Two   : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9411   defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9412   defm Four  : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9413 }
9414
9415 multiclass SIMDLd2Multiple<string asm> {
9416   defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9417 }
9418
9419 multiclass SIMDSt2Multiple<string asm> {
9420   defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9421 }
9422
9423 multiclass SIMDLd3Multiple<string asm> {
9424   defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9425 }
9426
9427 multiclass SIMDSt3Multiple<string asm> {
9428   defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9429 }
9430
9431 multiclass SIMDLd4Multiple<string asm> {
9432   defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9433 }
9434
9435 multiclass SIMDSt4Multiple<string asm> {
9436   defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9437 }
9438
9439 //---
9440 // AdvSIMD Load/store single-element
9441 //---
9442
9443 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
9444                          string asm, string operands, string cst,
9445                          dag oops, dag iops, list<dag> pattern>
9446   : I<oops, iops, asm, operands, cst, pattern> {
9447   bits<5> Vt;
9448   bits<5> Rn;
9449   let Inst{31} = 0;
9450   let Inst{29-24} = 0b001101;
9451   let Inst{22} = L;
9452   let Inst{21} = R;
9453   let Inst{15-13} = opcode;
9454   let Inst{9-5} = Rn;
9455   let Inst{4-0} = Vt;
9456 }
9457
9458 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
9459                          string asm, string operands, string cst,
9460                          dag oops, dag iops, list<dag> pattern>
9461   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
9462   bits<5> Vt;
9463   bits<5> Rn;
9464   let Inst{31} = 0;
9465   let Inst{29-24} = 0b001101;
9466   let Inst{22} = L;
9467   let Inst{21} = R;
9468   let Inst{15-13} = opcode;
9469   let Inst{9-5} = Rn;
9470   let Inst{4-0} = Vt;
9471 }
9472
9473
9474 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9475 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
9476                   DAGOperand listtype>
9477   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
9478                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
9479                        []> {
9480   let Inst{30} = Q;
9481   let Inst{23} = 0;
9482   let Inst{20-16} = 0b00000;
9483   let Inst{12} = S;
9484   let Inst{11-10} = size;
9485 }
9486 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9487 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
9488                       string asm, DAGOperand listtype, DAGOperand GPR64pi>
9489   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
9490                        "$Rn = $wback",
9491                        (outs GPR64sp:$wback, listtype:$Vt),
9492                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
9493   bits<5> Xm;
9494   let Inst{30} = Q;
9495   let Inst{23} = 1;
9496   let Inst{20-16} = Xm;
9497   let Inst{12} = S;
9498   let Inst{11-10} = size;
9499 }
9500
9501 multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
9502                           int Offset, int Size> {
9503   // E.g. "ld1r { v0.8b }, [x1], #1"
9504   //      "ld1r.8b\t$Vt, [$Rn], #1"
9505   // may get mapped to
9506   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9507   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9508                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9509                       GPR64sp:$Rn,
9510                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9511                       XZR), 1>;
9512
9513   // E.g. "ld1r.8b { v0 }, [x1], #1"
9514   //      "ld1r.8b\t$Vt, [$Rn], #1"
9515   // may get mapped to
9516   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9517   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9518                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9519                       GPR64sp:$Rn,
9520                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9521                       XZR), 0>;
9522
9523   // E.g. "ld1r.8b { v0 }, [x1]"
9524   //      "ld1r.8b\t$Vt, [$Rn]"
9525   // may get mapped to
9526   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9527   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9528                   (!cast<Instruction>(BaseName # "v" # layout)
9529                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9530                       GPR64sp:$Rn), 0>;
9531
9532   // E.g. "ld1r.8b { v0 }, [x1], x2"
9533   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
9534   // may get mapped to
9535   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9536   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9537                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9538                       GPR64sp:$Rn,
9539                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9540                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9541 }
9542
9543 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
9544   int Offset1, int Offset2, int Offset4, int Offset8> {
9545   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
9546                         !cast<DAGOperand>("VecList" # Count # "8b")>;
9547   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
9548                         !cast<DAGOperand>("VecList" # Count #"16b")>;
9549   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
9550                         !cast<DAGOperand>("VecList" # Count #"4h")>;
9551   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
9552                         !cast<DAGOperand>("VecList" # Count #"8h")>;
9553   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
9554                         !cast<DAGOperand>("VecList" # Count #"2s")>;
9555   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
9556                         !cast<DAGOperand>("VecList" # Count #"4s")>;
9557   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
9558                         !cast<DAGOperand>("VecList" # Count #"1d")>;
9559   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
9560                         !cast<DAGOperand>("VecList" # Count #"2d")>;
9561
9562   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
9563                                  !cast<DAGOperand>("VecList" # Count # "8b"),
9564                                  !cast<DAGOperand>("GPR64pi" # Offset1)>;
9565   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
9566                                  !cast<DAGOperand>("VecList" # Count # "16b"),
9567                                  !cast<DAGOperand>("GPR64pi" # Offset1)>;
9568   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
9569                                  !cast<DAGOperand>("VecList" # Count # "4h"),
9570                                  !cast<DAGOperand>("GPR64pi" # Offset2)>;
9571   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
9572                                  !cast<DAGOperand>("VecList" # Count # "8h"),
9573                                  !cast<DAGOperand>("GPR64pi" # Offset2)>;
9574   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
9575                                  !cast<DAGOperand>("VecList" # Count # "2s"),
9576                                  !cast<DAGOperand>("GPR64pi" # Offset4)>;
9577   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
9578                                  !cast<DAGOperand>("VecList" # Count # "4s"),
9579                                  !cast<DAGOperand>("GPR64pi" # Offset4)>;
9580   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
9581                                  !cast<DAGOperand>("VecList" # Count # "1d"),
9582                                  !cast<DAGOperand>("GPR64pi" # Offset8)>;
9583   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
9584                                  !cast<DAGOperand>("VecList" # Count # "2d"),
9585                                  !cast<DAGOperand>("GPR64pi" # Offset8)>;
9586
9587   defm : SIMDLdrAliases<NAME, asm, "8b",  Count, Offset1,  64>;
9588   defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
9589   defm : SIMDLdrAliases<NAME, asm, "4h",  Count, Offset2,  64>;
9590   defm : SIMDLdrAliases<NAME, asm, "8h",  Count, Offset2, 128>;
9591   defm : SIMDLdrAliases<NAME, asm, "2s",  Count, Offset4,  64>;
9592   defm : SIMDLdrAliases<NAME, asm, "4s",  Count, Offset4, 128>;
9593   defm : SIMDLdrAliases<NAME, asm, "1d",  Count, Offset8,  64>;
9594   defm : SIMDLdrAliases<NAME, asm, "2d",  Count, Offset8, 128>;
9595 }
9596
9597 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
9598                       dag oops, dag iops, list<dag> pattern>
9599   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9600                        pattern> {
9601   // idx encoded in Q:S:size fields.
9602   bits<4> idx;
9603   let Inst{30} = idx{3};
9604   let Inst{23} = 0;
9605   let Inst{20-16} = 0b00000;
9606   let Inst{12} = idx{2};
9607   let Inst{11-10} = idx{1-0};
9608 }
9609 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
9610                       dag oops, dag iops, list<dag> pattern>
9611   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9612                            oops, iops, pattern> {
9613   // idx encoded in Q:S:size fields.
9614   bits<4> idx;
9615   let Inst{30} = idx{3};
9616   let Inst{23} = 0;
9617   let Inst{20-16} = 0b00000;
9618   let Inst{12} = idx{2};
9619   let Inst{11-10} = idx{1-0};
9620 }
9621 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
9622                           dag oops, dag iops>
9623   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9624                        "$Rn = $wback", oops, iops, []> {
9625   // idx encoded in Q:S:size fields.
9626   bits<4> idx;
9627   bits<5> Xm;
9628   let Inst{30} = idx{3};
9629   let Inst{23} = 1;
9630   let Inst{20-16} = Xm;
9631   let Inst{12} = idx{2};
9632   let Inst{11-10} = idx{1-0};
9633 }
9634 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
9635                           dag oops, dag iops>
9636   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9637                            "$Rn = $wback", oops, iops, []> {
9638   // idx encoded in Q:S:size fields.
9639   bits<4> idx;
9640   bits<5> Xm;
9641   let Inst{30} = idx{3};
9642   let Inst{23} = 1;
9643   let Inst{20-16} = Xm;
9644   let Inst{12} = idx{2};
9645   let Inst{11-10} = idx{1-0};
9646 }
9647
9648 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
9649                       dag oops, dag iops, list<dag> pattern>
9650   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9651                        pattern> {
9652   // idx encoded in Q:S:size<1> fields.
9653   bits<3> idx;
9654   let Inst{30} = idx{2};
9655   let Inst{23} = 0;
9656   let Inst{20-16} = 0b00000;
9657   let Inst{12} = idx{1};
9658   let Inst{11} = idx{0};
9659   let Inst{10} = size;
9660 }
9661 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
9662                       dag oops, dag iops, list<dag> pattern>
9663   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9664                            oops, iops, pattern> {
9665   // idx encoded in Q:S:size<1> fields.
9666   bits<3> idx;
9667   let Inst{30} = idx{2};
9668   let Inst{23} = 0;
9669   let Inst{20-16} = 0b00000;
9670   let Inst{12} = idx{1};
9671   let Inst{11} = idx{0};
9672   let Inst{10} = size;
9673 }
9674
9675 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
9676                           dag oops, dag iops>
9677   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9678                        "$Rn = $wback", oops, iops, []> {
9679   // idx encoded in Q:S:size<1> fields.
9680   bits<3> idx;
9681   bits<5> Xm;
9682   let Inst{30} = idx{2};
9683   let Inst{23} = 1;
9684   let Inst{20-16} = Xm;
9685   let Inst{12} = idx{1};
9686   let Inst{11} = idx{0};
9687   let Inst{10} = size;
9688 }
9689 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
9690                           dag oops, dag iops>
9691   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9692                            "$Rn = $wback", oops, iops, []> {
9693   // idx encoded in Q:S:size<1> fields.
9694   bits<3> idx;
9695   bits<5> Xm;
9696   let Inst{30} = idx{2};
9697   let Inst{23} = 1;
9698   let Inst{20-16} = Xm;
9699   let Inst{12} = idx{1};
9700   let Inst{11} = idx{0};
9701   let Inst{10} = size;
9702 }
9703 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9704                       dag oops, dag iops, list<dag> pattern>
9705   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9706                        pattern> {
9707   // idx encoded in Q:S fields.
9708   bits<2> idx;
9709   let Inst{30} = idx{1};
9710   let Inst{23} = 0;
9711   let Inst{20-16} = 0b00000;
9712   let Inst{12} = idx{0};
9713   let Inst{11-10} = size;
9714 }
9715 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9716                       dag oops, dag iops, list<dag> pattern>
9717   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9718                            oops, iops, pattern> {
9719   // idx encoded in Q:S fields.
9720   bits<2> idx;
9721   let Inst{30} = idx{1};
9722   let Inst{23} = 0;
9723   let Inst{20-16} = 0b00000;
9724   let Inst{12} = idx{0};
9725   let Inst{11-10} = size;
9726 }
9727 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
9728                           string asm, dag oops, dag iops>
9729   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9730                        "$Rn = $wback", oops, iops, []> {
9731   // idx encoded in Q:S fields.
9732   bits<2> idx;
9733   bits<5> Xm;
9734   let Inst{30} = idx{1};
9735   let Inst{23} = 1;
9736   let Inst{20-16} = Xm;
9737   let Inst{12} = idx{0};
9738   let Inst{11-10} = size;
9739 }
9740 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9741                           string asm, dag oops, dag iops>
9742   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9743                            "$Rn = $wback", oops, iops, []> {
9744   // idx encoded in Q:S fields.
9745   bits<2> idx;
9746   bits<5> Xm;
9747   let Inst{30} = idx{1};
9748   let Inst{23} = 1;
9749   let Inst{20-16} = Xm;
9750   let Inst{12} = idx{0};
9751   let Inst{11-10} = size;
9752 }
9753 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9754                       dag oops, dag iops, list<dag> pattern>
9755   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9756                        pattern> {
9757   // idx encoded in Q field.
9758   bits<1> idx;
9759   let Inst{30} = idx;
9760   let Inst{23} = 0;
9761   let Inst{20-16} = 0b00000;
9762   let Inst{12} = 0;
9763   let Inst{11-10} = size;
9764 }
9765 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9766                       dag oops, dag iops, list<dag> pattern>
9767   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9768                            oops, iops, pattern> {
9769   // idx encoded in Q field.
9770   bits<1> idx;
9771   let Inst{30} = idx;
9772   let Inst{23} = 0;
9773   let Inst{20-16} = 0b00000;
9774   let Inst{12} = 0;
9775   let Inst{11-10} = size;
9776 }
9777 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
9778                           string asm, dag oops, dag iops>
9779   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9780                        "$Rn = $wback", oops, iops, []> {
9781   // idx encoded in Q field.
9782   bits<1> idx;
9783   bits<5> Xm;
9784   let Inst{30} = idx;
9785   let Inst{23} = 1;
9786   let Inst{20-16} = Xm;
9787   let Inst{12} = 0;
9788   let Inst{11-10} = size;
9789 }
9790 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9791                           string asm, dag oops, dag iops>
9792   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9793                            "$Rn = $wback", oops, iops, []> {
9794   // idx encoded in Q field.
9795   bits<1> idx;
9796   bits<5> Xm;
9797   let Inst{30} = idx;
9798   let Inst{23} = 1;
9799   let Inst{20-16} = Xm;
9800   let Inst{12} = 0;
9801   let Inst{11-10} = size;
9802 }
9803
9804 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9805 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
9806                          RegisterOperand listtype,
9807                          RegisterOperand GPR64pi> {
9808   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
9809                            (outs listtype:$dst),
9810                            (ins listtype:$Vt, VectorIndexB:$idx,
9811                                 GPR64sp:$Rn), []>;
9812
9813   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
9814                             (outs GPR64sp:$wback, listtype:$dst),
9815                             (ins listtype:$Vt, VectorIndexB:$idx,
9816                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9817 }
9818 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9819 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
9820                          RegisterOperand listtype,
9821                          RegisterOperand GPR64pi> {
9822   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
9823                             (outs listtype:$dst),
9824                             (ins listtype:$Vt, VectorIndexH:$idx,
9825                                  GPR64sp:$Rn), []>;
9826
9827   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
9828                             (outs GPR64sp:$wback, listtype:$dst),
9829                             (ins listtype:$Vt, VectorIndexH:$idx,
9830                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9831 }
9832 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9833 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
9834                          RegisterOperand listtype,
9835                          RegisterOperand GPR64pi> {
9836   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
9837                             (outs listtype:$dst),
9838                             (ins listtype:$Vt, VectorIndexS:$idx,
9839                                  GPR64sp:$Rn), []>;
9840
9841   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
9842                             (outs GPR64sp:$wback, listtype:$dst),
9843                             (ins listtype:$Vt, VectorIndexS:$idx,
9844                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9845 }
9846 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9847 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
9848                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9849   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
9850                             (outs listtype:$dst),
9851                             (ins listtype:$Vt, VectorIndexD:$idx,
9852                                  GPR64sp:$Rn), []>;
9853
9854   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
9855                             (outs GPR64sp:$wback, listtype:$dst),
9856                             (ins listtype:$Vt, VectorIndexD:$idx,
9857                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9858 }
9859 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9860 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
9861                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9862   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
9863                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
9864                                         GPR64sp:$Rn), []>;
9865
9866   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
9867                                     (outs GPR64sp:$wback),
9868                                     (ins listtype:$Vt, VectorIndexB:$idx,
9869                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
9870 }
9871 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9872 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
9873                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9874   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
9875                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
9876                                          GPR64sp:$Rn), []>;
9877
9878   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
9879                             (outs GPR64sp:$wback),
9880                             (ins listtype:$Vt, VectorIndexH:$idx,
9881                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9882 }
9883 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9884 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
9885                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9886   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
9887                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
9888                                          GPR64sp:$Rn), []>;
9889
9890   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
9891                             (outs GPR64sp:$wback),
9892                             (ins listtype:$Vt, VectorIndexS:$idx,
9893                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9894 }
9895 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9896 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
9897                          RegisterOperand listtype, RegisterOperand GPR64pi> {
9898   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
9899                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
9900                                          GPR64sp:$Rn), []>;
9901
9902   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
9903                             (outs GPR64sp:$wback),
9904                             (ins listtype:$Vt, VectorIndexD:$idx,
9905                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
9906 }
9907
9908 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
9909                                  string Count, int Offset, Operand idxtype> {
9910   // E.g. "ld1 { v0.8b }[0], [x1], #1"
9911   //      "ld1\t$Vt, [$Rn], #1"
9912   // may get mapped to
9913   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9914   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
9915                   (!cast<Instruction>(NAME # Type  # "_POST")
9916                       GPR64sp:$Rn,
9917                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9918                       idxtype:$idx, XZR), 1>;
9919
9920   // E.g. "ld1.8b { v0 }[0], [x1], #1"
9921   //      "ld1.8b\t$Vt, [$Rn], #1"
9922   // may get mapped to
9923   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9924   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9925                   (!cast<Instruction>(NAME # Type # "_POST")
9926                       GPR64sp:$Rn,
9927                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9928                       idxtype:$idx, XZR), 0>;
9929
9930   // E.g. "ld1.8b { v0 }[0], [x1]"
9931   //      "ld1.8b\t$Vt, [$Rn]"
9932   // may get mapped to
9933   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9934   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9935                       (!cast<Instruction>(NAME # Type)
9936                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9937                          idxtype:$idx, GPR64sp:$Rn), 0>;
9938
9939   // E.g. "ld1.8b { v0 }[0], [x1], x2"
9940   //      "ld1.8b\t$Vt, [$Rn], $Xm"
9941   // may get mapped to
9942   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9943   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9944                       (!cast<Instruction>(NAME # Type # "_POST")
9945                          GPR64sp:$Rn,
9946                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9947                          idxtype:$idx,
9948                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9949 }
9950
9951 multiclass SIMDLdSt1SingleAliases<string asm> {
9952   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
9953   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9954   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9955   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9956 }
9957
9958 multiclass SIMDLdSt2SingleAliases<string asm> {
9959   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
9960   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
9961   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
9962   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9963 }
9964
9965 multiclass SIMDLdSt3SingleAliases<string asm> {
9966   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
9967   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
9968   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9969   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9970 }
9971
9972 multiclass SIMDLdSt4SingleAliases<string asm> {
9973   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
9974   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
9975   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9976   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9977 }
9978 } // end of 'let Predicates = [HasNEON]'
9979
9980 //----------------------------------------------------------------------------
9981 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9982 //----------------------------------------------------------------------------
9983
9984 let Predicates = [HasNEON, HasRDM] in {
9985
9986 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9987                                     RegisterOperand regtype, string asm,
9988                                     string kind, list<dag> pattern>
9989   : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
9990                                 pattern> {
9991 }
9992 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9993                                              SDPatternOperator Accum> {
9994   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9995     [(set (v4i16 V64:$dst),
9996           (Accum (v4i16 V64:$Rd),
9997                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9998                                                    (v4i16 V64:$Rm)))))]>;
9999   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
10000     [(set (v8i16 V128:$dst),
10001           (Accum (v8i16 V128:$Rd),
10002                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
10003                                                    (v8i16 V128:$Rm)))))]>;
10004   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
10005     [(set (v2i32 V64:$dst),
10006           (Accum (v2i32 V64:$Rd),
10007                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
10008                                                    (v2i32 V64:$Rm)))))]>;
10009   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
10010     [(set (v4i32 V128:$dst),
10011           (Accum (v4i32 V128:$Rd),
10012                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
10013                                                    (v4i32 V128:$Rm)))))]>;
10014 }
10015
10016 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
10017                                      SDPatternOperator Accum> {
10018   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
10019                                           V64, V64, V128_lo, VectorIndexH,
10020                                           asm, ".4h", ".4h", ".4h", ".h",
10021     [(set (v4i16 V64:$dst),
10022           (Accum (v4i16 V64:$Rd),
10023                  (v4i16 (int_aarch64_neon_sqrdmulh
10024                           (v4i16 V64:$Rn),
10025                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10026                                                     VectorIndexH:$idx))))))]> {
10027     bits<3> idx;
10028     let Inst{11} = idx{2};
10029     let Inst{21} = idx{1};
10030     let Inst{20} = idx{0};
10031   }
10032
10033   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
10034                                           V128, V128, V128_lo, VectorIndexH,
10035                                           asm, ".8h", ".8h", ".8h", ".h",
10036     [(set (v8i16 V128:$dst),
10037           (Accum (v8i16 V128:$Rd),
10038                  (v8i16 (int_aarch64_neon_sqrdmulh
10039                           (v8i16 V128:$Rn),
10040                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10041                                                    VectorIndexH:$idx))))))]> {
10042     bits<3> idx;
10043     let Inst{11} = idx{2};
10044     let Inst{21} = idx{1};
10045     let Inst{20} = idx{0};
10046   }
10047
10048   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
10049                                           V64, V64, V128, VectorIndexS,
10050                                           asm, ".2s", ".2s", ".2s", ".s",
10051     [(set (v2i32 V64:$dst),
10052         (Accum (v2i32 V64:$Rd),
10053                (v2i32 (int_aarch64_neon_sqrdmulh
10054                         (v2i32 V64:$Rn),
10055                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
10056                                                  VectorIndexS:$idx))))))]> {
10057     bits<2> idx;
10058     let Inst{11} = idx{1};
10059     let Inst{21} = idx{0};
10060   }
10061
10062   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10063   // an intermediate EXTRACT_SUBREG would be untyped.
10064   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
10065   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
10066   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10067                        (i32 (vector_extract
10068                                (v4i32 (insert_subvector
10069                                        (undef),
10070                                         (v2i32 (int_aarch64_neon_sqrdmulh
10071                                                  (v2i32 V64:$Rn),
10072                                                  (v2i32 (AArch64duplane32
10073                                                           (v4i32 V128:$Rm),
10074                                                           VectorIndexS:$idx)))),
10075                                       (i32 0))),
10076                                (i64 0))))),
10077             (EXTRACT_SUBREG
10078                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
10079                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
10080                                                 FPR32Op:$Rd,
10081                                                 ssub)),
10082                           V64:$Rn,
10083                           V128:$Rm,
10084                           VectorIndexS:$idx)),
10085                 ssub)>;
10086
10087   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
10088                                           V128, V128, V128, VectorIndexS,
10089                                           asm, ".4s", ".4s", ".4s", ".s",
10090     [(set (v4i32 V128:$dst),
10091           (Accum (v4i32 V128:$Rd),
10092                  (v4i32 (int_aarch64_neon_sqrdmulh
10093                           (v4i32 V128:$Rn),
10094                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
10095                                                    VectorIndexS:$idx))))))]> {
10096     bits<2> idx;
10097     let Inst{11} = idx{1};
10098     let Inst{21} = idx{0};
10099   }
10100
10101   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10102   // an intermediate EXTRACT_SUBREG would be untyped.
10103   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10104                         (i32 (vector_extract
10105                                (v4i32 (int_aarch64_neon_sqrdmulh
10106                                         (v4i32 V128:$Rn),
10107                                         (v4i32 (AArch64duplane32
10108                                                  (v4i32 V128:$Rm),
10109                                                  VectorIndexS:$idx)))),
10110                                (i64 0))))),
10111             (EXTRACT_SUBREG
10112                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
10113                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
10114                                                FPR32Op:$Rd,
10115                                                ssub)),
10116                          V128:$Rn,
10117                          V128:$Rm,
10118                          VectorIndexS:$idx)),
10119                 ssub)>;
10120
10121   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
10122                                         FPR16Op, FPR16Op, V128_lo,
10123                                         VectorIndexH, asm, ".h", "", "", ".h",
10124                                         []> {
10125     bits<3> idx;
10126     let Inst{11} = idx{2};
10127     let Inst{21} = idx{1};
10128     let Inst{20} = idx{0};
10129   }
10130
10131   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
10132                                         FPR32Op, FPR32Op, V128, VectorIndexS,
10133                                         asm, ".s", "", "", ".s",
10134     [(set (i32 FPR32Op:$dst),
10135           (Accum (i32 FPR32Op:$Rd),
10136                  (i32 (int_aarch64_neon_sqrdmulh
10137                         (i32 FPR32Op:$Rn),
10138                         (i32 (vector_extract (v4i32 V128:$Rm),
10139                                              VectorIndexS:$idx))))))]> {
10140     bits<2> idx;
10141     let Inst{11} = idx{1};
10142     let Inst{21} = idx{0};
10143   }
10144 }
10145 } // let Predicates = [HasNeon, HasRDM]
10146
10147 //----------------------------------------------------------------------------
10148 // ARMv8.3 Complex ADD/MLA instructions
10149 //----------------------------------------------------------------------------
10150
10151 class ComplexRotationOperand<int Angle, int Remainder, string Type>
10152   : AsmOperandClass {
10153   let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
10154   let DiagnosticType = "InvalidComplexRotation" # Type;
10155   let Name = "ComplexRotation" # Type;
10156 }
10157 def complexrotateop : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270;  }],
10158                                                  SDNodeXForm<imm, [{
10159   return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32);
10160 }]>> {
10161   let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
10162   let PrintMethod = "printComplexRotationOp<90, 0>";
10163 }
10164 def complexrotateopodd : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270;  }],
10165                                                  SDNodeXForm<imm, [{
10166   return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32);
10167 }]>> {
10168   let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
10169   let PrintMethod = "printComplexRotationOp<180, 90>";
10170 }
10171 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10172 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
10173                                      RegisterOperand regtype, Operand rottype,
10174                                      string asm, string kind, list<dag> pattern>
10175   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10176       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10177       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
10178     Sched<[WriteV]> {
10179   bits<5> Rd;
10180   bits<5> Rn;
10181   bits<5> Rm;
10182   bits<1> rot;
10183   let Inst{31}    = 0;
10184   let Inst{30}    = Q;
10185   let Inst{29}    = U;
10186   let Inst{28-24} = 0b01110;
10187   let Inst{23-22} = size;
10188   let Inst{21}    = 0;
10189   let Inst{20-16} = Rm;
10190   let Inst{15-13} = opcode;
10191   // Non-tied version (FCADD) only has one rotation bit
10192   let Inst{12}    = rot;
10193   let Inst{11}    = 0;
10194   let Inst{10}    = 1;
10195   let Inst{9-5}   = Rn;
10196   let Inst{4-0}   = Rd;
10197 }
10198
10199 //8.3 CompNum - Floating-point complex number support
10200 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
10201                                           string asm, SDPatternOperator OpNode>{
10202   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10203   def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
10204               asm, ".4h",
10205               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10206                                               (v4f16 V64:$Rn),
10207                                               (v4f16 V64:$Rm),
10208                                               (rottype i32:$rot)))]>;
10209
10210   def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
10211               asm, ".8h",
10212               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10213                                                (v8f16 V128:$Rn),
10214                                                (v8f16 V128:$Rm),
10215                                                (rottype i32:$rot)))]>;
10216   }
10217
10218   let Predicates = [HasComplxNum, HasNEON] in {
10219   def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
10220               asm, ".2s",
10221               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10222                                               (v2f32 V64:$Rn),
10223                                               (v2f32 V64:$Rm),
10224                                               (rottype i32:$rot)))]>;
10225
10226   def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
10227               asm, ".4s",
10228               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10229                                                (v4f32 V128:$Rn),
10230                                                (v4f32 V128:$Rm),
10231                                                (rottype i32:$rot)))]>;
10232
10233   def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
10234               asm, ".2d",
10235               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10236                                                (v2f64 V128:$Rn),
10237                                                (v2f64 V128:$Rm),
10238                                                (rottype i32:$rot)))]>;
10239   }
10240 }
10241
10242 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10243 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
10244                                          bits<3> opcode,
10245                                          RegisterOperand regtype,
10246                                          Operand rottype, string asm,
10247                                          string kind, list<dag> pattern>
10248   : I<(outs regtype:$dst),
10249       (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10250       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10251       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
10252     Sched<[WriteV]> {
10253   bits<5> Rd;
10254   bits<5> Rn;
10255   bits<5> Rm;
10256   bits<2> rot;
10257   let Inst{31}    = 0;
10258   let Inst{30}    = Q;
10259   let Inst{29}    = U;
10260   let Inst{28-24} = 0b01110;
10261   let Inst{23-22} = size;
10262   let Inst{21}    = 0;
10263   let Inst{20-16} = Rm;
10264   let Inst{15-13} = opcode;
10265   let Inst{12-11} = rot;
10266   let Inst{10}    = 1;
10267   let Inst{9-5}   = Rn;
10268   let Inst{4-0}   = Rd;
10269 }
10270
10271 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
10272                                              Operand rottype, string asm,
10273                                              SDPatternOperator OpNode> {
10274   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10275   def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
10276               rottype, asm, ".4h",
10277               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10278                                               (v4f16 V64:$Rn),
10279                                               (v4f16 V64:$Rm),
10280                                               (rottype i32:$rot)))]>;
10281
10282   def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
10283               rottype, asm, ".8h",
10284               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10285                                                (v8f16 V128:$Rn),
10286                                                (v8f16 V128:$Rm),
10287                                                (rottype i32:$rot)))]>;
10288   }
10289
10290   let Predicates = [HasComplxNum, HasNEON] in {
10291   def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
10292               rottype, asm, ".2s",
10293               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10294                                               (v2f32 V64:$Rn),
10295                                               (v2f32 V64:$Rm),
10296                                               (rottype i32:$rot)))]>;
10297
10298   def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
10299               rottype, asm, ".4s",
10300               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10301                                                (v4f32 V128:$Rn),
10302                                                (v4f32 V128:$Rm),
10303                                                (rottype i32:$rot)))]>;
10304
10305   def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
10306               rottype, asm, ".2d",
10307               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10308                                                (v2f64 V128:$Rn),
10309                                                (v2f64 V128:$Rm),
10310                                                (rottype i32:$rot)))]>;
10311   }
10312 }
10313
10314 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10315 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
10316                                  bit opc1, bit opc2, RegisterOperand dst_reg,
10317                                  RegisterOperand lhs_reg,
10318                                  RegisterOperand rhs_reg, Operand vec_idx,
10319                                  Operand rottype, string asm, string apple_kind,
10320                                  string dst_kind, string lhs_kind,
10321                                  string rhs_kind, list<dag> pattern>
10322   : I<(outs dst_reg:$dst),
10323       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
10324       asm,
10325       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
10326       "$idx, $rot" # "|" # apple_kind #
10327       "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
10328     Sched<[WriteV]> {
10329   bits<5> Rd;
10330   bits<5> Rn;
10331   bits<5> Rm;
10332   bits<2> rot;
10333
10334   let Inst{31}    = 0;
10335   let Inst{30}    = Q;
10336   let Inst{29}    = U;
10337   let Inst{28}    = Scalar;
10338   let Inst{27-24} = 0b1111;
10339   let Inst{23-22} = size;
10340   // Bit 21 must be set by the derived class.
10341   let Inst{20-16} = Rm;
10342   let Inst{15}    = opc1;
10343   let Inst{14-13} = rot;
10344   let Inst{12}    = opc2;
10345   // Bit 11 must be set by the derived class.
10346   let Inst{10}    = 0;
10347   let Inst{9-5}   = Rn;
10348   let Inst{4-0}   = Rd;
10349 }
10350
10351 // The complex instructions index by pairs of elements, so the VectorIndexes
10352 // don't match the lane types, and the index bits are different to the other
10353 // classes.
10354 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
10355                                      string asm, SDPatternOperator OpNode> {
10356   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10357   def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
10358                       V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
10359                       ".4h", ".h", []> {
10360     bits<1> idx;
10361     let Inst{11} = 0;
10362     let Inst{21} = idx{0};
10363   }
10364
10365   def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
10366                       V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
10367                       ".8h", ".8h", ".h", []> {
10368     bits<2> idx;
10369     let Inst{11} = idx{1};
10370     let Inst{21} = idx{0};
10371   }
10372   } // Predicates = HasComplxNum, HasNEON, HasFullFP16]
10373
10374   let Predicates = [HasComplxNum, HasNEON] in {
10375   def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
10376                       V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
10377                       ".4s", ".4s", ".s", []> {
10378     bits<1> idx;
10379     let Inst{11} = idx{0};
10380     let Inst{21} = 0;
10381   }
10382   } // Predicates = [HasComplxNum, HasNEON]
10383 }
10384
10385 //----------------------------------------------------------------------------
10386 // Crypto extensions
10387 //----------------------------------------------------------------------------
10388
10389 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10390 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
10391               list<dag> pat>
10392   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
10393     Sched<[WriteV]>{
10394   bits<5> Rd;
10395   bits<5> Rn;
10396   let Inst{31-16} = 0b0100111000101000;
10397   let Inst{15-12} = opc;
10398   let Inst{11-10} = 0b10;
10399   let Inst{9-5}   = Rn;
10400   let Inst{4-0}   = Rd;
10401 }
10402
10403 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
10404   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
10405             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
10406
10407 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
10408   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
10409             "$Rd = $dst",
10410             [(set (v16i8 V128:$dst),
10411                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
10412
10413 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10414 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
10415                      dag oops, dag iops, list<dag> pat>
10416   : I<oops, iops, asm,
10417       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
10418       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
10419     Sched<[WriteV]>{
10420   bits<5> Rd;
10421   bits<5> Rn;
10422   bits<5> Rm;
10423   let Inst{31-21} = 0b01011110000;
10424   let Inst{20-16} = Rm;
10425   let Inst{15}    = 0;
10426   let Inst{14-12} = opc;
10427   let Inst{11-10} = 0b00;
10428   let Inst{9-5}   = Rn;
10429   let Inst{4-0}   = Rd;
10430 }
10431
10432 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
10433   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10434                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
10435                    [(set (v4i32 FPR128:$dst),
10436                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
10437                                  (v4i32 V128:$Rm)))]>;
10438
10439 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
10440   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
10441                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
10442                    [(set (v4i32 V128:$dst),
10443                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
10444                                  (v4i32 V128:$Rm)))]>;
10445
10446 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
10447   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10448                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
10449                    [(set (v4i32 FPR128:$dst),
10450                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
10451                                  (v4i32 V128:$Rm)))]>;
10452
10453 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10454 class SHA2OpInst<bits<4> opc, string asm, string kind,
10455                  string cstr, dag oops, dag iops,
10456                  list<dag> pat>
10457   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
10458                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
10459     Sched<[WriteV]>{
10460   bits<5> Rd;
10461   bits<5> Rn;
10462   let Inst{31-16} = 0b0101111000101000;
10463   let Inst{15-12} = opc;
10464   let Inst{11-10} = 0b10;
10465   let Inst{9-5}   = Rn;
10466   let Inst{4-0}   = Rd;
10467 }
10468
10469 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
10470   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
10471                (ins V128:$Rd, V128:$Rn),
10472                [(set (v4i32 V128:$dst),
10473                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
10474
10475 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
10476   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
10477                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
10478
10479 // Armv8.2-A Crypto extensions
10480 class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
10481                     list<dag> pattern>
10482   : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> {
10483   bits<5> Vd;
10484   bits<5> Vn;
10485   let Inst{31-25} = 0b1100111;
10486   let Inst{9-5}   = Vn;
10487   let Inst{4-0}   = Vd;
10488 }
10489
10490 class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
10491   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops,
10492                   "$Vm = $Vd", []> {
10493   let Inst{31-25} = 0b1100111;
10494   let Inst{24-21} = 0b0110;
10495   let Inst{20-15} = 0b000001;
10496   let Inst{14}    = op0;
10497   let Inst{13-12} = 0b00;
10498   let Inst{11-10} = op1;
10499 }
10500 class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
10501   : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">;
10502 class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
10503   : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">;
10504
10505 class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
10506                 string asmops, string cst>
10507   : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
10508   bits<5> Vm;
10509   let Inst{24-21} = 0b0011;
10510   let Inst{20-16} = Vm;
10511   let Inst{15}    = 0b1;
10512   let Inst{14}    = op0;
10513   let Inst{13-12} = 0b00;
10514   let Inst{11-10} = op1;
10515 }
10516 class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
10517   : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10518               "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">;
10519 class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
10520   : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10521               "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10522 class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
10523   : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10524               "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">;
10525 class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
10526   : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10527               "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10528 class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
10529   : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
10530               asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10531
10532 class CryptoRRRR<bits<2>op0, string asm, string asmops>
10533   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
10534                   asmops, "", []> {
10535   bits<5> Vm;
10536   bits<5> Va;
10537   let Inst{24-23} = 0b00;
10538   let Inst{22-21} = op0;
10539   let Inst{20-16} = Vm;
10540   let Inst{15}    = 0b0;
10541   let Inst{14-10} = Va;
10542 }
10543 class CryptoRRRR_16B<bits<2>op0, string asm>
10544  : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" #
10545                         "|.16b\t$Vd, $Vn, $Vm, $Va}"> {
10546 }
10547 class CryptoRRRR_4S<bits<2>op0, string asm>
10548  : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" #
10549                          "|.4s\t$Vd, $Vn, $Vm, $Va}"> {
10550 }
10551
10552 class CryptoRRRi6<string asm>
10553   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
10554                   "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" #
10555                   "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> {
10556   bits<6> imm;
10557   bits<5> Vm;
10558   let Inst{24-21} = 0b0100;
10559   let Inst{20-16} = Vm;
10560   let Inst{15-10} = imm;
10561   let Inst{9-5}   = Vn;
10562   let Inst{4-0}   = Vd;
10563 }
10564
10565 class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
10566   : BaseCryptoV82<(outs V128:$Vdst),
10567                   (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
10568                   asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" #
10569                        "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> {
10570   bits<2> imm;
10571   bits<5> Vm;
10572   let Inst{24-21} = 0b0010;
10573   let Inst{20-16} = Vm;
10574   let Inst{15}    = 0b1;
10575   let Inst{14}    = op0;
10576   let Inst{13-12} = imm;
10577   let Inst{11-10} = op1;
10578 }
10579
10580 //----------------------------------------------------------------------------
10581 // v8.1 atomic instructions extension:
10582 // * CAS
10583 // * CASP
10584 // * SWP
10585 // * LDOPregister<OP>, and aliases STOPregister<OP>
10586
10587 // Instruction encodings:
10588 //
10589 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
10590 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
10591 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
10592 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
10593 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
10594 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
10595
10596 // Instruction syntax:
10597 //
10598 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10599 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
10600 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
10601 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
10602 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10603 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
10604 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10605 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
10606 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
10607 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
10608
10609 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10610 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
10611                       string cstr, list<dag> pattern>
10612       : I<oops, iops, asm, operands, cstr, pattern> {
10613   bits<2> Sz;
10614   bit NP;
10615   bit Acq;
10616   bit Rel;
10617   bits<5> Rs;
10618   bits<5> Rn;
10619   bits<5> Rt;
10620   let Inst{31-30} = Sz;
10621   let Inst{29-24} = 0b001000;
10622   let Inst{23} = NP;
10623   let Inst{22} = Acq;
10624   let Inst{21} = 0b1;
10625   let Inst{20-16} = Rs;
10626   let Inst{15} = Rel;
10627   let Inst{14-10} = 0b11111;
10628   let Inst{9-5} = Rn;
10629   let Inst{4-0} = Rt;
10630   let Predicates = [HasLSE];
10631 }
10632
10633 class BaseCAS<string order, string size, RegisterClass RC>
10634       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
10635                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
10636                         "$out = $Rs",[]>,
10637         Sched<[WriteAtomic]> {
10638   let NP = 1;
10639 }
10640
10641 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
10642   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
10643   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
10644   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
10645   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
10646 }
10647
10648 class BaseCASP<string order, string size, RegisterOperand RC>
10649       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
10650                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
10651                         "$out = $Rs",[]>,
10652         Sched<[WriteAtomic]> {
10653   let NP = 0;
10654 }
10655
10656 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
10657   let Sz = 0b00, Acq = Acq, Rel = Rel in
10658     def W : BaseCASP<order, "", WSeqPairClassOperand>;
10659   let Sz = 0b01, Acq = Acq, Rel = Rel in
10660     def X : BaseCASP<order, "", XSeqPairClassOperand>;
10661 }
10662
10663 let Predicates = [HasLSE] in
10664 class BaseSWP<string order, string size, RegisterClass RC>
10665       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
10666           "\t$Rs, $Rt, [$Rn]","",[]>,
10667         Sched<[WriteAtomic]> {
10668   bits<2> Sz;
10669   bit Acq;
10670   bit Rel;
10671   bits<5> Rs;
10672   bits<3> opc = 0b000;
10673   bits<5> Rn;
10674   bits<5> Rt;
10675   let Inst{31-30} = Sz;
10676   let Inst{29-24} = 0b111000;
10677   let Inst{23} = Acq;
10678   let Inst{22} = Rel;
10679   let Inst{21} = 0b1;
10680   let Inst{20-16} = Rs;
10681   let Inst{15} = 0b1;
10682   let Inst{14-12} = opc;
10683   let Inst{11-10} = 0b00;
10684   let Inst{9-5} = Rn;
10685   let Inst{4-0} = Rt;
10686   let Predicates = [HasLSE];
10687 }
10688
10689 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
10690   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
10691   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
10692   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
10693   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
10694 }
10695
10696 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10697 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
10698       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
10699           "\t$Rs, $Rt, [$Rn]","",[]>,
10700         Sched<[WriteAtomic]> {
10701   bits<2> Sz;
10702   bit Acq;
10703   bit Rel;
10704   bits<5> Rs;
10705   bits<3> opc;
10706   bits<5> Rn;
10707   bits<5> Rt;
10708   let Inst{31-30} = Sz;
10709   let Inst{29-24} = 0b111000;
10710   let Inst{23} = Acq;
10711   let Inst{22} = Rel;
10712   let Inst{21} = 0b1;
10713   let Inst{20-16} = Rs;
10714   let Inst{15} = 0b0;
10715   let Inst{14-12} = opc;
10716   let Inst{11-10} = 0b00;
10717   let Inst{9-5} = Rn;
10718   let Inst{4-0} = Rt;
10719   let Predicates = [HasLSE];
10720 }
10721
10722 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
10723                         string order> {
10724   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
10725     def B : BaseLDOPregister<op, order, "b", GPR32>;
10726   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
10727     def H : BaseLDOPregister<op, order, "h", GPR32>;
10728   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
10729     def W : BaseLDOPregister<op, order, "", GPR32>;
10730   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
10731     def X : BaseLDOPregister<op, order, "", GPR64>;
10732 }
10733
10734 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
10735 // complex DAG for DstRHS.
10736 let Predicates = [HasLSE] in
10737 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
10738                                          string size, dag SrcRHS, dag DstRHS> {
10739   def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
10740             (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
10741   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
10742             (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
10743   def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
10744             (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
10745   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
10746             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
10747   def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
10748             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
10749 }
10750
10751 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
10752                                      string size, dag RHS> {
10753   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
10754 }
10755
10756 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
10757                                          string size, dag LHS, dag RHS> {
10758   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
10759 }
10760
10761 multiclass LDOPregister_patterns<string inst, string op> {
10762   defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
10763   defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
10764   defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
10765   defm : LDOPregister_patterns_ord<inst, "B", op, "8",  (i32 GPR32:$Rm)>;
10766 }
10767
10768 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
10769   defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
10770                         (i64 GPR64:$Rm),
10771                         (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
10772   defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
10773                         (i32 GPR32:$Rm),
10774                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10775   defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
10776                         (i32 GPR32:$Rm),
10777                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10778   defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
10779                         (i32 GPR32:$Rm),
10780                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10781 }
10782
10783 let Predicates = [HasLSE] in
10784 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
10785                                         string size, dag OLD, dag NEW> {
10786   def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
10787             (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
10788   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
10789             (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10790   def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
10791             (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10792   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
10793             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10794   def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
10795             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10796 }
10797
10798 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
10799                                     string size, dag OLD, dag NEW> {
10800   defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
10801 }
10802
10803 multiclass CASregister_patterns<string inst, string op> {
10804   defm : CASregister_patterns_ord<inst, "X", op, "64",
10805                         (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
10806   defm : CASregister_patterns_ord<inst, "W", op, "32",
10807                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10808   defm : CASregister_patterns_ord<inst, "H", op, "16",
10809                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10810   defm : CASregister_patterns_ord<inst, "B", op, "8",
10811                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10812 }
10813
10814 let Predicates = [HasLSE] in
10815 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
10816                         Instruction inst> :
10817       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
10818
10819 multiclass STOPregister<string asm, string instr> {
10820   def : BaseSTOPregister<asm # "lb", GPR32, WZR,
10821                     !cast<Instruction>(instr # "LB")>;
10822   def : BaseSTOPregister<asm # "lh", GPR32, WZR,
10823                     !cast<Instruction>(instr # "LH")>;
10824   def : BaseSTOPregister<asm # "l",  GPR32, WZR,
10825                     !cast<Instruction>(instr # "LW")>;
10826   def : BaseSTOPregister<asm # "l",  GPR64, XZR,
10827                     !cast<Instruction>(instr # "LX")>;
10828   def : BaseSTOPregister<asm # "b",  GPR32, WZR,
10829                     !cast<Instruction>(instr # "B")>;
10830   def : BaseSTOPregister<asm # "h",  GPR32, WZR,
10831                     !cast<Instruction>(instr # "H")>;
10832   def : BaseSTOPregister<asm,        GPR32, WZR,
10833                     !cast<Instruction>(instr # "W")>;
10834   def : BaseSTOPregister<asm,        GPR64, XZR,
10835                     !cast<Instruction>(instr # "X")>;
10836 }
10837
10838 //----------------------------------------------------------------------------
10839 // Allow the size specifier tokens to be upper case, not just lower.
10840 def : TokenAlias<".4B", ".4b">;  // Add dot product
10841 def : TokenAlias<".8B", ".8b">;
10842 def : TokenAlias<".4H", ".4h">;
10843 def : TokenAlias<".2S", ".2s">;
10844 def : TokenAlias<".1D", ".1d">;
10845 def : TokenAlias<".16B", ".16b">;
10846 def : TokenAlias<".8H", ".8h">;
10847 def : TokenAlias<".4S", ".4s">;
10848 def : TokenAlias<".2D", ".2d">;
10849 def : TokenAlias<".1Q", ".1q">;
10850 def : TokenAlias<".2H", ".2h">;
10851 def : TokenAlias<".B", ".b">;
10852 def : TokenAlias<".H", ".h">;
10853 def : TokenAlias<".S", ".s">;
10854 def : TokenAlias<".D", ".d">;
10855 def : TokenAlias<".Q", ".q">;