[SampleProfileLoader] Fix integer overflow in generateMDProfMetadata (#90217)
[llvm-project.git] / llvm / lib / Target / AArch64 / AArch64InstrFormats.td
blob1f437d0ed6f8d75b9a4162bc75a83e479cadef9c
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 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
10 //  Describe AArch64 instructions format here
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;
20 def PseudoFrm   : Format<0>;
21 def NormalFrm   : Format<1>; // Do we need any others?
23 // Enum describing whether an instruction is
24 // destructive in its first source operand.
25 class DestructiveInstTypeEnum<bits<4> val> {
26   bits<4> Value = val;
28 def NotDestructive                : DestructiveInstTypeEnum<0>;
29 // Destructive in its first operand and can be MOVPRFX'd, but has no other
30 // special properties.
31 def DestructiveOther              : DestructiveInstTypeEnum<1>;
32 def DestructiveUnary              : DestructiveInstTypeEnum<2>;
33 def DestructiveBinaryImm          : DestructiveInstTypeEnum<3>;
34 def DestructiveBinaryShImmUnpred  : DestructiveInstTypeEnum<4>;
35 def DestructiveBinary             : DestructiveInstTypeEnum<5>;
36 def DestructiveBinaryComm         : DestructiveInstTypeEnum<6>;
37 def DestructiveBinaryCommWithRev  : DestructiveInstTypeEnum<7>;
38 def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>;
39 def DestructiveUnaryPassthru      : DestructiveInstTypeEnum<9>;
41 class FalseLanesEnum<bits<2> val> {
42   bits<2> Value = val;
44 def FalseLanesNone  : FalseLanesEnum<0>;
45 def FalseLanesZero  : FalseLanesEnum<1>;
46 def FalseLanesUndef : FalseLanesEnum<2>;
48 class SMEMatrixTypeEnum<bits<3> val> {
49   bits<3> Value = val;
51 def SMEMatrixNone  : SMEMatrixTypeEnum<0>;
52 def SMEMatrixTileB : SMEMatrixTypeEnum<1>;
53 def SMEMatrixTileH : SMEMatrixTypeEnum<2>;
54 def SMEMatrixTileS : SMEMatrixTypeEnum<3>;
55 def SMEMatrixTileD : SMEMatrixTypeEnum<4>;
56 def SMEMatrixTileQ : SMEMatrixTypeEnum<5>;
57 def SMEMatrixArray : SMEMatrixTypeEnum<6>;
59 // AArch64 Instruction Format
60 class AArch64Inst<Format f, string cstr> : Instruction {
61   field bits<32> Inst; // Instruction encoding.
62   // Mask of bits that cause an encoding to be UNPREDICTABLE.
63   // If a bit is set, then if the corresponding bit in the
64   // target encoding differs from its value in the "Inst" field,
65   // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
66   field bits<32> Unpredictable = 0;
67   // SoftFail is the generic name for this field, but we alias it so
68   // as to make it more obvious what it means in ARM-land.
69   field bits<32> SoftFail = Unpredictable;
70   let Namespace   = "AArch64";
71   Format F        = f;
72   bits<2> Form    = F.Value;
74   // Defaults
75   bit isWhile = 0;
76   bit isPTestLike = 0;
77   FalseLanesEnum FalseLanes = FalseLanesNone;
78   DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
79   SMEMatrixTypeEnum SMEMatrixType = SMEMatrixNone;
80   ElementSizeEnum ElementSize = ElementSizeNone;
82   let TSFlags{13-11} = SMEMatrixType.Value;
83   let TSFlags{10}    = isPTestLike;
84   let TSFlags{9}     = isWhile;
85   let TSFlags{8-7}   = FalseLanes.Value;
86   let TSFlags{6-3}   = DestructiveInstType.Value;
87   let TSFlags{2-0}   = ElementSize.Value;
89   let Pattern       = [];
90   let Constraints   = cstr;
93 class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
94   : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
96 // Pseudo instructions (don't have encoding information)
97 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
98     : AArch64Inst<PseudoFrm, cstr> {
99   dag OutOperandList = oops;
100   dag InOperandList  = iops;
101   let Pattern        = pattern;
102   let isCodeGenOnly  = 1;
103   let isPseudo       = 1;
106 // Real instructions (have encoding information)
107 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
108   let Pattern = pattern;
109   let Size = 4;
112 // Normal instructions
113 class I<dag oops, dag iops, string asm, string operands, string cstr,
114         list<dag> pattern>
115     : EncodedI<cstr, pattern> {
116   dag OutOperandList = oops;
117   dag InOperandList  = iops;
118   let AsmString      = !strconcat(asm, operands);
121 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
122 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
123 class UnOpFrag<dag res>  : PatFrag<(ops node:$LHS), res>;
125 // Helper fragment for an extract of the high portion of a 128-bit vector. The
126 // ComplexPattern match both extract_subvector and bitcast(extract_subvector(..)).
127 def extract_high_v16i8 :
128     ComplexPattern<v8i8, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;
129 def extract_high_v8i16 :
130     ComplexPattern<v4i16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;
131 def extract_high_v4i32 :
132     ComplexPattern<v2i32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;
133 def extract_high_v2i64 :
134     ComplexPattern<v1i64, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;
136 def gi_extract_high_v16i8 :
137   GIComplexOperandMatcher<v8s8, "selectExtractHigh">,
138   GIComplexPatternEquiv<extract_high_v16i8>;
139 def gi_extract_high_v8i16 :
140   GIComplexOperandMatcher<v4s16, "selectExtractHigh">,
141   GIComplexPatternEquiv<extract_high_v8i16>;
142 def gi_extract_high_v4i32 :
143   GIComplexOperandMatcher<v2s32, "selectExtractHigh">,
144   GIComplexPatternEquiv<extract_high_v4i32>;
146 def extract_high_v8f16 :
147     ComplexPattern<v4f16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;
148 def extract_high_v4f32 :
149     ComplexPattern<v2f32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;
151 def gi_extract_high_v8f16 :
152   GIComplexOperandMatcher<v4s16, "selectExtractHigh">,
153   GIComplexPatternEquiv<extract_high_v8f16>;
154 def gi_extract_high_v4f32 :
155   GIComplexOperandMatcher<v2s32, "selectExtractHigh">,
156   GIComplexPatternEquiv<extract_high_v4f32>;
158 def extract_high_dup_v8i16 :
159    BinOpFrag<(extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 4))>;
160 def extract_high_dup_v4i32 :
161    BinOpFrag<(extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 2))>;
163 def dup_v8i16 :
164     PatFrags<(ops node:$LHS, node:$RHS),
165              [(v4i16 (extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 0))),
166               (v4i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS))]>;
167 def dup_v4i32 :
168     PatFrags<(ops node:$LHS, node:$RHS),
169              [(v2i32 (extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 0))),
170               (v2i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS))]>;
171 def dup_v8f16 :
172     PatFrags<(ops node:$LHS, node:$RHS),
173              [(v4f16 (extract_subvector (v8f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS)), (i64 0))),
174               (v4f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS))]>;
175 def dup_v4f32 :
176     PatFrags<(ops node:$LHS, node:$RHS),
177              [(v2f32 (extract_subvector (v4f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS)), (i64 0))),
178               (v2f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS))]>;
180 //===----------------------------------------------------------------------===//
181 // Asm Operand Classes.
184 // Shifter operand for arithmetic shifted encodings.
185 def ShifterOperand : AsmOperandClass {
186   let Name = "Shifter";
189 // Shifter operand for mov immediate encodings.
190 def MovImm32ShifterOperand : AsmOperandClass {
191   let SuperClasses = [ShifterOperand];
192   let Name = "MovImm32Shifter";
193   let RenderMethod = "addShifterOperands";
194   let DiagnosticType = "InvalidMovImm32Shift";
196 def MovImm64ShifterOperand : AsmOperandClass {
197   let SuperClasses = [ShifterOperand];
198   let Name = "MovImm64Shifter";
199   let RenderMethod = "addShifterOperands";
200   let DiagnosticType = "InvalidMovImm64Shift";
203 // Shifter operand for arithmetic register shifted encodings.
204 class ArithmeticShifterOperand<int width> : AsmOperandClass {
205   let SuperClasses = [ShifterOperand];
206   let Name = "ArithmeticShifter" # width;
207   let PredicateMethod = "isArithmeticShifter<" # width # ">";
208   let RenderMethod = "addShifterOperands";
209   let DiagnosticType = "AddSubRegShift" # width;
212 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
213 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
215 // Shifter operand for logical register shifted encodings.
216 class LogicalShifterOperand<int width> : AsmOperandClass {
217   let SuperClasses = [ShifterOperand];
218   let Name = "LogicalShifter" # width;
219   let PredicateMethod = "isLogicalShifter<" # width # ">";
220   let RenderMethod = "addShifterOperands";
221   let DiagnosticType = "AddSubRegShift" # width;
224 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
225 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
227 // Shifter operand for logical vector 128/64-bit shifted encodings.
228 def LogicalVecShifterOperand : AsmOperandClass {
229   let SuperClasses = [ShifterOperand];
230   let Name = "LogicalVecShifter";
231   let RenderMethod = "addShifterOperands";
233 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
234   let SuperClasses = [LogicalVecShifterOperand];
235   let Name = "LogicalVecHalfWordShifter";
236   let RenderMethod = "addShifterOperands";
239 // The "MSL" shifter on the vector MOVI instruction.
240 def MoveVecShifterOperand : AsmOperandClass {
241   let SuperClasses = [ShifterOperand];
242   let Name = "MoveVecShifter";
243   let RenderMethod = "addShifterOperands";
246 // Extend operand for arithmetic encodings.
247 def ExtendOperand : AsmOperandClass {
248   let Name = "Extend";
249   let DiagnosticType = "AddSubRegExtendLarge";
251 def ExtendOperand64 : AsmOperandClass {
252   let SuperClasses = [ExtendOperand];
253   let Name = "Extend64";
254   let DiagnosticType = "AddSubRegExtendSmall";
256 // 'extend' that's a lsl of a 64-bit register.
257 def ExtendOperandLSL64 : AsmOperandClass {
258   let SuperClasses = [ExtendOperand];
259   let Name = "ExtendLSL64";
260   let RenderMethod = "addExtend64Operands";
261   let DiagnosticType = "AddSubRegExtendLarge";
264 // 8-bit floating-point immediate encodings.
265 def FPImmOperand : AsmOperandClass {
266   let Name = "FPImm";
267   let ParserMethod = "tryParseFPImm<true>";
268   let DiagnosticType = "InvalidFPImm";
271 def CondCode : AsmOperandClass {
272   let Name = "CondCode";
273   let DiagnosticType = "InvalidCondCode";
276 // A 32-bit register pasrsed as 64-bit
277 def GPR32as64Operand : AsmOperandClass {
278   let Name = "GPR32as64";
279   let ParserMethod =
280       "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";
282 def GPR32as64 : RegisterOperand<GPR32> {
283   let ParserMatchClass = GPR32as64Operand;
286 // A 64-bit register pasrsed as 32-bit
287 def GPR64as32Operand : AsmOperandClass {
288   let Name = "GPR64as32";
289   let ParserMethod =
290       "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";
292 def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {
293   let ParserMatchClass = GPR64as32Operand;
296 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
297 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
298 // are encoded as the eight bit value 'abcdefgh'.
299 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
301 class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
302   let Name = "UImm" # Width # "s" # Scale;
303   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;
304   let RenderMethod = "addImmScaledOperands<" # Scale # ">";
305   let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";
308 class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
309   let Name = "SImm" # Width # "s" # Scale;
310   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;
311   let RenderMethod = "addImmScaledOperands<" # Scale # ">";
312   let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";
315 //===----------------------------------------------------------------------===//
316 // Operand Definitions.
319 // ADR[P] instruction labels.
320 def AdrpOperand : AsmOperandClass {
321   let Name = "AdrpLabel";
322   let ParserMethod = "tryParseAdrpLabel";
323   let DiagnosticType = "InvalidLabel";
325 def adrplabel : Operand<i64> {
326   let EncoderMethod = "getAdrLabelOpValue";
327   let PrintMethod = "printAdrAdrpLabel";
328   let ParserMatchClass = AdrpOperand;
329   let OperandType = "OPERAND_PCREL";
332 def AdrOperand : AsmOperandClass {
333   let Name = "AdrLabel";
334   let ParserMethod = "tryParseAdrLabel";
335   let DiagnosticType = "InvalidLabel";
337 def adrlabel : Operand<i64> {
338   let EncoderMethod = "getAdrLabelOpValue";
339   let PrintMethod = "printAdrAdrpLabel";
340   let ParserMatchClass = AdrOperand;
341   let OperandType = "OPERAND_PCREL";
344 class SImmOperand<int width> : AsmOperandClass {
345   let Name = "SImm" # width;
346   let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
347   let RenderMethod = "addImmOperands";
348   let PredicateMethod = "isSImm<" # width # ">";
351 class AsmImmRange<int Low, int High> : AsmOperandClass {
352   let Name = "Imm" # Low # "_" # High;
353   let DiagnosticType = "InvalidImm" # Low # "_" # High;
354   let RenderMethod = "addImmOperands";
355   let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
358 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
359 def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;
360 def simm10Scaled : Operand<i64> {
361   let ParserMatchClass = SImm10s8Operand;
362   let DecoderMethod = "DecodeSImm<10>";
363   let PrintMethod = "printImmScale<8>";
366 def simm9s16 : Operand<i64> {
367   let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;
368   let DecoderMethod = "DecodeSImm<9>";
369   let PrintMethod = "printImmScale<16>";
372 // uimm6 predicate - True if the immediate is in the range [0, 63].
373 def UImm6Operand : AsmOperandClass {
374   let Name = "UImm6";
375   let DiagnosticType = "InvalidImm0_63";
378 def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
379   let ParserMatchClass = UImm6Operand;
382 def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
383   let ParserMatchClass = AsmImmRange<0, 65535>;
386 def SImm9Operand : SImmOperand<9>;
387 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
388   let ParserMatchClass = SImm9Operand;
389   let DecoderMethod = "DecodeSImm<9>";
392 // imm0_255 predicate - True if the immediate is in the range [0,255].
393 def Imm0_255Operand : AsmImmRange<0,255>;
395 def uimm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
396   let ParserMatchClass = Imm0_255Operand;
398 def uimm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 256; }]> {
399   let ParserMatchClass = Imm0_255Operand;
402 def SImm8Operand : SImmOperand<8>;
403 def simm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> {
404   let ParserMatchClass = SImm8Operand;
405   let DecoderMethod = "DecodeSImm<8>";
407 def simm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 128; }]> {
408   let ParserMatchClass = SImm8Operand;
409   let DecoderMethod = "DecodeSImm<8>";
412 def SImm6Operand : SImmOperand<6>;
413 def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
414   let ParserMatchClass = SImm6Operand;
415   let DecoderMethod = "DecodeSImm<6>";
418 def SImm5Operand : SImmOperand<5>;
419 def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
420   let ParserMatchClass = SImm5Operand;
421   let DecoderMethod = "DecodeSImm<5>";
424 def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
425   let ParserMatchClass = SImm5Operand;
426   let DecoderMethod = "DecodeSImm<5>";
429 def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {
430   let ParserMatchClass = SImm5Operand;
431   let DecoderMethod = "DecodeSImm<5>";
432   let PrintMethod = "printSImm<8>";
435 def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {
436   let ParserMatchClass = SImm5Operand;
437   let DecoderMethod = "DecodeSImm<5>";
438   let PrintMethod = "printSImm<16>";
441 // simm7sN predicate - True if the immediate is a multiple of N in the range
442 // [-64 * N, 63 * N].
444 def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;
445 def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;
446 def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
448 def simm7s4 : Operand<i32> {
449   let ParserMatchClass = SImm7s4Operand;
450   let PrintMethod = "printImmScale<4>";
453 def simm7s8 : Operand<i32> {
454   let ParserMatchClass = SImm7s8Operand;
455   let PrintMethod = "printImmScale<8>";
458 def simm7s16 : Operand<i32> {
459   let ParserMatchClass = SImm7s16Operand;
460   let PrintMethod = "printImmScale<16>";
463 def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>;
465 def am_indexed7s8   : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>;
466 def am_indexed7s16  : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>;
467 def am_indexed7s32  : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>;
468 def am_indexed7s64  : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>;
469 def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>;
471 def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>;
472 def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>;
474 def UImmS1XForm : SDNodeXForm<imm, [{
475   return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64);
476 }]>;
477 def UImmS2XForm : SDNodeXForm<imm, [{
478   return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);
479 }]>;
480 def UImmS4XForm : SDNodeXForm<imm, [{
481   return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);
482 }]>;
483 def UImmS8XForm : SDNodeXForm<imm, [{
484   return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
485 }]>;
487 // uimm5sN predicate - True if the immediate is a multiple of N in the range
488 // [0 * N, 32 * N].
489 def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
490 def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;
491 def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;
493 def uimm5s2 : Operand<i64>, ImmLeaf<i64,
494                 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
495                 UImmS2XForm> {
496   let ParserMatchClass = UImm5s2Operand;
497   let PrintMethod = "printImmScale<2>";
499 def uimm5s4 : Operand<i64>, ImmLeaf<i64,
500                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
501                 UImmS4XForm> {
502   let ParserMatchClass = UImm5s4Operand;
503   let PrintMethod = "printImmScale<4>";
505 def uimm5s8 : Operand<i64>, ImmLeaf<i64,
506                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
507                 UImmS8XForm> {
508   let ParserMatchClass = UImm5s8Operand;
509   let PrintMethod = "printImmScale<8>";
512 // tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant)
513 // instead of ImmLeaf (Constant)
514 def tuimm5s2 : Operand<i64>, TImmLeaf<i64,
515                 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
516                 UImmS2XForm> {
517   let ParserMatchClass = UImm5s2Operand;
518   let PrintMethod = "printImmScale<2>";
520 def tuimm5s4 : Operand<i64>, TImmLeaf<i64,
521                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
522                 UImmS4XForm> {
523   let ParserMatchClass = UImm5s4Operand;
524   let PrintMethod = "printImmScale<4>";
526 def tuimm5s8 : Operand<i64>, TImmLeaf<i64,
527                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
528                 UImmS8XForm> {
529   let ParserMatchClass = UImm5s8Operand;
530   let PrintMethod = "printImmScale<8>";
533 // uimm6sN predicate - True if the immediate is a multiple of N in the range
534 // [0 * N, 64 * N].
535 def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;
536 def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;
537 def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;
538 def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;
539 def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;
541 def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
542   let ParserMatchClass = UImm6s1Operand;
544 def uimm6s2 : Operand<i64>, ImmLeaf<i64,
545 [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
546   let PrintMethod = "printImmScale<2>";
547   let ParserMatchClass = UImm6s2Operand;
549 def uimm6s4 : Operand<i64>, ImmLeaf<i64,
550 [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
551   let PrintMethod = "printImmScale<4>";
552   let ParserMatchClass = UImm6s4Operand;
554 def uimm6s8 : Operand<i64>, ImmLeaf<i64,
555 [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
556   let PrintMethod = "printImmScale<8>";
557   let ParserMatchClass = UImm6s8Operand;
559 def uimm6s16 : Operand<i64>, ImmLeaf<i64,
560 [{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {
561   let PrintMethod = "printImmScale<16>";
562   let ParserMatchClass = UImm6s16Operand;
565 def SImmS2XForm : SDNodeXForm<imm, [{
566   return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64);
567 }]>;
568 def SImmS3XForm : SDNodeXForm<imm, [{
569   return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64);
570 }]>;
571 def SImmS4XForm : SDNodeXForm<imm, [{
572   return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64);
573 }]>;
574 def SImmS16XForm : SDNodeXForm<imm, [{
575   return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64);
576 }]>;
577 def SImmS32XForm : SDNodeXForm<imm, [{
578   return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64);
579 }]>;
581 // simm6sN predicate - True if the immediate is a multiple of N in the range
582 // [-32 * N, 31 * N].
583 def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
584 def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
585   let ParserMatchClass = SImm6s1Operand;
586   let DecoderMethod = "DecodeSImm<6>";
589 // simm4sN predicate - True if the immediate is a multiple of N in the range
590 // [ -8* N, 7 * N].
591 def SImm4s1Operand  : SImmScaledMemoryIndexed<4, 1>;
592 def SImm4s2Operand  : SImmScaledMemoryIndexed<4, 2>;
593 def SImm4s3Operand  : SImmScaledMemoryIndexed<4, 3>;
594 def SImm4s4Operand  : SImmScaledMemoryIndexed<4, 4>;
595 def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
596 def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>;
598 def simm4s1 : Operand<i64>, ImmLeaf<i64,
599 [{ return Imm >=-8  && Imm <= 7; }]> {
600   let ParserMatchClass = SImm4s1Operand;
601   let DecoderMethod = "DecodeSImm<4>";
604 def simm4s2 : Operand<i64>, ImmLeaf<i64,
605 [{ return Imm >=-16  && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> {
606   let PrintMethod = "printImmScale<2>";
607   let ParserMatchClass = SImm4s2Operand;
608   let DecoderMethod = "DecodeSImm<4>";
611 def simm4s3 : Operand<i64>, ImmLeaf<i64,
612 [{ return Imm >=-24  && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> {
613   let PrintMethod = "printImmScale<3>";
614   let ParserMatchClass = SImm4s3Operand;
615   let DecoderMethod = "DecodeSImm<4>";
618 def simm4s4 : Operand<i64>, ImmLeaf<i64,
619 [{ return Imm >=-32  && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> {
620   let PrintMethod = "printImmScale<4>";
621   let ParserMatchClass = SImm4s4Operand;
622   let DecoderMethod = "DecodeSImm<4>";
624 def simm4s16 : Operand<i64>, ImmLeaf<i64,
625 [{ return Imm >=-128  && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> {
626   let PrintMethod = "printImmScale<16>";
627   let ParserMatchClass = SImm4s16Operand;
628   let DecoderMethod = "DecodeSImm<4>";
630 def simm4s32 : Operand<i64>, ImmLeaf<i64,
631 [{ return Imm >=-256  && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> {
632   let PrintMethod = "printImmScale<32>";
633   let ParserMatchClass = SImm4s32Operand;
634   let DecoderMethod = "DecodeSImm<4>";
637 def Imm1_8Operand : AsmImmRange<1, 8>;
638 def Imm1_16Operand : AsmImmRange<1, 16>;
639 def Imm1_32Operand : AsmImmRange<1, 32>;
640 def Imm1_64Operand : AsmImmRange<1, 64>;
642 class BranchTarget<int N> : AsmOperandClass {
643   let Name = "BranchTarget" # N;
644   let DiagnosticType = "InvalidLabel";
645   let PredicateMethod = "isBranchTarget<" # N # ">";
648 class PCRelLabel<int N> : BranchTarget<N> {
649   let Name = "PCRelLabel" # N;
652 def BranchTarget14Operand : BranchTarget<14>;
653 def BranchTarget26Operand : BranchTarget<26>;
654 def PCRelLabel19Operand   : PCRelLabel<19>;
656 def MovWSymbolG3AsmOperand : AsmOperandClass {
657   let Name = "MovWSymbolG3";
658   let RenderMethod = "addImmOperands";
661 def movw_symbol_g3 : Operand<i32> {
662   let ParserMatchClass = MovWSymbolG3AsmOperand;
665 def MovWSymbolG2AsmOperand : AsmOperandClass {
666   let Name = "MovWSymbolG2";
667   let RenderMethod = "addImmOperands";
670 def movw_symbol_g2 : Operand<i32> {
671   let ParserMatchClass = MovWSymbolG2AsmOperand;
674 def MovWSymbolG1AsmOperand : AsmOperandClass {
675   let Name = "MovWSymbolG1";
676   let RenderMethod = "addImmOperands";
679 def movw_symbol_g1 : Operand<i32> {
680   let ParserMatchClass = MovWSymbolG1AsmOperand;
683 def MovWSymbolG0AsmOperand : AsmOperandClass {
684   let Name = "MovWSymbolG0";
685   let RenderMethod = "addImmOperands";
688 def movw_symbol_g0 : Operand<i32> {
689   let ParserMatchClass = MovWSymbolG0AsmOperand;
692 class fixedpoint_i32<ValueType FloatVT>
693   : Operand<FloatVT>,
694     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
695   let EncoderMethod = "getFixedPointScaleOpValue";
696   let DecoderMethod = "DecodeFixedPointScaleImm32";
697   let ParserMatchClass = Imm1_32Operand;
700 class fixedpoint_i64<ValueType FloatVT>
701   : Operand<FloatVT>,
702     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
703   let EncoderMethod = "getFixedPointScaleOpValue";
704   let DecoderMethod = "DecodeFixedPointScaleImm64";
705   let ParserMatchClass = Imm1_64Operand;
708 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
709 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
710 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
712 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
713 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
714 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
716 class fixedpoint_recip_i32<ValueType FloatVT>
717   : Operand<FloatVT>,
718     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<32>", [fpimm, ld]> {
719   let EncoderMethod = "getFixedPointScaleOpValue";
720   let DecoderMethod = "DecodeFixedPointScaleImm32";
723 class fixedpoint_recip_i64<ValueType FloatVT>
724   : Operand<FloatVT>,
725     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<64>", [fpimm, ld]> {
726   let EncoderMethod = "getFixedPointScaleOpValue";
727   let DecoderMethod = "DecodeFixedPointScaleImm64";
730 def fixedpoint_recip_f16_i32 : fixedpoint_recip_i32<f16>;
731 def fixedpoint_recip_f32_i32 : fixedpoint_recip_i32<f32>;
732 def fixedpoint_recip_f64_i32 : fixedpoint_recip_i32<f64>;
734 def fixedpoint_recip_f16_i64 : fixedpoint_recip_i64<f16>;
735 def fixedpoint_recip_f32_i64 : fixedpoint_recip_i64<f32>;
736 def fixedpoint_recip_f64_i64 : fixedpoint_recip_i64<f64>;
738 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
739   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
740 }]> {
741   let EncoderMethod = "getVecShiftR8OpValue";
742   let DecoderMethod = "DecodeVecShiftR8Imm";
743   let ParserMatchClass = Imm1_8Operand;
745 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
746   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
747 }]> {
748   let EncoderMethod = "getVecShiftR16OpValue";
749   let DecoderMethod = "DecodeVecShiftR16Imm";
750   let ParserMatchClass = Imm1_16Operand;
752 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
753   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
754 }]> {
755   let EncoderMethod = "getVecShiftR16OpValue";
756   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
757   let ParserMatchClass = Imm1_8Operand;
759 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
760   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
761 }]> {
762   let EncoderMethod = "getVecShiftR32OpValue";
763   let DecoderMethod = "DecodeVecShiftR32Imm";
764   let ParserMatchClass = Imm1_32Operand;
766 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
767   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
768 }]> {
769   let EncoderMethod = "getVecShiftR32OpValue";
770   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
771   let ParserMatchClass = Imm1_16Operand;
773 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
774   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
775 }]> {
776   let EncoderMethod = "getVecShiftR64OpValue";
777   let DecoderMethod = "DecodeVecShiftR64Imm";
778   let ParserMatchClass = Imm1_64Operand;
780 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
781   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
782 }]> {
783   let EncoderMethod = "getVecShiftR64OpValue";
784   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
785   let ParserMatchClass = Imm1_32Operand;
788 // Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant
789 // (ImmLeaf)
790 def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
791   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
792 }]> {
793   let EncoderMethod = "getVecShiftR8OpValue";
794   let DecoderMethod = "DecodeVecShiftR8Imm";
795   let ParserMatchClass = Imm1_8Operand;
797 def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
798   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
799 }]> {
800   let EncoderMethod = "getVecShiftR16OpValue";
801   let DecoderMethod = "DecodeVecShiftR16Imm";
802   let ParserMatchClass = Imm1_16Operand;
804 def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
805   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
806 }]> {
807   let EncoderMethod = "getVecShiftR32OpValue";
808   let DecoderMethod = "DecodeVecShiftR32Imm";
809   let ParserMatchClass = Imm1_32Operand;
811 def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{
812   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
813 }]> {
814   let EncoderMethod = "getVecShiftR64OpValue";
815   let DecoderMethod = "DecodeVecShiftR64Imm";
816   let ParserMatchClass = Imm1_64Operand;
819 def Imm0_0Operand : AsmImmRange<0, 0>;
820 def Imm0_1Operand : AsmImmRange<0, 1>;
821 def Imm1_1Operand : AsmImmRange<1, 1>;
822 def Imm0_3Operand : AsmImmRange<0, 3>;
823 def Imm1_3Operand : AsmImmRange<1, 3>;
824 def Imm0_7Operand : AsmImmRange<0, 7>;
825 def Imm1_7Operand : AsmImmRange<1, 7>;
826 def Imm0_15Operand : AsmImmRange<0, 15>;
827 def Imm0_31Operand : AsmImmRange<0, 31>;
828 def Imm0_63Operand : AsmImmRange<0, 63>;
830 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
831   return (((uint32_t)Imm) < 8);
832 }]> {
833   let EncoderMethod = "getVecShiftL8OpValue";
834   let DecoderMethod = "DecodeVecShiftL8Imm";
835   let ParserMatchClass = Imm0_7Operand;
837 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
838   return (((uint32_t)Imm) < 16);
839 }]> {
840   let EncoderMethod = "getVecShiftL16OpValue";
841   let DecoderMethod = "DecodeVecShiftL16Imm";
842   let ParserMatchClass = Imm0_15Operand;
844 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
845   return (((uint32_t)Imm) < 32);
846 }]> {
847   let EncoderMethod = "getVecShiftL32OpValue";
848   let DecoderMethod = "DecodeVecShiftL32Imm";
849   let ParserMatchClass = Imm0_31Operand;
851 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
852   return (((uint32_t)Imm) < 64);
853 }]> {
854   let EncoderMethod = "getVecShiftL64OpValue";
855   let DecoderMethod = "DecodeVecShiftL64Imm";
856   let ParserMatchClass = Imm0_63Operand;
859 // Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant
860 // (ImmLeaf)
861 def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{
862   return (((uint32_t)Imm) < 8);
863 }]> {
864   let EncoderMethod = "getVecShiftL8OpValue";
865   let DecoderMethod = "DecodeVecShiftL8Imm";
866   let ParserMatchClass = Imm0_7Operand;
868 def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{
869   return (((uint32_t)Imm) < 16);
870 }]> {
871   let EncoderMethod = "getVecShiftL16OpValue";
872   let DecoderMethod = "DecodeVecShiftL16Imm";
873   let ParserMatchClass = Imm0_15Operand;
875 def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{
876   return (((uint32_t)Imm) < 32);
877 }]> {
878   let EncoderMethod = "getVecShiftL32OpValue";
879   let DecoderMethod = "DecodeVecShiftL32Imm";
880   let ParserMatchClass = Imm0_31Operand;
882 def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{
883   return (((uint32_t)Imm) < 64);
884 }]> {
885   let EncoderMethod = "getVecShiftL64OpValue";
886   let DecoderMethod = "DecodeVecShiftL64Imm";
887   let ParserMatchClass = Imm0_63Operand;
890 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
891 // instructions for splatting repeating bit patterns across the immediate.
892 def logical_imm32_XFORM : SDNodeXForm<imm, [{
893   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
894   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
895 }]>;
896 def logical_imm64_XFORM : SDNodeXForm<imm, [{
897   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
898   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
899 }]>;
901 def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">,
902   GISDNodeXFormEquiv<logical_imm32_XFORM>;
903 def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">,
904   GISDNodeXFormEquiv<logical_imm64_XFORM>;
906 let DiagnosticType = "LogicalSecondSource" in {
907   def LogicalImm32Operand : AsmOperandClass {
908     let Name = "LogicalImm32";
909     let PredicateMethod = "isLogicalImm<int32_t>";
910     let RenderMethod = "addLogicalImmOperands<int32_t>";
911   }
912   def LogicalImm64Operand : AsmOperandClass {
913     let Name = "LogicalImm64";
914     let PredicateMethod = "isLogicalImm<int64_t>";
915     let RenderMethod = "addLogicalImmOperands<int64_t>";
916   }
917   def LogicalImm32NotOperand : AsmOperandClass {
918     let Name = "LogicalImm32Not";
919     let PredicateMethod = "isLogicalImm<int32_t>";
920     let RenderMethod = "addLogicalImmNotOperands<int32_t>";
921   }
922   def LogicalImm64NotOperand : AsmOperandClass {
923     let Name = "LogicalImm64Not";
924     let PredicateMethod = "isLogicalImm<int64_t>";
925     let RenderMethod = "addLogicalImmNotOperands<int64_t>";
926   }
929 def Imm0_127Operand : AsmImmRange<0, 127>;
931 let OperandType = "OPERAND_IMMEDIATE" in {
933 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
934   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
935 }], logical_imm32_XFORM> {
936   let PrintMethod = "printLogicalImm<int32_t>";
937   let ParserMatchClass = LogicalImm32Operand;
939 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
940   return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
941 }], logical_imm64_XFORM> {
942   let PrintMethod = "printLogicalImm<int64_t>";
943   let ParserMatchClass = LogicalImm64Operand;
945 def logical_imm32_not : Operand<i32> {
946   let ParserMatchClass = LogicalImm32NotOperand;
948 def logical_imm64_not : Operand<i64> {
949   let ParserMatchClass = LogicalImm64NotOperand;
952 // immXX_0_65535 predicates - True if the immediate is in the range [0,65535].
953 let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in {
954 def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{
955   return ((uint32_t)Imm) < 65536;
956 }]>;
958 def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{
959   return ((uint64_t)Imm) < 65536;
960 }]>;
962 def imm64_0_65535 : Operand<i64>, ImmLeaf<i64, [{
963   return ((uint64_t)Imm) < 65536;
964 }]>;
965 } // ParserMatchClass
967 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
968   return ((uint32_t)Imm) < 256;
969 }]> {
970   let ParserMatchClass = Imm0_255Operand;
971   let PrintMethod = "printImm";
974 // imm0_127 predicate - True if the immediate is in the range [0,127]
975 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
976   return ((uint32_t)Imm) < 128;
977 }]> {
978   let ParserMatchClass = Imm0_127Operand;
979   let PrintMethod = "printImm";
982 def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{
983   return ((uint64_t)Imm) < 128;
984 }]> {
985   let ParserMatchClass = Imm0_127Operand;
986   let PrintMethod = "printImm";
989 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
990 // for all shift-amounts.
992 // imm0_63 predicate - True if the immediate is in the range [0,63]
993 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
994   return ((uint64_t)Imm) < 64;
995 }]> {
996   let ParserMatchClass = Imm0_63Operand;
999 def timm0_63 : Operand<i64>, TImmLeaf<i64, [{
1000   return ((uint64_t)Imm) < 64;
1001 }]> {
1002   let ParserMatchClass = Imm0_63Operand;
1005 // imm0_31 predicate - True if the immediate is in the range [0,31]
1006 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
1007   return ((uint64_t)Imm) < 32;
1008 }]> {
1009   let ParserMatchClass = Imm0_31Operand;
1012 // timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf)
1013 // instead of Constant (ImmLeaf)
1014 def timm0_31 : Operand<i64>, TImmLeaf<i64, [{
1015   return ((uint64_t)Imm) < 32;
1016 }]> {
1017   let ParserMatchClass = Imm0_31Operand;
1020 // True if the 32-bit immediate is in the range [0,31]
1021 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
1022   return ((uint64_t)Imm) < 32;
1023 }]> {
1024   let ParserMatchClass = Imm0_31Operand;
1027 // imm0_1 predicate - True if the immediate is in the range [0,1]
1028 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
1029   return ((uint64_t)Imm) < 2;
1030 }]> {
1031   let ParserMatchClass = Imm0_1Operand;
1034 // timm0_1 - as above, but use TargetConstant (TImmLeaf)
1035 def timm0_1 : Operand<i64>, TImmLeaf<i64, [{
1036   return ((uint64_t)Imm) < 2;
1037 }]> {
1038   let ParserMatchClass = Imm0_1Operand;
1041 // timm32_0_0 predicate - True if the 32-bit immediate is in the range [0,0]
1042 def timm32_0_0 : Operand<i32>, TImmLeaf<i32, [{
1043   return ((uint32_t)Imm) == 0;
1044 }]> {
1045   let ParserMatchClass = Imm0_0Operand;
1048 // timm32_0_1 predicate - True if the 32-bit immediate is in the range [0,1]
1049 def timm32_0_1 : Operand<i32>, TImmLeaf<i32, [{
1050   return ((uint32_t)Imm) < 2;
1051 }]> {
1052   let ParserMatchClass = Imm0_1Operand;
1055 // timm32_1_1 - True if the 32-bit immediate is in the range [1,1]
1056 def timm32_1_1 : Operand<i32>, TImmLeaf<i32, [{
1057     return ((uint32_t)Imm) == 1;
1058 }]> {
1059   let ParserMatchClass = Imm1_1Operand;
1062 // timm32_1_3 predicate - True if the 32-bit immediate is in the range [1,3]
1063 def timm32_1_3 : Operand<i32>, TImmLeaf<i32, [{
1064   return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 4;
1065 }]> {
1066   let ParserMatchClass = Imm1_3Operand;
1069 // imm0_15 predicate - True if the immediate is in the range [0,15]
1070 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
1071   return ((uint64_t)Imm) < 16;
1072 }]> {
1073   let ParserMatchClass = Imm0_15Operand;
1076 // imm0_7 predicate - True if the immediate is in the range [0,7]
1077 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
1078   return ((uint64_t)Imm) < 8;
1079 }]> {
1080   let ParserMatchClass = Imm0_7Operand;
1083 // imm0_3 predicate - True if the immediate is in the range [0,3]
1084 def imm0_3 : Operand<i64>, ImmLeaf<i64, [{
1085   return ((uint64_t)Imm) < 4;
1086 }]> {
1087   let ParserMatchClass = Imm0_3Operand;
1090 // timm32_0_3 predicate - True if the 32-bit immediate is in the range [0,3]
1091 def timm32_0_3 : Operand<i32>, TImmLeaf<i32, [{
1092   return ((uint32_t)Imm) < 4;
1093 }]> {
1094   let ParserMatchClass = Imm0_3Operand;
1097 // timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
1098 def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{
1099   return ((uint32_t)Imm) < 8;
1100 }]> {
1101   let ParserMatchClass = Imm0_7Operand;
1104 // timm32_1_7 predicate - True if the 32-bit immediate is in the range [1,7]
1105 def timm32_1_7 : Operand<i32>, TImmLeaf<i32, [{
1106   return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 8;
1107 }]> {
1108   let ParserMatchClass = Imm1_7Operand;
1111 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
1112 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
1113   return ((uint32_t)Imm) < 16;
1114 }]> {
1115   let ParserMatchClass = Imm0_15Operand;
1118 // timm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
1119 def timm32_0_15 : Operand<i32>, TImmLeaf<i32, [{
1120   return ((uint32_t)Imm) < 16;
1121 }]> {
1122   let ParserMatchClass = Imm0_15Operand;
1125 // timm32_0_31 predicate - True if the 32-bit immediate is in the range [0,31]
1126 def timm32_0_31 : Operand<i32>, TImmLeaf<i32, [{
1127   return ((uint32_t)Imm) < 32;
1128 }]> {
1129   let ParserMatchClass = Imm0_31Operand;
1132 // timm32_0_255 predicate - True if the 32-bit immediate is in the range [0,255]
1133 def timm32_0_255 : Operand<i32>, TImmLeaf<i32, [{
1134   return ((uint32_t)Imm) < 256;
1135 }]> {
1136   let ParserMatchClass = Imm0_255Operand;
1139 } // let OperandType = "OPERAND_IMMEDIATE"
1141 // An arithmetic shifter operand:
1142 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
1143 //  {5-0} - imm6
1144 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
1145   let PrintMethod = "printShifter";
1146   let ParserMatchClass = !cast<AsmOperandClass>(
1147                          "ArithmeticShifterOperand" # width);
1150 def arith_shift32 : arith_shift<i32, 32>;
1151 def arith_shift64 : arith_shift<i64, 64>;
1153 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
1154     : Operand<Ty>,
1155       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
1156   let PrintMethod = "printShiftedRegister";
1157   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
1160 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
1161 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
1163 def gi_arith_shifted_reg32 :
1164   GIComplexOperandMatcher<s32, "selectArithShiftedRegister">,
1165   GIComplexPatternEquiv<arith_shifted_reg32>;
1167 def gi_arith_shifted_reg64 :
1168   GIComplexOperandMatcher<s64, "selectArithShiftedRegister">,
1169   GIComplexPatternEquiv<arith_shifted_reg64>;
1171 // An arithmetic shifter operand:
1172 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
1173 //  {5-0} - imm6
1174 class logical_shift<int width> : Operand<i32> {
1175   let PrintMethod = "printShifter";
1176   let ParserMatchClass = !cast<AsmOperandClass>(
1177                          "LogicalShifterOperand" # width);
1180 def logical_shift32 : logical_shift<32>;
1181 def logical_shift64 : logical_shift<64>;
1183 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
1184     : Operand<Ty>,
1185       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
1186   let PrintMethod = "printShiftedRegister";
1187   let MIOperandInfo = (ops regclass, shiftop);
1190 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
1191 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
1193 def gi_logical_shifted_reg32 :
1194   GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">,
1195   GIComplexPatternEquiv<logical_shifted_reg32>;
1197 def gi_logical_shifted_reg64 :
1198   GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">,
1199   GIComplexPatternEquiv<logical_shifted_reg64>;
1201 // A logical vector shifter operand:
1202 //  {7-6} - shift type: 00 = lsl
1203 //  {5-0} - imm6: #0, #8, #16, or #24
1204 def logical_vec_shift : Operand<i32> {
1205   let PrintMethod = "printShifter";
1206   let EncoderMethod = "getVecShifterOpValue";
1207   let ParserMatchClass = LogicalVecShifterOperand;
1210 // A logical vector half-word shifter operand:
1211 //  {7-6} - shift type: 00 = lsl
1212 //  {5-0} - imm6: #0 or #8
1213 def logical_vec_hw_shift : Operand<i32> {
1214   let PrintMethod = "printShifter";
1215   let EncoderMethod = "getVecShifterOpValue";
1216   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
1219 // A vector move shifter operand:
1220 //  {0} - imm1: #8 or #16
1221 def move_vec_shift : Operand<i32> {
1222   let PrintMethod = "printShifter";
1223   let EncoderMethod = "getMoveVecShifterOpValue";
1224   let ParserMatchClass = MoveVecShifterOperand;
1227 let DiagnosticType = "AddSubSecondSource" in {
1228   def AddSubImmOperand : AsmOperandClass {
1229     let Name = "AddSubImm";
1230     let ParserMethod = "tryParseImmWithOptionalShift";
1231     let RenderMethod = "addImmWithOptionalShiftOperands<12>";
1232   }
1233   def AddSubImmNegOperand : AsmOperandClass {
1234     let Name = "AddSubImmNeg";
1235     let ParserMethod = "tryParseImmWithOptionalShift";
1236     let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
1237   }
1239 // An ADD/SUB immediate shifter operand:
1240 //  second operand:
1241 //  {7-6} - shift type: 00 = lsl
1242 //  {5-0} - imm6: #0 or #12
1243 class addsub_shifted_imm<ValueType Ty>
1244     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
1245   let PrintMethod = "printAddSubImm";
1246   let EncoderMethod = "getAddSubImmOpValue";
1247   let ParserMatchClass = AddSubImmOperand;
1248   let MIOperandInfo = (ops i32imm, i32imm);
1251 class addsub_shifted_imm_neg<ValueType Ty>
1252     : Operand<Ty> {
1253   let EncoderMethod = "getAddSubImmOpValue";
1254   let ParserMatchClass = AddSubImmNegOperand;
1255   let MIOperandInfo = (ops i32imm, i32imm);
1258 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
1259 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
1260 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
1261 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
1263 def gi_addsub_shifted_imm32 :
1264     GIComplexOperandMatcher<s32, "selectArithImmed">,
1265     GIComplexPatternEquiv<addsub_shifted_imm32>;
1267 def gi_addsub_shifted_imm64 :
1268     GIComplexOperandMatcher<s64, "selectArithImmed">,
1269     GIComplexPatternEquiv<addsub_shifted_imm64>;
1271 class neg_addsub_shifted_imm<ValueType Ty>
1272     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
1273   let PrintMethod = "printAddSubImm";
1274   let EncoderMethod = "getAddSubImmOpValue";
1275   let ParserMatchClass = AddSubImmOperand;
1276   let MIOperandInfo = (ops i32imm, i32imm);
1279 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
1280 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
1282 def gi_neg_addsub_shifted_imm32 :
1283     GIComplexOperandMatcher<s32, "selectNegArithImmed">,
1284     GIComplexPatternEquiv<neg_addsub_shifted_imm32>;
1286 def gi_neg_addsub_shifted_imm64 :
1287     GIComplexOperandMatcher<s64, "selectNegArithImmed">,
1288     GIComplexPatternEquiv<neg_addsub_shifted_imm64>;
1290 // An extend operand:
1291 //  {5-3} - extend type
1292 //  {2-0} - imm3
1293 def arith_extend : Operand<i32> {
1294   let PrintMethod = "printArithExtend";
1295   let ParserMatchClass = ExtendOperand;
1297 def arith_extend64 : Operand<i32> {
1298   let PrintMethod = "printArithExtend";
1299   let ParserMatchClass = ExtendOperand64;
1302 // 'extend' that's a lsl of a 64-bit register.
1303 def arith_extendlsl64 : Operand<i32> {
1304   let PrintMethod = "printArithExtend";
1305   let ParserMatchClass = ExtendOperandLSL64;
1308 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
1309                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1310   let PrintMethod = "printExtendedRegister";
1311   let MIOperandInfo = (ops GPR32, arith_extend);
1314 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
1315                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1316   let PrintMethod = "printExtendedRegister";
1317   let MIOperandInfo = (ops GPR32, arith_extend64);
1320 def arith_extended_reg32_i32 : arith_extended_reg32<i32>;
1321 def gi_arith_extended_reg32_i32 :
1322     GIComplexOperandMatcher<s32, "selectArithExtendedRegister">,
1323     GIComplexPatternEquiv<arith_extended_reg32_i32>;
1325 def arith_extended_reg32_i64 : arith_extended_reg32<i64>;
1326 def gi_arith_extended_reg32_i64 :
1327     GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1328     GIComplexPatternEquiv<arith_extended_reg32_i64>;
1330 def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>;
1331 def gi_arith_extended_reg32to64_i64 :
1332     GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1333     GIComplexPatternEquiv<arith_extended_reg32to64_i64>;
1335 def arith_uxtx : ComplexPattern<i64, 2, "SelectArithUXTXRegister", []>;
1337 // Floating-point immediate.
1339 def fpimm16XForm : SDNodeXForm<fpimm, [{
1340       APFloat InVal = N->getValueAPF();
1341       uint32_t enc = AArch64_AM::getFP16Imm(InVal);
1342       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1343     }]>;
1345 def fpimm32XForm : SDNodeXForm<fpimm, [{
1346       APFloat InVal = N->getValueAPF();
1347       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
1348       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1349     }]>;
1351 def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{
1352       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF()
1353                                                           .bitcastToAPInt()
1354                                                           .getZExtValue());
1355       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1356     }]>;
1358 def fpimm64XForm : SDNodeXForm<fpimm, [{
1359       APFloat InVal = N->getValueAPF();
1360       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
1361       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1362     }]>;
1364 def fpimm16 : Operand<f16>,
1365               FPImmLeaf<f16, [{
1366       return AArch64_AM::getFP16Imm(Imm) != -1;
1367     }], fpimm16XForm> {
1368   let ParserMatchClass = FPImmOperand;
1369   let PrintMethod = "printFPImmOperand";
1372 def fpimmbf16 : Operand<bf16>,
1373                 FPImmLeaf<bf16, [{
1374       return AArch64_AM::getFP16Imm(Imm) != -1;
1375     }], fpimm16XForm>;
1377 def fpimm32 : Operand<f32>,
1378               FPImmLeaf<f32, [{
1379       return AArch64_AM::getFP32Imm(Imm) != -1;
1380     }], fpimm32XForm> {
1381   let ParserMatchClass = FPImmOperand;
1382   let PrintMethod = "printFPImmOperand";
1385 def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{
1386       uint64_t Enc = Imm.bitcastToAPInt().getZExtValue();
1387       return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc);
1388     }], fpimm32SIMDModImmType4XForm> {
1391 def fpimm64 : Operand<f64>,
1392               FPImmLeaf<f64, [{
1393       return AArch64_AM::getFP64Imm(Imm) != -1;
1394     }], fpimm64XForm> {
1395   let ParserMatchClass = FPImmOperand;
1396   let PrintMethod = "printFPImmOperand";
1399 def fpimm8 : Operand<i32> {
1400   let ParserMatchClass = FPImmOperand;
1401   let PrintMethod = "printFPImmOperand";
1404 def fpimm0 : FPImmLeaf<fAny, [{
1405   return Imm.isExactlyValue(+0.0);
1406 }]>;
1408 def fpimm_minus0 : FPImmLeaf<fAny, [{
1409   return Imm.isExactlyValue(-0.0);
1410 }]>;
1412 def fpimm_half : FPImmLeaf<fAny, [{
1413   return Imm.isExactlyValue(+0.5);
1414 }]>;
1416 def fpimm_one : FPImmLeaf<fAny, [{
1417   return Imm.isExactlyValue(+1.0);
1418 }]>;
1420 def fpimm_two : FPImmLeaf<fAny, [{
1421   return Imm.isExactlyValue(+2.0);
1422 }]>;
1424 def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">,
1425   GISDNodeXFormEquiv<fpimm16XForm>;
1426 def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">,
1427   GISDNodeXFormEquiv<fpimm32XForm>;
1428 def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">,
1429   GISDNodeXFormEquiv<fpimm64XForm>;
1430 def gi_fpimm32SIMDModImmType4 :
1431     GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">,
1432   GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>;
1434 // Vector lane operands
1435 class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {
1436   let Name = NamePrefix # "IndexRange" # Min # "_" # Max;
1437   let DiagnosticType = "Invalid" # Name;
1438   let PredicateMethod = "isVectorIndex<" # Min # ", " # Max #  ">";
1439   let RenderMethod = "addVectorIndexOperands";
1442 class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc>
1443     : Operand<ty> {
1444   let ParserMatchClass = mc;
1445   let PrintMethod = "printVectorIndex";
1448 multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> {
1449   def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>;
1450   def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>;
1453 def VectorIndex0Operand : AsmVectorIndex<0, 0>;
1454 def VectorIndex1Operand : AsmVectorIndex<1, 1>;
1455 def VectorIndexBOperand : AsmVectorIndex<0, 15>;
1456 def VectorIndexHOperand : AsmVectorIndex<0, 7>;
1457 def VectorIndexSOperand : AsmVectorIndex<0, 3>;
1458 def VectorIndexDOperand : AsmVectorIndex<0, 1>;
1460 let OperandNamespace = "AArch64" in {
1461   let OperandType = "OPERAND_IMPLICIT_IMM_0" in {
1462     defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand,
1463                                 [{ return ((uint64_t)Imm) == 0; }]>;
1464     defm VectorIndex032b : VectorIndex<i32, VectorIndex0Operand,
1465                                 [{ return ((uint32_t)Imm) == 0; }]>;
1466   }
1468 defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,
1469                                 [{ return ((uint64_t)Imm) == 1; }]>;
1470 defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand,
1471                                 [{ return ((uint64_t)Imm) < 16; }]>;
1472 defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand,
1473                                 [{ return ((uint64_t)Imm) < 8; }]>;
1474 defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand,
1475                                 [{ return ((uint64_t)Imm) < 4; }]>;
1476 defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand,
1477                                 [{ return ((uint64_t)Imm) < 2; }]>;
1479 defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand,
1480                                    [{ return ((uint64_t)Imm) == 1; }]>;
1481 defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand,
1482                                    [{ return ((uint64_t)Imm) < 16; }]>;
1483 defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand,
1484                                    [{ return ((uint64_t)Imm) < 8; }]>;
1485 defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand,
1486                                    [{ return ((uint64_t)Imm) < 4; }]>;
1487 defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand,
1488                                    [{ return ((uint64_t)Imm) < 2; }]>;
1490 def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
1491 def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
1492 def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
1493 def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
1494 def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
1496 defm sve_elm_idx_extdup_b
1497   : VectorIndex<i64, SVEVectorIndexExtDupBOperand,
1498                 [{ return ((uint64_t)Imm) < 64; }]>;
1499 defm sve_elm_idx_extdup_h
1500   : VectorIndex<i64, SVEVectorIndexExtDupHOperand,
1501                 [{ return ((uint64_t)Imm) < 32; }]>;
1502 defm sve_elm_idx_extdup_s
1503   : VectorIndex<i64, SVEVectorIndexExtDupSOperand,
1504                 [{ return ((uint64_t)Imm) < 16; }]>;
1505 defm sve_elm_idx_extdup_d
1506   : VectorIndex<i64, SVEVectorIndexExtDupDOperand,
1507                 [{ return ((uint64_t)Imm) < 8; }]>;
1508 defm sve_elm_idx_extdup_q
1509   : VectorIndex<i64, SVEVectorIndexExtDupQOperand,
1510                 [{ return ((uint64_t)Imm) < 4; }]>;
1512 def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{
1513   return ((uint32_t)Imm) == 0;
1514 }]> {
1515   let ParserMatchClass = Imm0_0Operand;
1516   let PrintMethod = "printMatrixIndex";
1517   let OperandNamespace = "AArch64";
1518   let OperandType = "OPERAND_IMPLICIT_IMM_0";
1520 def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{
1521   return ((uint32_t)Imm) <= 1;
1522 }]> {
1523   let ParserMatchClass = Imm0_1Operand;
1524   let PrintMethod = "printMatrixIndex";
1526 def sme_elm_idx0_3 : Operand<i32>, TImmLeaf<i32, [{
1527   return ((uint32_t)Imm) <= 3;
1528 }]> {
1529   let ParserMatchClass = Imm0_3Operand;
1530   let PrintMethod = "printMatrixIndex";
1532 def sme_elm_idx0_7 : Operand<i32>, TImmLeaf<i32, [{
1533   return ((uint32_t)Imm) <= 7;
1534 }]> {
1535   let ParserMatchClass = Imm0_7Operand;
1536   let PrintMethod = "printMatrixIndex";
1538 def sme_elm_idx0_15 : Operand<i32>, TImmLeaf<i32, [{
1539   return ((uint32_t)Imm) <= 15;
1540 }]> {
1541   let ParserMatchClass = Imm0_15Operand;
1542   let PrintMethod = "printMatrixIndex";
1545 // SME2 vector select offset operands
1547 // uimm3s8 predicate
1548 // True if the immediate is a multiple of 8 in the range [0,56].
1549 def UImm3s8Operand : UImmScaledMemoryIndexed<3, 8>;
1551 def uimm3s8 : Operand<i64>, ImmLeaf<i64,
1552 [{ return Imm >= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> {
1553   let PrintMethod = "printMatrixIndex<8>";
1554   let ParserMatchClass = UImm3s8Operand;
1557 class UImmScaledMemoryIndexedRange<int Width, int Scale, int OffsetVal> : AsmOperandClass {
1558   let Name = "UImm" # Width # "s" # Scale # "Range";
1559   let DiagnosticType = "InvalidMemoryIndexedRange" # Scale # "UImm" # Width;
1560   let RenderMethod = "addImmScaledRangeOperands<" # Scale # ">";
1561   let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ", " # OffsetVal # ", /*IsRange=*/true>";
1562   let ParserMethod = "tryParseImmRange";
1565 // Implicit immediate ranges 0:1 and 0:3, scale has no meaning
1566 // since the immediate is zero
1567 def UImm0s2RangeOperand : UImmScaledMemoryIndexedRange<0, 2, 1>;
1568 def UImm0s4RangeOperand : UImmScaledMemoryIndexedRange<0, 4, 3>;
1570 def UImm1s2RangeOperand : UImmScaledMemoryIndexedRange<1, 2, 1>;
1571 def UImm1s4RangeOperand : UImmScaledMemoryIndexedRange<1, 4, 3>;
1572 def UImm2s2RangeOperand : UImmScaledMemoryIndexedRange<2, 2, 1>;
1573 def UImm2s4RangeOperand : UImmScaledMemoryIndexedRange<2, 4, 3>;
1574 def UImm3s2RangeOperand : UImmScaledMemoryIndexedRange<3, 2, 1>;
1576 def uimm0s2range : Operand<i64>, ImmLeaf<i64,
1577 [{ return Imm == 0; }], UImmS1XForm> {
1578   let PrintMethod = "printImmRangeScale<2, 1>";
1579   let ParserMatchClass = UImm0s2RangeOperand;
1580   let OperandNamespace = "AArch64";
1581   let OperandType = "OPERAND_IMPLICIT_IMM_0";
1584 def uimm0s4range : Operand<i64>, ImmLeaf<i64,
1585 [{ return Imm == 0; }], UImmS1XForm> {
1586   let PrintMethod = "printImmRangeScale<4, 3>";
1587   let ParserMatchClass = UImm0s4RangeOperand;
1588   let OperandNamespace = "AArch64";
1589   let OperandType = "OPERAND_IMPLICIT_IMM_0";
1592 def uimm1s2range : Operand<i64>, ImmLeaf<i64,
1593 [{ return Imm >= 0 && Imm <= 2 && ((Imm % 2) == 0); }], UImmS2XForm> {
1594   let PrintMethod = "printImmRangeScale<2, 1>";
1595   let ParserMatchClass = UImm1s2RangeOperand;
1598 def uimm1s4range : Operand<i64>, ImmLeaf<i64,
1599 [{ return Imm >= 0 && Imm <= 4 && ((Imm % 4) == 0); }], UImmS4XForm> {
1600   let PrintMethod = "printImmRangeScale<4, 3>";
1601   let ParserMatchClass = UImm1s4RangeOperand;
1604 def uimm2s2range : Operand<i64>, ImmLeaf<i64,
1605 [{ return Imm >= 0 && Imm <= 6 && ((Imm % 2) == 0); }], UImmS2XForm> {
1606   let PrintMethod = "printImmRangeScale<2, 1>";
1607   let ParserMatchClass = UImm2s2RangeOperand;
1610 def uimm2s4range : Operand<i64>, ImmLeaf<i64,
1611 [{ return Imm >= 0 && Imm <= 12 && ((Imm % 4) == 0); }], UImmS4XForm> {
1612   let PrintMethod = "printImmRangeScale<4, 3>";
1613   let ParserMatchClass = UImm2s4RangeOperand;
1616 def uimm3s2range : Operand<i64>, ImmLeaf<i64,
1617 [{ return Imm >= 0 && Imm <= 14 && ((Imm % 2) == 0); }], UImmS2XForm> {
1618   let PrintMethod = "printImmRangeScale<2, 1>";
1619   let ParserMatchClass = UImm3s2RangeOperand;
1623 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
1624 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
1625 // are encoded as the eight bit value 'abcdefgh'.
1626 def simdimmtype10 : Operand<i32>,
1627                     FPImmLeaf<f64, [{
1628       return AArch64_AM::isAdvSIMDModImmType10(
1629                  Imm.bitcastToAPInt().getZExtValue());
1630     }], SDNodeXForm<fpimm, [{
1631       APFloat InVal = N->getValueAPF();
1632       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
1633                                                            .bitcastToAPInt()
1634                                                            .getZExtValue());
1635       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1636     }]>> {
1637   let ParserMatchClass = SIMDImmType10Operand;
1638   let PrintMethod = "printSIMDType10Operand";
1642 //---
1643 // System management
1644 //---
1646 // Base encoding for system instruction operands.
1647 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
1648 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
1649                   list<dag> pattern = []>
1650     : I<oops, iops, asm, operands, "", pattern> {
1651   let Inst{31-22} = 0b1101010100;
1652   let Inst{21}    = L;
1655 // System instructions which do not have an Rt register.
1656 class SimpleSystemI<bit L, dag iops, string asm, string operands,
1657                     list<dag> pattern = []>
1658     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
1659   let Inst{4-0} = 0b11111;
1662 // System instructions which have an Rt register.
1663 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands,
1664                 list<dag> pattern = []>
1665     : BaseSystemI<L, oops, iops, asm, operands, pattern>,
1666       Sched<[WriteSys]> {
1667   bits<5> Rt;
1668   let Inst{4-0} = Rt;
1671 // System instructions for transactional memory extension
1672 class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops,
1673                     string asm, string operands, list<dag> pattern>
1674     : BaseSystemI<L, oops, iops, asm, operands, pattern>,
1675       Sched<[WriteSys]> {
1676   let Inst{20-12} = 0b000110011;
1677   let Inst{11-8} = CRm;
1678   let Inst{7-5} = op2;
1679   let DecoderMethod = "";
1681   let mayLoad = 1;
1682   let mayStore = 1;
1685 // System instructions for transactional memory - single input operand
1686 class TMSystemI<bits<4> CRm, string asm, list<dag> pattern>
1687     : TMBaseSystemI<0b1, CRm, 0b011,
1688                     (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> {
1689   bits<5> Rt;
1690   let Inst{4-0} = Rt;
1693 // System instructions that pass a register argument
1694 // This class assumes the register is for input rather than output.
1695 class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm,
1696                       list<dag> pattern = []>
1697     : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> {
1698   let Inst{20-12} = 0b000110001;
1699   let Inst{11-8} = CRm;
1700   let Inst{7-5} = Op2;
1703 // System instructions for transactional memory - no operand
1704 class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern>
1705     : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> {
1706   let Inst{4-0} = 0b11111;
1709 // System instructions for exit from transactions
1710 class TMSystemException<bits<3> op1, string asm, list<dag> pattern>
1711     : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>,
1712       Sched<[WriteSys]> {
1713   bits<16> imm;
1714   let Inst{31-24} = 0b11010100;
1715   let Inst{23-21} = op1;
1716   let Inst{20-5}  = imm;
1717   let Inst{4-0}   = 0b00000;
1720 // Hint instructions that take both a CRm and a 3-bit immediate.
1721 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
1722 // model patterns with sufficiently fine granularity
1723 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
1724   class HintI<string mnemonic>
1725       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
1726                       [(int_aarch64_hint imm0_127:$imm)]>,
1727         Sched<[WriteHint]> {
1728     bits <7> imm;
1729     let Inst{20-12} = 0b000110010;
1730     let Inst{11-5} = imm;
1731   }
1733 // System instructions taking a single literal operand which encodes into
1734 // CRm. op2 differentiates the opcodes.
1735 def BarrierAsmOperand : AsmOperandClass {
1736   let Name = "Barrier";
1737   let ParserMethod = "tryParseBarrierOperand";
1739 def barrier_op : Operand<i32> {
1740   let PrintMethod = "printBarrierOption";
1741   let ParserMatchClass = BarrierAsmOperand;
1743 def BarriernXSAsmOperand : AsmOperandClass {
1744   let Name = "BarriernXS";
1745   let ParserMethod = "tryParseBarriernXSOperand";
1747 def barrier_nxs_op : Operand<i32> {
1748   let PrintMethod = "printBarriernXSOption";
1749   let ParserMatchClass = BarriernXSAsmOperand;
1751 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
1752                  list<dag> pattern = []>
1753     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
1754       Sched<[WriteBarrier]> {
1755   bits<4> CRm;
1756   let Inst{20-12} = 0b000110011;
1757   let Inst{11-8} = CRm;
1758   let Inst{7-5} = opc;
1761 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
1762     : SimpleSystemI<0, (ins), asm, "", pattern>,
1763       Sched<[WriteHint]> {
1764   bits<4> CRm;
1765   let CRm = 0b0011;
1766   let Inst{31-12} = 0b11010101000000110010;
1767   let Inst{11-8} = CRm;
1768   let Inst{7-5} = op2;
1769   let Inst{4-0} = 0b11111;
1772 // MRS/MSR system instructions. These have different operand classes because
1773 // a different subset of registers can be accessed through each instruction.
1774 def MRSSystemRegisterOperand : AsmOperandClass {
1775   let Name = "MRSSystemRegister";
1776   let ParserMethod = "tryParseSysReg";
1777   let DiagnosticType = "MRS";
1779 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
1780 def mrs_sysreg_op : Operand<i32> {
1781   let ParserMatchClass = MRSSystemRegisterOperand;
1782   let DecoderMethod = "DecodeMRSSystemRegister";
1783   let PrintMethod = "printMRSSystemRegister";
1786 def MSRSystemRegisterOperand : AsmOperandClass {
1787   let Name = "MSRSystemRegister";
1788   let ParserMethod = "tryParseSysReg";
1789   let DiagnosticType = "MSR";
1791 def msr_sysreg_op : Operand<i32> {
1792   let ParserMatchClass = MSRSystemRegisterOperand;
1793   let DecoderMethod = "DecodeMSRSystemRegister";
1794   let PrintMethod = "printMSRSystemRegister";
1797 def PSBHintOperand : AsmOperandClass {
1798   let Name = "PSBHint";
1799   let ParserMethod = "tryParsePSBHint";
1801 def psbhint_op : Operand<i32> {
1802   let ParserMatchClass = PSBHintOperand;
1803   let PrintMethod = "printPSBHintOp";
1804   let MCOperandPredicate = [{
1805     // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
1806     // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
1807     if (!MCOp.isImm())
1808       return false;
1809     return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
1810   }];
1813 def BTIHintOperand : AsmOperandClass {
1814   let Name = "BTIHint";
1815   let ParserMethod = "tryParseBTIHint";
1817 def btihint_op : Operand<i32> {
1818   let ParserMatchClass = BTIHintOperand;
1819   let PrintMethod = "printBTIHintOp";
1820   let MCOperandPredicate = [{
1821     // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.
1822     if (!MCOp.isImm())
1823       return false;
1824     return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr;
1825   }];
1828 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
1829                        "mrs", "\t$Rt, $systemreg"> {
1830   bits<16> systemreg;
1831   let Inst{20-5} = systemreg;
1832   let DecoderNamespace = "Fallback";
1833   // The MRS is set as a NZCV setting instruction. Not all MRS instructions
1834   // require doing this. The alternative was to explicitly model each one, but
1835   // it feels like it is unnecessary because it seems there are no negative
1836   // consequences setting these flags for all.
1837   let Defs = [NZCV];
1840 // FIXME: Some of these def NZCV, others don't. Best way to model that?
1841 // Explicitly modeling each of the system register as a register class
1842 // would do it, but feels like overkill at this point.
1843 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
1844                        "msr", "\t$systemreg, $Rt"> {
1845   bits<16> systemreg;
1846   let Inst{20-5} = systemreg;
1847   let DecoderNamespace = "Fallback";
1850 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
1851   let Name = "SystemPStateFieldWithImm0_15";
1852   let ParserMethod = "tryParseSysReg";
1854 def pstatefield4_op : Operand<i32> {
1855   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
1856   let PrintMethod = "printSystemPStateField";
1857   let MCOperandPredicate = [{
1858     if (!MCOp.isImm())
1859       return false;
1860     return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr;
1861   }];
1864 // Instructions to modify PSTATE, no input reg
1865 let Defs = [NZCV] in
1866 class PstateWriteSimple<dag iops, string asm, string operands>
1867   : SimpleSystemI<0, iops, asm, operands> {
1869   let Inst{20-19} = 0b00;
1870   let Inst{15-12} = 0b0100;
1873 class MSRpstateImm0_15
1874   : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr",
1875                   "\t$pstatefield, $imm">,
1876     Sched<[WriteSys]> {
1878   bits<6> pstatefield;
1879   bits<4> imm;
1880   let Inst{18-16} = pstatefield{5-3};
1881   let Inst{11-8} = imm;
1882   let Inst{7-5} = pstatefield{2-0};
1884   let DecoderMethod = "DecodeSystemPStateImm0_15Instruction";
1885   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1886   // Fail the decoder should attempt to decode the instruction as MSRI.
1887   let hasCompleteDecoder = false;
1890 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1891   let Name = "SystemPStateFieldWithImm0_1";
1892   let ParserMethod = "tryParseSysReg";
1894 def pstatefield1_op : Operand<i32> {
1895   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1896   let PrintMethod = "printSystemPStateField";
1897   let MCOperandPredicate = [{
1898     if (!MCOp.isImm())
1899       return false;
1900     return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr;
1901   }];
1904 class MSRpstateImm0_1
1905   : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",
1906                  "\t$pstatefield, $imm">,
1907     Sched<[WriteSys]> {
1909   bits<9> pstatefield;
1910   bit imm;
1911   let Inst{18-16} = pstatefield{5-3};
1912   let Inst{11-9} = pstatefield{8-6};
1913   let Inst{8} = imm;
1914   let Inst{7-5} = pstatefield{2-0};
1916   let DecoderMethod = "DecodeSystemPStateImm0_1Instruction";
1917   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1918   // Fail the decoder should attempt to decode the instruction as MSRI.
1919   let hasCompleteDecoder = false;
1920   let DecoderNamespace = "Fallback";
1923 // SYS and SYSL generic system instructions.
1924 def SysCRAsmOperand : AsmOperandClass {
1925   let Name = "SysCR";
1926   let ParserMethod = "tryParseSysCROperand";
1929 def sys_cr_op : Operand<i32> {
1930   let PrintMethod = "printSysCROperand";
1931   let ParserMatchClass = SysCRAsmOperand;
1934 class SystemXtI<bit L, string asm>
1935   : RtSystemI<L, (outs),
1936        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1937        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1938   bits<3> op1;
1939   bits<4> Cn;
1940   bits<4> Cm;
1941   bits<3> op2;
1942   let Inst{20-19} = 0b01;
1943   let Inst{18-16} = op1;
1944   let Inst{15-12} = Cn;
1945   let Inst{11-8}  = Cm;
1946   let Inst{7-5}   = op2;
1949 class SystemLXtI<bit L, string asm>
1950   : RtSystemI<L, (outs),
1951        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1952        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1953   bits<3> op1;
1954   bits<4> Cn;
1955   bits<4> Cm;
1956   bits<3> op2;
1957   let Inst{20-19} = 0b01;
1958   let Inst{18-16} = op1;
1959   let Inst{15-12} = Cn;
1960   let Inst{11-8}  = Cm;
1961   let Inst{7-5}   = op2;
1964 def RangePrefetchOperand : AsmOperandClass {
1965   let Name = "RangePrefetch";
1966   let ParserMethod = "tryParseRPRFMOperand";
1967   let PredicateMethod = "isPrefetch";
1968   let RenderMethod = "addPrefetchOperands";
1971 def rprfop : Operand<i32>, TImmLeaf<i32, [{
1972     return (((uint32_t)Imm) <= 63);
1973   }]> {
1974   let PrintMethod = "printRPRFMOperand";
1975   let ParserMatchClass = RangePrefetchOperand;
1978 // Branch (register) instructions:
1980 //  case opc of
1981 //    0001 blr
1982 //    0000 br
1983 //    0101 dret
1984 //    0100 eret
1985 //    0010 ret
1986 //    otherwise UNDEFINED
1987 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1988                     string operands, list<dag> pattern>
1989     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1990   let Inst{31-25} = 0b1101011;
1991   let Inst{24-21} = opc;
1992   let Inst{20-16} = 0b11111;
1993   let Inst{15-10} = 0b000000;
1994   let Inst{4-0}   = 0b00000;
1997 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1998     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1999   bits<5> Rn;
2000   let Inst{9-5} = Rn;
2003 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
2004 class SpecialReturn<bits<4> opc, string asm>
2005     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
2006   let Inst{9-5} = 0b11111;
2009 let mayLoad = 1 in
2010 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
2011   : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
2012   Sched<[]> {
2013   bits<5> Rn;
2014   bits<5> Rt;
2015   let Inst{31-30} = sz;
2016   let Inst{29-10} = 0b11100010111111110000;
2017   let Inst{9-5} = Rn;
2018   let Inst{4-0} = Rt;
2021 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
2022                list<dag> pattern>
2023   : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
2024   let isAuthenticated = 1;
2025   let Inst{31-25} = 0b1101011;
2026   let Inst{20-11} = 0b1111100001;
2027   let Inst{10} = M;
2028   let Inst{4-0} = 0b11111;
2031 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
2032   : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
2033   bits<5> Rn;
2034   bits<5> Rm;
2035   let Inst{24-22} = 0b100;
2036   let Inst{21} = op;
2037   let Inst{9-5} = Rn;
2038   let Inst{4-0} = Rm;
2041 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
2042   : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
2043   bits<5> Rn;
2044   let Inst{24} = 0;
2045   let Inst{23-21} = opc;
2046   let Inst{9-5} = Rn;
2049 let Uses = [LR,SP] in
2050 class AuthReturn<bits<3> op, bits<1> M, string asm>
2051   : AuthBase<M, (outs), (ins), asm, "", []> {
2052   let Inst{24} = 0;
2053   let Inst{23-21} = op;
2054   let Inst{9-0} = 0b1111111111;
2057 let mayLoad = 1 in
2058 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
2059                    string operands, string cstr>
2060   : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
2061   bits<10> offset;
2062   bits<5> Rn;
2063   bits<5> Rt;
2064   let isAuthenticated = 1;
2065   let Inst{31-24} = 0b11111000;
2066   let Inst{23} = M;
2067   let Inst{22} = offset{9};
2068   let Inst{21} = 1;
2069   let Inst{20-12} = offset{8-0};
2070   let Inst{11} = W;
2071   let Inst{10} = 1;
2072   let Inst{9-5} = Rn;
2073   let Inst{4-0} = Rt;
2075   let DecoderMethod = "DecodeAuthLoadInstruction";
2078 multiclass AuthLoad<bit M, string asm, Operand opr> {
2079   def indexed   : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
2080                                (ins GPR64sp:$Rn, opr:$offset),
2081                                asm, "\t$Rt, [$Rn, $offset]", "">;
2082   def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
2083                                (ins GPR64sp:$Rn, opr:$offset),
2084                                asm, "\t$Rt, [$Rn, $offset]!",
2085                                "$Rn = $wback,@earlyclobber $wback">;
2087   def : InstAlias<asm # "\t$Rt, [$Rn]",
2088                   (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
2090   def : InstAlias<asm # "\t$Rt, [$wback]!",
2091                   (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>;
2094 //---
2095 // Conditional branch instruction.
2096 //---
2098 // Condition code.
2099 // 4-bit immediate. Pretty-printed as <cc>
2100 def ccode : Operand<i32> {
2101   let PrintMethod = "printCondCode";
2102   let ParserMatchClass = CondCode;
2104 def inv_ccode : Operand<i32> {
2105   // AL and NV are invalid in the aliases which use inv_ccode
2106   let PrintMethod = "printInverseCondCode";
2107   let ParserMatchClass = CondCode;
2108   let MCOperandPredicate = [{
2109     return MCOp.isImm() &&
2110            MCOp.getImm() != AArch64CC::AL &&
2111            MCOp.getImm() != AArch64CC::NV;
2112   }];
2115 // Conditional branch target. 19-bit immediate. The low two bits of the target
2116 // offset are implied zero and so are not part of the immediate.
2117 def am_brcond : Operand<OtherVT> {
2118   let EncoderMethod = "getCondBranchTargetOpValue";
2119   let DecoderMethod = "DecodePCRelLabel19";
2120   let PrintMethod = "printAlignedLabel";
2121   let ParserMatchClass = PCRelLabel19Operand;
2122   let OperandType = "OPERAND_PCREL";
2125 class BranchCond<bit bit4, string mnemonic>
2126    : I<(outs), (ins ccode:$cond, am_brcond:$target),
2127        mnemonic, ".$cond\t$target", "",
2128        [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> {
2129   let isBranch = 1;
2130   let isTerminator = 1;
2131   let Uses = [NZCV];
2133   bits<4> cond;
2134   bits<19> target;
2135   let Inst{31-24} = 0b01010100;
2136   let Inst{23-5} = target;
2137   let Inst{4} = bit4;
2138   let Inst{3-0} = cond;
2141 //---
2142 // Compare-and-branch instructions.
2143 //---
2144 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
2145     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
2146          asm, "\t$Rt, $target", "",
2147          [(node regtype:$Rt, bb:$target)]>,
2148       Sched<[WriteBr]> {
2149   let isBranch = 1;
2150   let isTerminator = 1;
2152   bits<5> Rt;
2153   bits<19> target;
2154   let Inst{30-25} = 0b011010;
2155   let Inst{24}    = op;
2156   let Inst{23-5}  = target;
2157   let Inst{4-0}   = Rt;
2160 multiclass CmpBranch<bit op, string asm, SDNode node> {
2161   def W : BaseCmpBranch<GPR32, op, asm, node> {
2162     let Inst{31} = 0;
2163   }
2164   def X : BaseCmpBranch<GPR64, op, asm, node> {
2165     let Inst{31} = 1;
2166   }
2169 //---
2170 // Test-bit-and-branch instructions.
2171 //---
2172 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
2173 // the target offset are implied zero and so are not part of the immediate.
2174 def am_tbrcond : Operand<OtherVT> {
2175   let EncoderMethod = "getTestBranchTargetOpValue";
2176   let PrintMethod = "printAlignedLabel";
2177   let ParserMatchClass = BranchTarget14Operand;
2178   let OperandType = "OPERAND_PCREL";
2181 // AsmOperand classes to emit (or not) special diagnostics
2182 def TBZImm0_31Operand : AsmOperandClass {
2183   let Name = "TBZImm0_31";
2184   let PredicateMethod = "isImmInRange<0,31>";
2185   let RenderMethod = "addImmOperands";
2187 def TBZImm32_63Operand : AsmOperandClass {
2188   let Name = "Imm32_63";
2189   let PredicateMethod = "isImmInRange<32,63>";
2190   let DiagnosticType = "InvalidImm0_63";
2191   let RenderMethod = "addImmOperands";
2194 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
2195   return (((uint32_t)Imm) < 32);
2196 }]> {
2197   let ParserMatchClass = matcher;
2200 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
2201 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
2203 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
2204   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
2205 }]> {
2206   let ParserMatchClass = TBZImm32_63Operand;
2209 class BaseTestBranch<RegisterClass regtype, Operand immtype,
2210                      bit op, string asm, SDNode node>
2211     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
2212        asm, "\t$Rt, $bit_off, $target", "",
2213        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
2214       Sched<[WriteBr]> {
2215   let isBranch = 1;
2216   let isTerminator = 1;
2218   bits<5> Rt;
2219   bits<6> bit_off;
2220   bits<14> target;
2222   let Inst{30-25} = 0b011011;
2223   let Inst{24}    = op;
2224   let Inst{23-19} = bit_off{4-0};
2225   let Inst{18-5}  = target;
2226   let Inst{4-0}   = Rt;
2228   let DecoderMethod = "DecodeTestAndBranch";
2231 multiclass TestBranch<bit op, string asm, SDNode node> {
2232   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
2233     let Inst{31} = 0;
2234   }
2236   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
2237     let Inst{31} = 1;
2238   }
2240   // Alias X-reg with 0-31 imm to W-Reg.
2241   def : InstAlias<asm # "\t$Rd, $imm, $target",
2242                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
2243                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
2244   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
2245             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
2246             tbz_imm0_31_diag:$imm, bb:$target)>;
2249 //---
2250 // Unconditional branch (immediate) instructions.
2251 //---
2252 def am_b_target : Operand<OtherVT> {
2253   let EncoderMethod = "getBranchTargetOpValue";
2254   let PrintMethod = "printAlignedLabel";
2255   let ParserMatchClass = BranchTarget26Operand;
2256   let OperandType = "OPERAND_PCREL";
2258 def am_bl_target : Operand<i64> {
2259   let EncoderMethod = "getBranchTargetOpValue";
2260   let PrintMethod = "printAlignedLabel";
2261   let ParserMatchClass = BranchTarget26Operand;
2262   let OperandType = "OPERAND_PCREL";
2265 class BImm<bit op, dag iops, string asm, list<dag> pattern>
2266     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
2267   bits<26> addr;
2268   let Inst{31}    = op;
2269   let Inst{30-26} = 0b00101;
2270   let Inst{25-0}  = addr;
2272   let DecoderMethod = "DecodeUnconditionalBranch";
2275 class BranchImm<bit op, string asm, list<dag> pattern>
2276     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
2277 class CallImm<bit op, string asm, list<dag> pattern>
2278     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
2280 //---
2281 // Basic one-operand data processing instructions.
2282 //---
2284 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2285 class BaseOneOperandData<bit sf, bit S, bits<5> opc2, bits<6> opc,
2286                          RegisterClass regtype, string asm,
2287                          SDPatternOperator node>
2288   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
2289       [(set regtype:$Rd, (node regtype:$Rn))]>,
2290     Sched<[WriteI, ReadI]> {
2291   bits<5> Rd;
2292   bits<5> Rn;
2294   let Inst{31} = sf;
2295   let Inst{30} = 0b1;
2296   let Inst{29} = S;
2297   let Inst{28-21} = 0b11010110;
2298   let Inst{20-16} = opc2;
2299   let Inst{15-10} = opc;
2300   let Inst{9-5}   = Rn;
2301   let Inst{4-0}   = Rd;
2304 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2305 multiclass OneOperandData<bits<6> opc, string asm,
2306                           SDPatternOperator node = null_frag> {
2307   def Wr : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>;
2309   def Xr : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>;
2312 class OneWRegData<bits<6> opc, string asm, SDPatternOperator node>
2313     : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>;
2315 class OneXRegData<bits<6> opc, string asm, SDPatternOperator node>
2316     : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>;
2318 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm,
2319                       SDPatternOperator op>
2320   : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn",
2321       "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>,
2322     Sched<[WriteI, ReadI]> {
2323   bits<5> Rd;
2324   bits<5> Rn;
2325   let Inst{31-15} = 0b11011010110000010;
2326   let Inst{14-12} = opcode_prefix;
2327   let Inst{11-10} = opcode;
2328   let Inst{9-5} = Rn;
2329   let Inst{4-0} = Rd;
2332 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm,
2333                    SDPatternOperator op>
2334   : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd",
2335       [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>,
2336     Sched<[]> {
2337   bits<5> Rd;
2338   let Inst{31-15} = 0b11011010110000010;
2339   let Inst{14-12} = opcode_prefix;
2340   let Inst{11-10} = opcode;
2341   let Inst{9-5} = 0b11111;
2342   let Inst{4-0} = Rd;
2345 class SignAuthTwoOperand<bits<4> opc, string asm,
2346                          SDPatternOperator OpNode>
2347   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
2348       asm, "\t$Rd, $Rn, $Rm", "",
2349       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
2350     Sched<[WriteI, ReadI, ReadI]> {
2351   bits<5> Rd;
2352   bits<5> Rn;
2353   bits<5> Rm;
2354   let Inst{31-21} = 0b10011010110;
2355   let Inst{20-16} = Rm;
2356   let Inst{15-14} = 0b00;
2357   let Inst{13-10} = opc;
2358   let Inst{9-5}   = Rn;
2359   let Inst{4-0}   = Rd;
2362 class ClearAuth<bits<1> data, string asm>
2363   : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> {
2364   bits<5> Rd;
2365   let Inst{31-11} = 0b110110101100000101000;
2366   let Inst{10} = data;
2367   let Inst{9-5} = 0b11111;
2368   let Inst{4-0} = Rd;
2371 // v9.5-A FEAT_PAuth_LR
2373 class SignAuthFixedRegs<bits<5> opcode2, bits<6> opcode, string asm>
2374   : I<(outs), (ins), asm, "", "", []>,
2375     Sched<[WriteI, ReadI]> {
2376   let Inst{31} = 0b1; // sf
2377   let Inst{30} = 0b1;
2378   let Inst{29} = 0b0; // S
2379   let Inst{28-21} = 0b11010110;
2380   let Inst{20-16} = opcode2;
2381   let Inst{15-10} = opcode;
2382   let Inst{9-5} = 0b11111; // Rn
2383   let Inst{4-0} = 0b11110; // Rd
2386 def PAuthPCRelLabel16Operand : PCRelLabel<16> {
2387   let Name = "PAuthPCRelLabel16";
2388   let PredicateMethod = "isPAuthPCRelLabel16Operand";
2390 def am_pauth_pcrel : Operand<OtherVT> {
2391   let EncoderMethod = "getPAuthPCRelOpValue";
2392   let DecoderMethod = "DecodePCRelLabel16";
2393   let PrintMethod = "printAlignedLabel";
2394   let ParserMatchClass = PAuthPCRelLabel16Operand;
2395   let OperandType = "OPERAND_PCREL";
2398 class SignAuthPCRel<bits<2> opc, string asm>
2399   : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>,
2400     Sched<[]> {
2401   bits<16> label;
2402   let Inst{31} = 0b1; // sf
2403   let Inst{30-23} = 0b11100111;
2404   let Inst{22-21} = opc;
2405   let Inst{20-5} = label; // imm
2406   let Inst{4-0} = 0b11111; // Rd
2409 class SignAuthOneReg<bits<5> opcode2, bits<6> opcode, string asm>
2410   : I<(outs), (ins GPR64:$Rn), asm, "\t$Rn", "", []>,
2411     Sched<[]> {
2412   bits<5> Rn;
2413   let Inst{31} = 0b1; // sf
2414   let Inst{30} = 0b1;
2415   let Inst{29} = 0b0; // S
2416   let Inst{28-21} = 0b11010110;
2417   let Inst{20-16} = opcode2;
2418   let Inst{15-10} = opcode;
2419   let Inst{9-5} = Rn;
2420   let Inst{4-0} = 0b11110; // Rd
2423 class SignAuthReturnPCRel<bits<3> opc, bits<5> op2, string asm>
2424   : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>,
2425     Sched<[WriteAtomic]> {
2426   bits<16> label;
2427   let Inst{31-24} = 0b01010101;
2428   let Inst{23-21} = opc;
2429   let Inst{20-5} = label; // imm16
2430   let Inst{4-0} = op2;
2433 class SignAuthReturnReg<bits<6> op3, string asm>
2434   : I<(outs), (ins GPR64common:$Rm), asm, "\t$Rm", "", []>,
2435     Sched<[WriteAtomic]> {
2436   bits<5> Rm;
2437   let Inst{31-25} = 0b1101011;
2438   let Inst{24-21} = 0b0010; // opc
2439   let Inst{20-16} = 0b11111; // op2
2440   let Inst{15-10} = op3;
2441   let Inst{9-5} = 0b11111; // Rn
2442   let Inst{4-0} = Rm; // op4 (Rm)
2445 // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
2446 class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
2447     : I<(outs), iops, asm, ops, "", []>,
2448       Sched<[WriteI, ReadI, ReadI]> {
2449   let Uses = [NZCV];
2450   let Defs = [NZCV];
2451   bits<5> Rn;
2452   let Inst{31}    = sf;
2453   let Inst{30-15} = 0b0111010000000000;
2454   let Inst{14}    = sz;
2455   let Inst{13-10} = 0b0010;
2456   let Inst{9-5}   = Rn;
2457   let Inst{4-0}   = 0b01101;
2460 class FlagRotate<dag iops, string asm, string ops>
2461     : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
2462   bits<6> imm;
2463   bits<4> mask;
2464   let Inst{20-15} = imm;
2465   let Inst{13-10} = 0b0001;
2466   let Inst{4}     = 0b0;
2467   let Inst{3-0}   = mask;
2470 //---
2471 // Basic two-operand data processing instructions.
2472 //---
2473 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
2474                           list<dag> pattern>
2475     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2476         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2477       Sched<[WriteI, ReadI, ReadI]> {
2478   let Uses = [NZCV];
2479   bits<5> Rd;
2480   bits<5> Rn;
2481   bits<5> Rm;
2482   let Inst{30}    = isSub;
2483   let Inst{28-21} = 0b11010000;
2484   let Inst{20-16} = Rm;
2485   let Inst{15-10} = 0;
2486   let Inst{9-5}   = Rn;
2487   let Inst{4-0}   = Rd;
2490 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
2491                       SDNode OpNode>
2492     : BaseBaseAddSubCarry<isSub, regtype, asm,
2493         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
2495 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
2496                               SDNode OpNode>
2497     : BaseBaseAddSubCarry<isSub, regtype, asm,
2498         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
2499          (implicit NZCV)]> {
2500   let Defs = [NZCV];
2503 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
2504                        SDNode OpNode, SDNode OpNode_setflags> {
2505   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
2506     let Inst{31} = 0;
2507     let Inst{29} = 0;
2508   }
2509   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
2510     let Inst{31} = 1;
2511     let Inst{29} = 0;
2512   }
2514   // Sets flags.
2515   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
2516                                     OpNode_setflags> {
2517     let Inst{31} = 0;
2518     let Inst{29} = 1;
2519   }
2520   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
2521                                     OpNode_setflags> {
2522     let Inst{31} = 1;
2523     let Inst{29} = 1;
2524   }
2527 class BaseTwoOperandRegReg<bit sf, bit S, bits<6> opc, RegisterClass regtype,
2528                            string asm, SDPatternOperator OpNode,
2529                            RegisterClass in1regtype = regtype,
2530                            RegisterClass in2regtype = regtype>
2531   : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm),
2532       asm, "\t$Rd, $Rn, $Rm", "",
2533       [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> {
2534   bits<5> Rd;
2535   bits<5> Rn;
2536   bits<5> Rm;
2537   let Inst{31}    = sf;
2538   let Inst{30}    = 0b0;
2539   let Inst{29}    = S;
2540   let Inst{28-21} = 0b11010110;
2541   let Inst{20-16} = Rm;
2542   let Inst{15-10} = opc;
2543   let Inst{9-5}   = Rn;
2544   let Inst{4-0}   = Rd;
2547 class BaseDiv<bit size, bit isSigned, RegisterClass regtype, string asm,
2548               SDPatternOperator OpNode>
2549     : BaseTwoOperandRegReg<size, 0b0, {0,0,0,0,1,?}, regtype, asm, OpNode> {
2550   let Inst{10}    = isSigned;
2553 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
2554   def Wr : BaseDiv<0b0, isSigned, GPR32, asm, OpNode>,
2555            Sched<[WriteID32, ReadID, ReadID]>;
2557   def Xr : BaseDiv<0b1, isSigned, GPR64, asm, OpNode>,
2558            Sched<[WriteID64, ReadID, ReadID]>;
2561 class BaseShift<bit size, bits<2> shift_type, RegisterClass regtype, string asm,
2562                 SDPatternOperator OpNode = null_frag>
2563   : BaseTwoOperandRegReg<size, 0b0, {0,0,1,0,?,?}, regtype, asm, OpNode>,
2564     Sched<[WriteIS, ReadI]> {
2565   let Inst{11-10} = shift_type;
2568 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
2569   def Wr : BaseShift<0b0, shift_type, GPR32, asm>;
2571   def Xr : BaseShift<0b1, shift_type, GPR64, asm, OpNode>;
2573   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
2574             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
2575                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
2577   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
2578             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2580   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
2581             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2583   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
2584             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2586   def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))),
2587             (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2588                 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2590   def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))),
2591             (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2592                 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2595 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
2596     : InstAlias<asm#"\t$dst, $src1, $src2",
2597                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
2599 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
2600                        RegisterClass addtype, string asm,
2601                        list<dag> pattern>
2602   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
2603       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
2604   bits<5> Rd;
2605   bits<5> Rn;
2606   bits<5> Rm;
2607   bits<5> Ra;
2608   let Inst{30-24} = 0b0011011;
2609   let Inst{23-21} = opc;
2610   let Inst{20-16} = Rm;
2611   let Inst{15}    = isSub;
2612   let Inst{14-10} = Ra;
2613   let Inst{9-5}   = Rn;
2614   let Inst{4-0}   = Rd;
2617 multiclass MulAccum<bit isSub, string asm> {
2618   // MADD/MSUB generation is decided by MachineCombiner.cpp
2619   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>,
2620       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2621     let Inst{31} = 0;
2622   }
2624   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>,
2625       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
2626     let Inst{31} = 1;
2627   }
2630 class WideMulAccum<bit isSub, bits<3> opc, string asm,
2631                    SDNode AccNode, SDNode ExtNode>
2632   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
2633     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
2634                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
2635     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2636   let Inst{31} = 1;
2639 class MulHi<bits<3> opc, string asm, SDNode OpNode>
2640   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
2641       asm, "\t$Rd, $Rn, $Rm", "",
2642       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
2643     Sched<[WriteIM64, ReadIM, ReadIM]> {
2644   bits<5> Rd;
2645   bits<5> Rn;
2646   bits<5> Rm;
2647   let Inst{31-24} = 0b10011011;
2648   let Inst{23-21} = opc;
2649   let Inst{20-16} = Rm;
2650   let Inst{15}    = 0;
2651   let Inst{9-5}   = Rn;
2652   let Inst{4-0}   = Rd;
2654   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
2655   // (i.e. all bits 1) but is ignored by the processor.
2656   let PostEncoderMethod = "fixMulHigh";
2659 class MulAccumWAlias<string asm, Instruction inst>
2660     : InstAlias<asm#"\t$dst, $src1, $src2",
2661                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
2662 class MulAccumXAlias<string asm, Instruction inst>
2663     : InstAlias<asm#"\t$dst, $src1, $src2",
2664                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
2665 class WideMulAccumAlias<string asm, Instruction inst>
2666     : InstAlias<asm#"\t$dst, $src1, $src2",
2667                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
2669 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
2670               SDPatternOperator OpNode, string asm>
2671   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
2672       asm, "\t$Rd, $Rn, $Rm", "",
2673       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
2674     Sched<[WriteISReg, ReadI, ReadISReg]> {
2675   bits<5> Rd;
2676   bits<5> Rn;
2677   bits<5> Rm;
2679   let Inst{31} = sf;
2680   let Inst{30-21} = 0b0011010110;
2681   let Inst{20-16} = Rm;
2682   let Inst{15-13} = 0b010;
2683   let Inst{12} = C;
2684   let Inst{11-10} = sz;
2685   let Inst{9-5} = Rn;
2686   let Inst{4-0} = Rd;
2687   let Predicates = [HasCRC];
2690 //---
2691 // Address generation.
2692 //---
2694 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
2695     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
2696         pattern>,
2697       Sched<[WriteI]> {
2698   bits<5>  Xd;
2699   bits<21> label;
2700   let Inst{31}    = page;
2701   let Inst{30-29} = label{1-0};
2702   let Inst{28-24} = 0b10000;
2703   let Inst{23-5}  = label{20-2};
2704   let Inst{4-0}   = Xd;
2706   let DecoderMethod = "DecodeAdrInstruction";
2709 //---
2710 // Move immediate.
2711 //---
2713 def movimm32_imm : Operand<i32> {
2714   let ParserMatchClass = AsmImmRange<0, 65535>;
2715   let EncoderMethod = "getMoveWideImmOpValue";
2716   let PrintMethod = "printImm";
2718 def movimm32_shift : Operand<i32> {
2719   let PrintMethod = "printShifter";
2720   let ParserMatchClass = MovImm32ShifterOperand;
2722 def movimm64_shift : Operand<i32> {
2723   let PrintMethod = "printShifter";
2724   let ParserMatchClass = MovImm64ShifterOperand;
2727 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2728 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2729                         string asm>
2730   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
2731        asm, "\t$Rd, $imm$shift", "", []>,
2732     Sched<[WriteImm]> {
2733   bits<5> Rd;
2734   bits<16> imm;
2735   bits<6> shift;
2736   let Inst{30-29} = opc;
2737   let Inst{28-23} = 0b100101;
2738   let Inst{22-21} = shift{5-4};
2739   let Inst{20-5}  = imm;
2740   let Inst{4-0}   = Rd;
2742   let DecoderMethod = "DecodeMoveImmInstruction";
2745 multiclass MoveImmediate<bits<2> opc, string asm> {
2746   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
2747     let Inst{31} = 0;
2748   }
2750   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
2751     let Inst{31} = 1;
2752   }
2755 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2756 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2757                           string asm>
2758   : I<(outs regtype:$Rd),
2759       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
2760        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
2761     Sched<[WriteI, ReadI]> {
2762   bits<5> Rd;
2763   bits<16> imm;
2764   bits<6> shift;
2765   let Inst{30-29} = opc;
2766   let Inst{28-23} = 0b100101;
2767   let Inst{22-21} = shift{5-4};
2768   let Inst{20-5}  = imm;
2769   let Inst{4-0}   = Rd;
2771   let DecoderMethod = "DecodeMoveImmInstruction";
2774 multiclass InsertImmediate<bits<2> opc, string asm> {
2775   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
2776     let Inst{31} = 0;
2777   }
2779   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
2780     let Inst{31} = 1;
2781   }
2784 //---
2785 // Add/Subtract
2786 //---
2788 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
2789                     string asm_inst, string asm_ops,
2790                     dag inputs, dag pattern>
2791     : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>,
2792       Sched<[WriteI, ReadI]> {
2793   bits<5>  Rd;
2794   bits<5>  Rn;
2795   let Inst{30}    = isSub;
2796   let Inst{29}    = setFlags;
2797   let Inst{28-24} = 0b10001;
2798   let Inst{9-5}   = Rn;
2799   let Inst{4-0}   = Rd;
2802 class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype,
2803                      RegisterClass srcRegtype, addsub_shifted_imm immtype,
2804                      string asm_inst, SDPatternOperator OpNode>
2805     : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm",
2806                     (ins srcRegtype:$Rn, immtype:$imm),
2807                     (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> {
2808   bits<14> imm;
2809   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
2810   let Inst{21-10} = imm{11-0};
2811   let DecoderMethod = "DecodeAddSubImmShift";
2812   let hasPostISelHook = 1;
2815 class BaseAddSubRegPseudo<RegisterClass regtype,
2816                           SDPatternOperator OpNode>
2817     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2818              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2819       Sched<[WriteI, ReadI, ReadI]>;
2821 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
2822                      arith_shifted_reg shifted_regtype, string asm,
2823                      SDPatternOperator OpNode>
2824     : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift),
2825         asm, "\t$Rd, $Rn, $Rm_and_shift", "",
2826         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>,
2827       Sched<[WriteISReg, ReadI, ReadISReg]> {
2828   bits<5> Rd;
2829   bits<5> Rn;
2830   bits<5> Rm;
2831   bits<8> shift;
2832   let Inst{30}    = isSub;
2833   let Inst{29}    = setFlags;
2834   let Inst{28-24} = 0b01011;
2835   let Inst{23-22} = shift{7-6};
2836   let Inst{21}    = 0;
2837   let Inst{20-16} = Rm;
2838   let Inst{15-10} = shift{5-0};
2839   let Inst{9-5}   = Rn;
2840   let Inst{4-0}   = Rd;
2842   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2845 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
2846                      RegisterClass src1Regtype, Operand src2Regtype,
2847                      string asm, SDPatternOperator OpNode>
2848     : I<(outs dstRegtype:$Rd),
2849         (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend),
2850         asm, "\t$Rd, $Rn, $Rm_and_extend", "",
2851         [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>,
2852       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2853   bits<5> Rd;
2854   bits<5> Rn;
2855   bits<5> Rm;
2856   bits<6> extend;
2857   let Inst{30}    = isSub;
2858   let Inst{29}    = setFlags;
2859   let Inst{28-24} = 0b01011;
2860   let Inst{23-21} = 0b001;
2861   let Inst{20-16} = Rm;
2862   let Inst{15-13} = extend{5-3};
2863   let Inst{12-10} = extend{2-0};
2864   let Inst{9-5}   = Rn;
2865   let Inst{4-0}   = Rd;
2867   let DecoderMethod = "DecodeAddSubERegInstruction";
2870 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2871 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
2872                        RegisterClass src1Regtype, RegisterClass src2Regtype,
2873                        Operand ext_op, string asm>
2874     : I<(outs dstRegtype:$Rd),
2875         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
2876         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
2877       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2878   bits<5> Rd;
2879   bits<5> Rn;
2880   bits<5> Rm;
2881   bits<6> ext;
2882   let Inst{30}    = isSub;
2883   let Inst{29}    = setFlags;
2884   let Inst{28-24} = 0b01011;
2885   let Inst{23-21} = 0b001;
2886   let Inst{20-16} = Rm;
2887   let Inst{15}    = ext{5};
2888   let Inst{12-10} = ext{2-0};
2889   let Inst{9-5}   = Rn;
2890   let Inst{4-0}   = Rd;
2892   let DecoderMethod = "DecodeAddSubERegInstruction";
2895 // Aliases for register+register add/subtract.
2896 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
2897                      RegisterClass src1Regtype, RegisterClass src2Regtype,
2898                      int shiftExt>
2899     : InstAlias<asm#"\t$dst, $src1, $src2",
2900                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
2901                       shiftExt)>;
2903 multiclass AddSub<bit isSub, string mnemonic, string alias,
2904                   SDPatternOperator OpNode = null_frag> {
2905   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2906   // Add/Subtract immediate
2907   // Increase the weight of the immediate variant to try to match it before
2908   // the extended register variant.
2909   // We used to match the register variant before the immediate when the
2910   // register argument could be implicitly zero-extended.
2911   let AddedComplexity = 6 in
2912   def Wri  : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
2913                            mnemonic, OpNode> {
2914     let Inst{31} = 0;
2915   }
2916   let AddedComplexity = 6 in
2917   def Xri  : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
2918                            mnemonic, OpNode> {
2919     let Inst{31} = 1;
2920   }
2922   // Add/Subtract register - Only used for CodeGen
2923   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2924   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2926   // Add/Subtract shifted register
2927   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
2928                            OpNode> {
2929     let Inst{31} = 0;
2930   }
2931   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
2932                            OpNode> {
2933     let Inst{31} = 1;
2934   }
2935   }
2937   // Add/Subtract extended register
2938   let AddedComplexity = 1, hasSideEffects = 0 in {
2939   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
2940                            arith_extended_reg32_i32, mnemonic, OpNode> {
2941     let Inst{31} = 0;
2942   }
2943   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
2944                            arith_extended_reg32to64_i64, mnemonic, OpNode> {
2945     let Inst{31} = 1;
2946   }
2947   }
2949   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
2950                                arith_extendlsl64, mnemonic> {
2951     // UXTX and SXTX only.
2952     let Inst{14-13} = 0b11;
2953     let Inst{31} = 1;
2954   }
2956   // add Rd, Rb, -imm -> sub Rd, Rn, imm
2957   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2958                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
2959                       addsub_shifted_imm32_neg:$imm), 0>;
2960   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2961                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
2962                        addsub_shifted_imm64_neg:$imm), 0>;
2964   // Register/register aliases with no shift when SP is not used.
2965   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2966                        GPR32, GPR32, GPR32, 0>;
2967   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2968                        GPR64, GPR64, GPR64, 0>;
2970   // Register/register aliases with no shift when either the destination or
2971   // first source register is SP.
2972   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2973                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
2974   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2975                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
2976   def : AddSubRegAlias<mnemonic,
2977                        !cast<Instruction>(NAME#"Xrx64"),
2978                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
2979   def : AddSubRegAlias<mnemonic,
2980                        !cast<Instruction>(NAME#"Xrx64"),
2981                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
2984 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
2985                    string alias, string cmpAlias> {
2986   let isCompare = 1, Defs = [NZCV] in {
2987   // Add/Subtract immediate
2988   def Wri  : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
2989                            mnemonic, OpNode> {
2990     let Inst{31} = 0;
2991   }
2992   def Xri  : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
2993                            mnemonic, OpNode> {
2994     let Inst{31} = 1;
2995   }
2997   // Add/Subtract register
2998   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2999   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
3001   // Add/Subtract shifted register
3002   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
3003                            OpNode> {
3004     let Inst{31} = 0;
3005   }
3006   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
3007                            OpNode> {
3008     let Inst{31} = 1;
3009   }
3011   // Add/Subtract extended register
3012   let AddedComplexity = 1 in {
3013   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
3014                            arith_extended_reg32_i32, mnemonic, OpNode> {
3015     let Inst{31} = 0;
3016   }
3017   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
3018                            arith_extended_reg32_i64, mnemonic, OpNode> {
3019     let Inst{31} = 1;
3020   }
3021   }
3023   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
3024                                arith_extendlsl64, mnemonic> {
3025     // UXTX and SXTX only.
3026     let Inst{14-13} = 0b11;
3027     let Inst{31} = 1;
3028   }
3029   } // Defs = [NZCV]
3031   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
3032   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
3033                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
3034                       addsub_shifted_imm32_neg:$imm), 0>;
3035   def : InstSubst<alias#"\t$Rd, $Rn, $imm",
3036                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
3037                        addsub_shifted_imm64_neg:$imm), 0>;
3039   // Compare aliases
3040   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
3041                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
3042   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
3043                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
3044   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
3045                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
3046   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
3047                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
3048   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
3049                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
3050   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
3051                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
3052   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
3053                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
3055   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
3056   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
3057                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
3058   def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
3059                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
3061   // Compare shorthands
3062   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
3063                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
3064   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
3065                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
3066   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
3067                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
3068   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
3069                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
3071   // Register/register aliases with no shift when SP is not used.
3072   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
3073                        GPR32, GPR32, GPR32, 0>;
3074   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
3075                        GPR64, GPR64, GPR64, 0>;
3077   // Register/register aliases with no shift when the first source register
3078   // is SP.
3079   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
3080                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
3081   def : AddSubRegAlias<mnemonic,
3082                        !cast<Instruction>(NAME#"Xrx64"),
3083                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
3086 class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode>
3087       : BaseAddSubImm<
3088           isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4",
3089           (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4),
3090           (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> {
3091   bits<6> imm6;
3092   bits<4> imm4;
3093   let Inst{31} = 1;
3094   let Inst{23-22} = 0b10;
3095   let Inst{21-16} = imm6;
3096   let Inst{15-14} = 0b00;
3097   let Inst{13-10} = imm4;
3098   let Unpredictable{15-14} = 0b11;
3101 class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode>
3102       : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode,
3103                              GPR64sp, GPR64sp>;
3105 //---
3106 // Extract
3107 //---
3108 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
3109                                       SDTCisPtrTy<3>]>;
3110 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
3112 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
3113                      list<dag> patterns>
3114     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
3115          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
3116       Sched<[WriteExtr, ReadExtrHi]> {
3117   bits<5> Rd;
3118   bits<5> Rn;
3119   bits<5> Rm;
3120   bits<6> imm;
3122   let Inst{30-23} = 0b00100111;
3123   let Inst{21}    = 0;
3124   let Inst{20-16} = Rm;
3125   let Inst{15-10} = imm;
3126   let Inst{9-5}   = Rn;
3127   let Inst{4-0}   = Rd;
3130 multiclass ExtractImm<string asm> {
3131   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
3132                       [(set GPR32:$Rd,
3133                         (fshr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
3134     let Inst{31} = 0;
3135     let Inst{22} = 0;
3136     // imm<5> must be zero.
3137     let imm{5}   = 0;
3138   }
3139   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
3140                       [(set GPR64:$Rd,
3141                         (fshr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
3143     let Inst{31} = 1;
3144     let Inst{22} = 1;
3145   }
3148 //---
3149 // Bitfield
3150 //---
3152 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3153 class BaseBitfieldImm<bits<2> opc,
3154                       RegisterClass regtype, Operand imm_type, string asm>
3155     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
3156          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
3157       Sched<[WriteIS, ReadI]> {
3158   bits<5> Rd;
3159   bits<5> Rn;
3160   bits<6> immr;
3161   bits<6> imms;
3163   let Inst{30-29} = opc;
3164   let Inst{28-23} = 0b100110;
3165   let Inst{21-16} = immr;
3166   let Inst{15-10} = imms;
3167   let Inst{9-5}   = Rn;
3168   let Inst{4-0}   = Rd;
3171 multiclass BitfieldImm<bits<2> opc, string asm> {
3172   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
3173     let Inst{31} = 0;
3174     let Inst{22} = 0;
3175     // imms<5> and immr<5> must be zero, else ReservedValue().
3176     let Inst{21} = 0;
3177     let Inst{15} = 0;
3178   }
3179   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
3180     let Inst{31} = 1;
3181     let Inst{22} = 1;
3182   }
3185 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3186 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
3187                       RegisterClass regtype, Operand imm_type, string asm>
3188     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
3189                              imm_type:$imms),
3190          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
3191       Sched<[WriteIS, ReadI]> {
3192   bits<5> Rd;
3193   bits<5> Rn;
3194   bits<6> immr;
3195   bits<6> imms;
3197   let Inst{30-29} = opc;
3198   let Inst{28-23} = 0b100110;
3199   let Inst{21-16} = immr;
3200   let Inst{15-10} = imms;
3201   let Inst{9-5}   = Rn;
3202   let Inst{4-0}   = Rd;
3205 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
3206   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
3207     let Inst{31} = 0;
3208     let Inst{22} = 0;
3209     // imms<5> and immr<5> must be zero, else ReservedValue().
3210     let Inst{21} = 0;
3211     let Inst{15} = 0;
3212   }
3213   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
3214     let Inst{31} = 1;
3215     let Inst{22} = 1;
3216   }
3219 //---
3220 // Logical
3221 //---
3223 // Logical (immediate)
3224 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
3225                      RegisterClass sregtype, Operand imm_type, string asm,
3226                      list<dag> pattern>
3227     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
3228          asm, "\t$Rd, $Rn, $imm", "", pattern>,
3229       Sched<[WriteI, ReadI]> {
3230   bits<5>  Rd;
3231   bits<5>  Rn;
3232   bits<13> imm;
3233   let Inst{30-29} = opc;
3234   let Inst{28-23} = 0b100100;
3235   let Inst{22}    = imm{12};
3236   let Inst{21-16} = imm{11-6};
3237   let Inst{15-10} = imm{5-0};
3238   let Inst{9-5}   = Rn;
3239   let Inst{4-0}   = Rd;
3241   let DecoderMethod = "DecodeLogicalImmInstruction";
3244 // Logical (shifted register)
3245 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
3246                       logical_shifted_reg shifted_regtype, string asm,
3247                       list<dag> pattern>
3248     : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift),
3249         asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>,
3250       Sched<[WriteISReg, ReadI, ReadISReg]> {
3251   bits<5> Rd;
3252   bits<5> Rn;
3253   bits<5> Rm;
3254   bits<8> shift;
3255   let Inst{30-29} = opc;
3256   let Inst{28-24} = 0b01010;
3257   let Inst{23-22} = shift{7-6};
3258   let Inst{21}    = N;
3259   let Inst{20-16} = Rm;
3260   let Inst{15-10} = shift{5-0};
3261   let Inst{9-5}   = Rn;
3262   let Inst{4-0}   = Rd;
3264   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
3267 // Aliases for register+register logical instructions.
3268 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
3269     : InstAlias<asm#"\t$dst, $src1, $src2",
3270                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
3272 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
3273                       string Alias> {
3274   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
3275   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
3276                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
3277                                                logical_imm32:$imm))]> {
3278     let Inst{31} = 0;
3279     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
3280   }
3281   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
3282   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
3283                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
3284                                                logical_imm64:$imm))]> {
3285     let Inst{31} = 1;
3286   }
3288   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
3289                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
3290                       logical_imm32_not:$imm), 0>;
3291   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
3292                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
3293                        logical_imm64_not:$imm), 0>;
3296 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
3297                        string Alias> {
3298   let isCompare = 1, Defs = [NZCV] in {
3299   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
3300       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
3301     let Inst{31} = 0;
3302     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
3303   }
3304   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
3305       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
3306     let Inst{31} = 1;
3307   }
3308   } // end Defs = [NZCV]
3310   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
3311                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
3312                       logical_imm32_not:$imm), 0>;
3313   def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
3314                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
3315                        logical_imm64_not:$imm), 0>;
3318 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
3319     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3320              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
3321       Sched<[WriteI, ReadI, ReadI]>;
3323 // Split from LogicalImm as not all instructions have both.
3324 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
3325                       SDPatternOperator OpNode, int AddedComplexityVal = 0> {
3326   let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in {
3327   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
3328   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
3329   }
3331   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
3332                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
3333                                                  logical_shifted_reg32:$Rm_and_shift))]> {
3334     let Inst{31} = 0;
3335   }
3336   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
3337                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
3338                                                  logical_shifted_reg64:$Rm_and_shift))]> {
3339     let Inst{31} = 1;
3340   }
3342   def : LogicalRegAlias<mnemonic,
3343                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
3344   def : LogicalRegAlias<mnemonic,
3345                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
3348 // Split from LogicalReg to allow setting NZCV Defs
3349 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
3350                        SDPatternOperator OpNode = null_frag> {
3351   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
3352   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
3353   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
3355   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
3356             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> {
3357     let Inst{31} = 0;
3358   }
3359   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
3360             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> {
3361     let Inst{31} = 1;
3362   }
3363   } // Defs = [NZCV]
3365   def : LogicalRegAlias<mnemonic,
3366                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
3367   def : LogicalRegAlias<mnemonic,
3368                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
3371 //---
3372 // Conditionally set flags
3373 //---
3375 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3376 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
3377                             string mnemonic, SDNode OpNode>
3378     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
3379          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
3380          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
3381                              (i32 imm:$cond), NZCV))]>,
3382       Sched<[WriteI, ReadI]> {
3383   let Uses = [NZCV];
3384   let Defs = [NZCV];
3386   bits<5> Rn;
3387   bits<5> imm;
3388   bits<4> nzcv;
3389   bits<4> cond;
3391   let Inst{30}    = op;
3392   let Inst{29-21} = 0b111010010;
3393   let Inst{20-16} = imm;
3394   let Inst{15-12} = cond;
3395   let Inst{11-10} = 0b10;
3396   let Inst{9-5}   = Rn;
3397   let Inst{4}     = 0b0;
3398   let Inst{3-0}   = nzcv;
3401 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3402 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
3403                             SDNode OpNode>
3404     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
3405          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
3406          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
3407                              (i32 imm:$cond), NZCV))]>,
3408       Sched<[WriteI, ReadI, ReadI]> {
3409   let Uses = [NZCV];
3410   let Defs = [NZCV];
3412   bits<5> Rn;
3413   bits<5> Rm;
3414   bits<4> nzcv;
3415   bits<4> cond;
3417   let Inst{30}    = op;
3418   let Inst{29-21} = 0b111010010;
3419   let Inst{20-16} = Rm;
3420   let Inst{15-12} = cond;
3421   let Inst{11-10} = 0b00;
3422   let Inst{9-5}   = Rn;
3423   let Inst{4}     = 0b0;
3424   let Inst{3-0}   = nzcv;
3427 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
3428   // immediate operand variants
3429   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
3430     let Inst{31} = 0;
3431   }
3432   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
3433     let Inst{31} = 1;
3434   }
3435   // register operand variants
3436   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
3437     let Inst{31} = 0;
3438   }
3439   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
3440     let Inst{31} = 1;
3441   }
3444 //---
3445 // Conditional select
3446 //---
3448 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
3449     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3450          asm, "\t$Rd, $Rn, $Rm, $cond", "",
3451          [(set regtype:$Rd,
3452                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
3453       Sched<[WriteI, ReadI, ReadI]> {
3454   let Uses = [NZCV];
3456   bits<5> Rd;
3457   bits<5> Rn;
3458   bits<5> Rm;
3459   bits<4> cond;
3461   let Inst{30}    = op;
3462   let Inst{29-21} = 0b011010100;
3463   let Inst{20-16} = Rm;
3464   let Inst{15-12} = cond;
3465   let Inst{11-10} = op2;
3466   let Inst{9-5}   = Rn;
3467   let Inst{4-0}   = Rd;
3470 multiclass CondSelect<bit op, bits<2> op2, string asm> {
3471   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
3472     let Inst{31} = 0;
3473   }
3474   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
3475     let Inst{31} = 1;
3476   }
3479 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
3480                        PatFrag frag>
3481     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3482          asm, "\t$Rd, $Rn, $Rm, $cond", "",
3483          [(set regtype:$Rd,
3484                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
3485                (i32 imm:$cond), NZCV))]>,
3486       Sched<[WriteI, ReadI, ReadI]> {
3487   let Uses = [NZCV];
3489   bits<5> Rd;
3490   bits<5> Rn;
3491   bits<5> Rm;
3492   bits<4> cond;
3494   let Inst{30}    = op;
3495   let Inst{29-21} = 0b011010100;
3496   let Inst{20-16} = Rm;
3497   let Inst{15-12} = cond;
3498   let Inst{11-10} = op2;
3499   let Inst{9-5}   = Rn;
3500   let Inst{4-0}   = Rd;
3503 def inv_cond_XFORM : SDNodeXForm<imm, [{
3504   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
3505   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
3506                                    MVT::i32);
3507 }]>;
3509 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
3510   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
3511     let Inst{31} = 0;
3512   }
3513   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
3514     let Inst{31} = 1;
3515   }
3517   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
3518             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
3519                                            (inv_cond_XFORM imm:$cond))>;
3521   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
3522             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
3523                                            (inv_cond_XFORM imm:$cond))>;
3526 //---
3527 // Special Mask Value
3528 //---
3529 def maski8_or_more : Operand<i32>,
3530   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
3532 def maski16_or_more : Operand<i32>,
3533   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
3537 //---
3538 // Load/store
3539 //---
3541 // (unsigned immediate)
3542 // Indexed for 8-bit registers. offset is in range [0,4095].
3543 def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>;
3544 def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>;
3545 def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>;
3546 def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>;
3547 def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>;
3549 // (unsigned immediate)
3550 // Indexed for 8-bit registers. offset is in range [0,63].
3551 def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>;
3552 def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>;
3553 def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>;
3554 def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>;
3556 def gi_am_indexed8 :
3557     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
3558     GIComplexPatternEquiv<am_indexed8>;
3559 def gi_am_indexed16 :
3560     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
3561     GIComplexPatternEquiv<am_indexed16>;
3562 def gi_am_indexed32 :
3563     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
3564     GIComplexPatternEquiv<am_indexed32>;
3565 def gi_am_indexed64 :
3566     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
3567     GIComplexPatternEquiv<am_indexed64>;
3568 def gi_am_indexed128 :
3569     GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
3570     GIComplexPatternEquiv<am_indexed128>;
3572 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
3573   let Name = "UImm12Offset" # Scale;
3574   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
3575   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
3576   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
3579 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
3580 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
3581 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
3582 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
3583 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
3585 class uimm12_scaled<int Scale> : Operand<i64> {
3586   let ParserMatchClass
3587    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
3588   let EncoderMethod
3589    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
3590   let PrintMethod = "printUImm12Offset<" # Scale # ">";
3593 def uimm12s1 : uimm12_scaled<1>;
3594 def uimm12s2 : uimm12_scaled<2>;
3595 def uimm12s4 : uimm12_scaled<4>;
3596 def uimm12s8 : uimm12_scaled<8>;
3597 def uimm12s16 : uimm12_scaled<16>;
3599 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3600                       string asm, list<dag> pattern>
3601     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3602   bits<5> Rt;
3604   bits<5> Rn;
3605   bits<12> offset;
3607   let Inst{31-30} = sz;
3608   let Inst{29-27} = 0b111;
3609   let Inst{26}    = V;
3610   let Inst{25-24} = 0b01;
3611   let Inst{23-22} = opc;
3612   let Inst{21-10} = offset;
3613   let Inst{9-5}   = Rn;
3614   let Inst{4-0}   = Rt;
3616   let DecoderMethod = "DecodeUnsignedLdStInstruction";
3619 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3620                   Operand indextype, string asm, list<dag> pattern> {
3621   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3622   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
3623                            (ins GPR64sp:$Rn, indextype:$offset),
3624                            asm, pattern>,
3625            Sched<[WriteLD]>;
3627   def : InstAlias<asm # "\t$Rt, [$Rn]",
3628                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3631 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3632              Operand indextype, string asm, list<dag> pattern> {
3633   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3634   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3635                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3636                            asm, pattern>,
3637            Sched<[WriteST]>;
3639   def : InstAlias<asm # "\t$Rt, [$Rn]",
3640                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3643 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
3644 // substitute zero-registers automatically.
3646 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
3647 //       into StoreUI.
3648 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3649              Operand indextype, string asm, list<dag> pattern> {
3650   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3651   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3652                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3653                            asm, pattern>,
3654            Sched<[WriteST]>;
3656   def : InstAlias<asm # "\t$Rt, [$Rn]",
3657                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3660 def PrefetchOperand : AsmOperandClass {
3661   let Name = "Prefetch";
3662   let ParserMethod = "tryParsePrefetch";
3664 def prfop : Operand<i32> {
3665   let PrintMethod = "printPrefetchOp";
3666   let ParserMatchClass = PrefetchOperand;
3669 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3670 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
3671     : BaseLoadStoreUI<sz, V, opc,
3672                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
3673                       asm, pat>,
3674       Sched<[WriteLD]>;
3676 //---
3677 // Load literal
3678 //---
3680 // Load literal address: 19-bit immediate. The low two bits of the target
3681 // offset are implied zero and so are not part of the immediate.
3682 def am_ldrlit : Operand<iPTR> {
3683   let EncoderMethod = "getLoadLiteralOpValue";
3684   let DecoderMethod = "DecodePCRelLabel19";
3685   let PrintMethod = "printAlignedLabel";
3686   let ParserMatchClass = PCRelLabel19Operand;
3687   let OperandType = "OPERAND_PCREL";
3690 let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
3691 class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
3692     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
3693         asm, "\t$Rt, $label", "", pat>,
3694       Sched<[WriteLD]> {
3695   bits<5> Rt;
3696   bits<19> label;
3697   let Inst{31-30} = opc;
3698   let Inst{29-27} = 0b011;
3699   let Inst{26}    = V;
3700   let Inst{25-24} = 0b00;
3701   let Inst{23-5}  = label;
3702   let Inst{4-0}   = Rt;
3705 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3706 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
3707     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
3708         asm, "\t$Rt, $label", "", pat>,
3709       Sched<[WriteLD]> {
3710   bits<5> Rt;
3711   bits<19> label;
3712   let Inst{31-30} = opc;
3713   let Inst{29-27} = 0b011;
3714   let Inst{26}    = V;
3715   let Inst{25-24} = 0b00;
3716   let Inst{23-5}  = label;
3717   let Inst{4-0}   = Rt;
3720 //---
3721 // Load/store register offset
3722 //---
3724 def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>;
3725 def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>;
3726 def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>;
3727 def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>;
3728 def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>;
3730 def gi_ro_Xindexed8 :
3731     GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">,
3732     GIComplexPatternEquiv<ro_Xindexed8>;
3733 def gi_ro_Xindexed16 :
3734     GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">,
3735     GIComplexPatternEquiv<ro_Xindexed16>;
3736 def gi_ro_Xindexed32 :
3737     GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">,
3738     GIComplexPatternEquiv<ro_Xindexed32>;
3739 def gi_ro_Xindexed64 :
3740     GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">,
3741     GIComplexPatternEquiv<ro_Xindexed64>;
3742 def gi_ro_Xindexed128 :
3743     GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">,
3744     GIComplexPatternEquiv<ro_Xindexed128>;
3746 def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>;
3747 def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>;
3748 def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>;
3749 def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>;
3750 def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>;
3752 def gi_ro_Windexed8 :
3753     GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">,
3754     GIComplexPatternEquiv<ro_Windexed8>;
3755 def gi_ro_Windexed16 :
3756     GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">,
3757     GIComplexPatternEquiv<ro_Windexed16>;
3758 def gi_ro_Windexed32 :
3759     GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">,
3760     GIComplexPatternEquiv<ro_Windexed32>;
3761 def gi_ro_Windexed64 :
3762     GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">,
3763     GIComplexPatternEquiv<ro_Windexed64>;
3764 def gi_ro_Windexed128 :
3765     GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">,
3766     GIComplexPatternEquiv<ro_Windexed128>;
3768 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
3769   let Name = "Mem" # Reg # "Extend" # Width;
3770   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
3771   let RenderMethod = "addMemExtendOperands";
3772   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
3775 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
3776   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3777   // the trivial shift.
3778   let RenderMethod = "addMemExtend8Operands";
3780 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
3781 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
3782 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
3783 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
3785 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
3786   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3787   // the trivial shift.
3788   let RenderMethod = "addMemExtend8Operands";
3790 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
3791 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
3792 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
3793 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
3795 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
3796         : Operand<i32> {
3797   let ParserMatchClass = ParserClass;
3798   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
3799   let DecoderMethod = "DecodeMemExtend";
3800   let EncoderMethod = "getMemExtendOpValue";
3801   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
3804 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
3805 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
3806 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
3807 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
3808 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
3810 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
3811 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
3812 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
3813 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
3814 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
3816 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
3817                   Operand wextend, Operand xextend>  {
3818   // CodeGen-level pattern covering the entire addressing mode.
3819   ComplexPattern Wpat = windex;
3820   ComplexPattern Xpat = xindex;
3822   // Asm-level Operand covering the valid "uxtw #3" style syntax.
3823   Operand Wext = wextend;
3824   Operand Xext = xextend;
3827 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
3828 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
3829 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
3830 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
3831 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
3832                        ro_Xextend128>;
3834 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
3835                    dag outs, list<dag> pat>
3836     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3837   bits<5> Rt;
3838   bits<5> Rn;
3839   bits<5> Rm;
3840   bits<2> extend;
3841   let Inst{31-30} = sz;
3842   let Inst{29-27} = 0b111;
3843   let Inst{26}    = V;
3844   let Inst{25-24} = 0b00;
3845   let Inst{23-22} = opc;
3846   let Inst{21}    = 1;
3847   let Inst{20-16} = Rm;
3848   let Inst{15}    = extend{1}; // sign extend Rm?
3849   let Inst{14}    = 1;
3850   let Inst{12}    = extend{0}; // do shift?
3851   let Inst{11-10} = 0b10;
3852   let Inst{9-5}   = Rn;
3853   let Inst{4-0}   = Rt;
3856 class ROInstAlias<string asm, DAGOperand regtype, Instruction INST>
3857   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
3858               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3860 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3861                    string asm, ValueType Ty, SDPatternOperator loadop> {
3862   let AddedComplexity = 10 in
3863   def roW : LoadStore8RO<sz, V, opc, asm,
3864                  (outs regtype:$Rt),
3865                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3866                  [(set (Ty regtype:$Rt),
3867                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3868                                              ro_Wextend8:$extend)))]>,
3869            Sched<[WriteLDIdx, ReadAdrBase]> {
3870     let Inst{13} = 0b0;
3871   }
3873   let AddedComplexity = 10 in
3874   def roX : LoadStore8RO<sz, V, opc, asm,
3875                  (outs regtype:$Rt),
3876                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3877                  [(set (Ty regtype:$Rt),
3878                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3879                                              ro_Xextend8:$extend)))]>,
3880            Sched<[WriteLDIdx, ReadAdrBase]> {
3881     let Inst{13} = 0b1;
3882   }
3884   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3887 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3888                     string asm, ValueType Ty, SDPatternOperator storeop> {
3889   let AddedComplexity = 10 in
3890   def roW : LoadStore8RO<sz, V, opc, asm, (outs),
3891                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3892                  [(storeop (Ty regtype:$Rt),
3893                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3894                                          ro_Wextend8:$extend))]>,
3895             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
3896     let Inst{13} = 0b0;
3897   }
3899   let AddedComplexity = 10 in
3900   def roX : LoadStore8RO<sz, V, opc, asm, (outs),
3901                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3902                  [(storeop (Ty regtype:$Rt),
3903                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3904                                          ro_Xextend8:$extend))]>,
3905             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
3906     let Inst{13} = 0b1;
3907   }
3909   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3912 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
3913                     dag outs, list<dag> pat>
3914     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3915   bits<5> Rt;
3916   bits<5> Rn;
3917   bits<5> Rm;
3918   bits<2> extend;
3919   let Inst{31-30} = sz;
3920   let Inst{29-27} = 0b111;
3921   let Inst{26}    = V;
3922   let Inst{25-24} = 0b00;
3923   let Inst{23-22} = opc;
3924   let Inst{21}    = 1;
3925   let Inst{20-16} = Rm;
3926   let Inst{15}    = extend{1}; // sign extend Rm?
3927   let Inst{14}    = 1;
3928   let Inst{12}    = extend{0}; // do shift?
3929   let Inst{11-10} = 0b10;
3930   let Inst{9-5}   = Rn;
3931   let Inst{4-0}   = Rt;
3934 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3935                     string asm, ValueType Ty, SDPatternOperator loadop> {
3936   let AddedComplexity = 10 in
3937   def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt),
3938                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3939                  [(set (Ty regtype:$Rt),
3940                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3941                                               ro_Wextend16:$extend)))]>,
3942             Sched<[WriteLDIdx, ReadAdrBase]> {
3943     let Inst{13} = 0b0;
3944   }
3946   let AddedComplexity = 10 in
3947   def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt),
3948                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3949                  [(set (Ty regtype:$Rt),
3950                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3951                                              ro_Xextend16:$extend)))]>,
3952             Sched<[WriteLDIdx, ReadAdrBase]> {
3953     let Inst{13} = 0b1;
3954   }
3956   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3959 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3960                      string asm, ValueType Ty, SDPatternOperator storeop> {
3961   let AddedComplexity = 10 in
3962   def roW : LoadStore16RO<sz, V, opc, asm, (outs),
3963                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3964                 [(storeop (Ty regtype:$Rt),
3965                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3966                                          ro_Wextend16:$extend))]>,
3967            Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
3968     let Inst{13} = 0b0;
3969   }
3971   let AddedComplexity = 10 in
3972   def roX : LoadStore16RO<sz, V, opc, asm, (outs),
3973                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3974                 [(storeop (Ty regtype:$Rt),
3975                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3976                                          ro_Xextend16:$extend))]>,
3977            Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
3978     let Inst{13} = 0b1;
3979   }
3981   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3984 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
3985                     dag outs, list<dag> pat>
3986     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3987   bits<5> Rt;
3988   bits<5> Rn;
3989   bits<5> Rm;
3990   bits<2> extend;
3991   let Inst{31-30} = sz;
3992   let Inst{29-27} = 0b111;
3993   let Inst{26}    = V;
3994   let Inst{25-24} = 0b00;
3995   let Inst{23-22} = opc;
3996   let Inst{21}    = 1;
3997   let Inst{20-16} = Rm;
3998   let Inst{15}    = extend{1}; // sign extend Rm?
3999   let Inst{14}    = 1;
4000   let Inst{12}    = extend{0}; // do shift?
4001   let Inst{11-10} = 0b10;
4002   let Inst{9-5}   = Rn;
4003   let Inst{4-0}   = Rt;
4006 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4007                     string asm, ValueType Ty, SDPatternOperator loadop> {
4008   let AddedComplexity = 10 in
4009   def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt),
4010                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
4011                  [(set (Ty regtype:$Rt),
4012                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
4013                                               ro_Wextend32:$extend)))]>,
4014            Sched<[WriteLDIdx, ReadAdrBase]> {
4015     let Inst{13} = 0b0;
4016   }
4018   let AddedComplexity = 10 in
4019   def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt),
4020                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
4021                  [(set (Ty regtype:$Rt),
4022                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
4023                                               ro_Xextend32:$extend)))]>,
4024            Sched<[WriteLDIdx, ReadAdrBase]> {
4025     let Inst{13} = 0b1;
4026   }
4028   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
4031 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4032                      string asm, ValueType Ty, SDPatternOperator storeop> {
4033   let AddedComplexity = 10 in
4034   def roW : LoadStore32RO<sz, V, opc, asm, (outs),
4035                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
4036                 [(storeop (Ty regtype:$Rt),
4037                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
4038                                          ro_Wextend32:$extend))]>,
4039             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
4040     let Inst{13} = 0b0;
4041   }
4043   let AddedComplexity = 10 in
4044   def roX : LoadStore32RO<sz, V, opc, asm, (outs),
4045                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
4046                 [(storeop (Ty regtype:$Rt),
4047                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
4048                                         ro_Xextend32:$extend))]>,
4049             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
4050     let Inst{13} = 0b1;
4051   }
4053   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
4056 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
4057                     dag outs, list<dag> pat>
4058     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
4059   bits<5> Rt;
4060   bits<5> Rn;
4061   bits<5> Rm;
4062   bits<2> extend;
4063   let Inst{31-30} = sz;
4064   let Inst{29-27} = 0b111;
4065   let Inst{26}    = V;
4066   let Inst{25-24} = 0b00;
4067   let Inst{23-22} = opc;
4068   let Inst{21}    = 1;
4069   let Inst{20-16} = Rm;
4070   let Inst{15}    = extend{1}; // sign extend Rm?
4071   let Inst{14}    = 1;
4072   let Inst{12}    = extend{0}; // do shift?
4073   let Inst{11-10} = 0b10;
4074   let Inst{9-5}   = Rn;
4075   let Inst{4-0}   = Rt;
4078 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4079                     string asm, ValueType Ty, SDPatternOperator loadop> {
4080   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
4081   def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt),
4082                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
4083                 [(set (Ty regtype:$Rt),
4084                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
4085                                              ro_Wextend64:$extend)))]>,
4086            Sched<[WriteLDIdx, ReadAdrBase]> {
4087     let Inst{13} = 0b0;
4088   }
4090   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
4091   def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt),
4092                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
4093                  [(set (Ty regtype:$Rt),
4094                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
4095                                               ro_Xextend64:$extend)))]>,
4096            Sched<[WriteLDIdx, ReadAdrBase]> {
4097     let Inst{13} = 0b1;
4098   }
4100   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
4103 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4104                      string asm, ValueType Ty, SDPatternOperator storeop> {
4105   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
4106   def roW : LoadStore64RO<sz, V, opc, asm, (outs),
4107                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
4108                 [(storeop (Ty regtype:$Rt),
4109                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
4110                                          ro_Wextend64:$extend))]>,
4111             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
4112     let Inst{13} = 0b0;
4113   }
4115   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
4116   def roX : LoadStore64RO<sz, V, opc, asm, (outs),
4117                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
4118                 [(storeop (Ty regtype:$Rt),
4119                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
4120                                          ro_Xextend64:$extend))]>,
4121             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
4122     let Inst{13} = 0b1;
4123   }
4125   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
4128 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
4129                      dag outs, list<dag> pat>
4130     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
4131   bits<5> Rt;
4132   bits<5> Rn;
4133   bits<5> Rm;
4134   bits<2> extend;
4135   let Inst{31-30} = sz;
4136   let Inst{29-27} = 0b111;
4137   let Inst{26}    = V;
4138   let Inst{25-24} = 0b00;
4139   let Inst{23-22} = opc;
4140   let Inst{21}    = 1;
4141   let Inst{20-16} = Rm;
4142   let Inst{15}    = extend{1}; // sign extend Rm?
4143   let Inst{14}    = 1;
4144   let Inst{12}    = extend{0}; // do shift?
4145   let Inst{11-10} = 0b10;
4146   let Inst{9-5}   = Rn;
4147   let Inst{4-0}   = Rt;
4150 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4151                      string asm, ValueType Ty, SDPatternOperator loadop> {
4152   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
4153   def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt),
4154                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
4155                  [(set (Ty regtype:$Rt),
4156                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
4157                                                ro_Wextend128:$extend)))]>,
4158             Sched<[WriteLDIdx, ReadAdrBase]> {
4159     let Inst{13} = 0b0;
4160   }
4162   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
4163   def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt),
4164                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
4165                  [(set (Ty regtype:$Rt),
4166                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
4167                                                ro_Xextend128:$extend)))]>,
4168             Sched<[WriteLDIdx, ReadAdrBase]> {
4169     let Inst{13} = 0b1;
4170   }
4172   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
4175 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4176                       string asm> {
4177   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
4178   def roW : LoadStore128RO<sz, V, opc, asm, (outs),
4179                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
4180                 []>,
4181             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
4182     let Inst{13} = 0b0;
4183   }
4185   let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
4186   def roX : LoadStore128RO<sz, V, opc, asm, (outs),
4187                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
4188                 []>,
4189             Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
4190     let Inst{13} = 0b1;
4191   }
4193   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
4196 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
4197 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
4198                      string asm, list<dag> pat>
4199     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
4200       Sched<[WriteLD]> {
4201   bits<5> Rt;
4202   bits<5> Rn;
4203   bits<5> Rm;
4204   bits<2> extend;
4205   let Inst{31-30} = sz;
4206   let Inst{29-27} = 0b111;
4207   let Inst{26}    = V;
4208   let Inst{25-24} = 0b00;
4209   let Inst{23-22} = opc;
4210   let Inst{21}    = 1;
4211   let Inst{20-16} = Rm;
4212   let Inst{15}    = extend{1}; // sign extend Rm?
4213   let Inst{14}    = 1;
4214   let Inst{12}    = extend{0}; // do shift?
4215   let Inst{11-10} = 0b10;
4216   let Inst{9-5}   = Rn;
4217   let Inst{4-0}   = Rt;
4218   let DecoderMethod = "DecodePRFMRegInstruction";
4219   // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When
4220   // the decoder method returns Fail, the decoder should attempt to decode the
4221   // instruction as RPRFM.
4222   let hasCompleteDecoder = 0;
4225 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
4226   def roW : BasePrefetchRO<sz, V, opc, (outs),
4227                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
4228                 asm, [(AArch64Prefetch timm:$Rt,
4229                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
4230                                                     ro_Wextend64:$extend))]> {
4231     let Inst{13} = 0b0;
4232   }
4234   def roX : BasePrefetchRO<sz, V, opc, (outs),
4235                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
4236                 asm,  [(AArch64Prefetch timm:$Rt,
4237                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
4238                                                      ro_Xextend64:$extend))]> {
4239     let Inst{13} = 0b1;
4240   }
4242   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
4243                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
4244                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
4247 //---
4248 // Load/store unscaled immediate
4249 //---
4251 def am_unscaled8 :  ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>;
4252 def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>;
4253 def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>;
4254 def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>;
4255 def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>;
4257 def gi_am_unscaled8 :
4258     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
4259     GIComplexPatternEquiv<am_unscaled8>;
4260 def gi_am_unscaled16 :
4261     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
4262     GIComplexPatternEquiv<am_unscaled16>;
4263 def gi_am_unscaled32 :
4264     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
4265     GIComplexPatternEquiv<am_unscaled32>;
4266 def gi_am_unscaled64 :
4267     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
4268     GIComplexPatternEquiv<am_unscaled64>;
4269 def gi_am_unscaled128 :
4270     GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
4271     GIComplexPatternEquiv<am_unscaled128>;
4274 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
4275                            string asm, list<dag> pattern>
4276     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
4277   bits<5> Rt;
4278   bits<5> Rn;
4279   bits<9> offset;
4280   let Inst{31-30} = sz;
4281   let Inst{29-27} = 0b111;
4282   let Inst{26}    = V;
4283   let Inst{25-24} = 0b00;
4284   let Inst{23-22} = opc;
4285   let Inst{21}    = 0;
4286   let Inst{20-12} = offset;
4287   let Inst{11-10} = 0b00;
4288   let Inst{9-5}   = Rn;
4289   let Inst{4-0}   = Rt;
4291   let DecoderMethod = "DecodeSignedLdStInstruction";
4294 // Armv8.4 LDAPR & STLR with Immediate Offset instruction
4295 multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,
4296                               DAGOperand regtype > {
4297   def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),
4298                                (ins GPR64sp:$Rn, simm9:$offset), asm, []>,
4299           Sched<[WriteST]> {
4300     let Inst{29} = 0;
4301     let Inst{24} = 1;
4302   }
4303   def : InstAlias<asm # "\t$Rt, [$Rn]",
4304                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
4307 multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,
4308                                DAGOperand regtype > {
4309   def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),
4310                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
4311                                asm, []>,
4312           Sched<[WriteST]> {
4313     let Inst{29} = 0;
4314     let Inst{24} = 1;
4315   }
4316   def : InstAlias<asm # "\t$Rt, [$Rn]",
4317                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
4320 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4321                    string asm, list<dag> pattern> {
4322   let AddedComplexity = 1 in // try this before LoadUI
4323   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
4324                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
4325           Sched<[WriteLD]>;
4327   def : InstAlias<asm # "\t$Rt, [$Rn]",
4328                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
4331 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
4332                          string asm, list<dag> pattern> {
4333   let AddedComplexity = 1 in // try this before StoreUI
4334   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
4335                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
4336                                asm, pattern>,
4337           Sched<[WriteST]>;
4339   def : InstAlias<asm # "\t$Rt, [$Rn]",
4340                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
4343 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
4344                             list<dag> pat> {
4345   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
4346   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
4347                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
4348                                asm, pat>,
4349           Sched<[WriteLD]>;
4351   def : InstAlias<asm # "\t$Rt, [$Rn]",
4352                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
4355 //---
4356 // Load/store unscaled immediate, unprivileged
4357 //---
4359 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
4360                                 dag oops, dag iops, string asm>
4361     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
4362   bits<5> Rt;
4363   bits<5> Rn;
4364   bits<9> offset;
4365   let Inst{31-30} = sz;
4366   let Inst{29-27} = 0b111;
4367   let Inst{26}    = V;
4368   let Inst{25-24} = 0b00;
4369   let Inst{23-22} = opc;
4370   let Inst{21}    = 0;
4371   let Inst{20-12} = offset;
4372   let Inst{11-10} = 0b10;
4373   let Inst{9-5}   = Rn;
4374   let Inst{4-0}   = Rt;
4376   let DecoderMethod = "DecodeSignedLdStInstruction";
4379 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
4380                             RegisterClass regtype, string asm> {
4381   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
4382   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
4383                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
4384           Sched<[WriteLD]>;
4386   def : InstAlias<asm # "\t$Rt, [$Rn]",
4387                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
4390 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
4391                              RegisterClass regtype, string asm> {
4392   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
4393   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
4394                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
4395                                  asm>,
4396           Sched<[WriteST]>;
4398   def : InstAlias<asm # "\t$Rt, [$Rn]",
4399                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
4402 //---
4403 // Load/store pre-indexed
4404 //---
4406 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
4407                           string asm, string cstr, list<dag> pat>
4408     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
4409   bits<5> Rt;
4410   bits<5> Rn;
4411   bits<9> offset;
4412   let Inst{31-30} = sz;
4413   let Inst{29-27} = 0b111;
4414   let Inst{26}    = V;
4415   let Inst{25-24} = 0;
4416   let Inst{23-22} = opc;
4417   let Inst{21}    = 0;
4418   let Inst{20-12} = offset;
4419   let Inst{11-10} = 0b11;
4420   let Inst{9-5}   = Rn;
4421   let Inst{4-0}   = Rt;
4423   let DecoderMethod = "DecodeSignedLdStInstruction";
4426 let hasSideEffects = 0 in {
4427 let mayStore = 0, mayLoad = 1 in
4428 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4429              string asm>
4430     : BaseLoadStorePreIdx<sz, V, opc,
4431                      (outs GPR64sp:$wback, regtype:$Rt),
4432                      (ins GPR64sp:$Rn, simm9:$offset), asm,
4433                      "$Rn = $wback,@earlyclobber $wback", []>,
4434       Sched<[WriteAdr, WriteLD]>;
4436 let mayStore = 1, mayLoad = 0 in
4437 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4438                   string asm, SDPatternOperator storeop, ValueType Ty>
4439     : BaseLoadStorePreIdx<sz, V, opc,
4440                       (outs GPR64sp:$wback),
4441                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
4442                       asm, "$Rn = $wback,@earlyclobber $wback",
4443       [(set GPR64sp:$wback,
4444             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
4445       Sched<[WriteAdr, WriteST]>;
4446 } // hasSideEffects = 0
4448 //---
4449 // Load/store post-indexed
4450 //---
4452 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
4453                           string asm, string cstr, list<dag> pat>
4454     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
4455   bits<5> Rt;
4456   bits<5> Rn;
4457   bits<9> offset;
4458   let Inst{31-30} = sz;
4459   let Inst{29-27} = 0b111;
4460   let Inst{26}    = V;
4461   let Inst{25-24} = 0b00;
4462   let Inst{23-22} = opc;
4463   let Inst{21}    = 0b0;
4464   let Inst{20-12} = offset;
4465   let Inst{11-10} = 0b01;
4466   let Inst{9-5}   = Rn;
4467   let Inst{4-0}   = Rt;
4469   let DecoderMethod = "DecodeSignedLdStInstruction";
4472 let hasSideEffects = 0 in {
4473 let mayStore = 0, mayLoad = 1 in
4474 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4475              string asm>
4476     : BaseLoadStorePostIdx<sz, V, opc,
4477                       (outs GPR64sp:$wback, regtype:$Rt),
4478                       (ins GPR64sp:$Rn, simm9:$offset),
4479                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
4480       Sched<[WriteAdr, WriteLD]>;
4482 let mayStore = 1, mayLoad = 0 in
4483 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4484                    string asm, SDPatternOperator storeop, ValueType Ty>
4485     : BaseLoadStorePostIdx<sz, V, opc,
4486                       (outs GPR64sp:$wback),
4487                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
4488                        asm, "$Rn = $wback,@earlyclobber $wback",
4489       [(set GPR64sp:$wback,
4490             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
4491     Sched<[WriteAdr, WriteST]>;
4492 } // hasSideEffects = 0
4495 //---
4496 // Load/store pair
4497 //---
4499 // (indexed, offset)
4501 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
4502                               string asm>
4503     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4504   bits<5> Rt;
4505   bits<5> Rt2;
4506   bits<5> Rn;
4507   bits<7> offset;
4508   let Inst{31-30} = opc;
4509   let Inst{29-27} = 0b101;
4510   let Inst{26}    = V;
4511   let Inst{25-23} = 0b010;
4512   let Inst{22}    = L;
4513   let Inst{21-15} = offset;
4514   let Inst{14-10} = Rt2;
4515   let Inst{9-5}   = Rn;
4516   let Inst{4-0}   = Rt;
4518   let DecoderMethod = "DecodePairLdStInstruction";
4521 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4522                           Operand indextype, string asm> {
4523   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4524   def i : BaseLoadStorePairOffset<opc, V, 1,
4525                                   (outs regtype:$Rt, regtype:$Rt2),
4526                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
4527           Sched<[WriteLD, WriteLDHi]>;
4529   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4530                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4531                                                   GPR64sp:$Rn, 0)>;
4535 multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4536                            Operand indextype, string asm> {
4537   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
4538   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
4539                                   (ins regtype:$Rt, regtype:$Rt2,
4540                                        GPR64sp:$Rn, indextype:$offset),
4541                                   asm>,
4542           Sched<[WriteSTP]>;
4544   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4545                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4546                                                   GPR64sp:$Rn, 0)>;
4549 // (pre-indexed)
4550 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4551                               string asm>
4552     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
4553   bits<5> Rt;
4554   bits<5> Rt2;
4555   bits<5> Rn;
4556   bits<7> offset;
4557   let Inst{31-30} = opc;
4558   let Inst{29-27} = 0b101;
4559   let Inst{26}    = V;
4560   let Inst{25-23} = 0b011;
4561   let Inst{22}    = L;
4562   let Inst{21-15} = offset;
4563   let Inst{14-10} = Rt2;
4564   let Inst{9-5}   = Rn;
4565   let Inst{4-0}   = Rt;
4567   let DecoderMethod = "DecodePairLdStInstruction";
4570 let hasSideEffects = 0 in {
4571 let mayStore = 0, mayLoad = 1 in
4572 class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4573                      Operand indextype, string asm>
4574     : BaseLoadStorePairPreIdx<opc, V, 1,
4575                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4576                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
4577       Sched<[WriteAdr, WriteLD, WriteLDHi]>;
4579 let mayStore = 1, mayLoad = 0 in
4580 class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4581                       Operand indextype, string asm>
4582     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
4583                              (ins regtype:$Rt, regtype:$Rt2,
4584                                   GPR64sp:$Rn, indextype:$offset),
4585                              asm>,
4586       Sched<[WriteAdr, WriteSTP]>;
4587 } // hasSideEffects = 0
4589 // (post-indexed)
4591 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4592                               string asm>
4593     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
4594   bits<5> Rt;
4595   bits<5> Rt2;
4596   bits<5> Rn;
4597   bits<7> offset;
4598   let Inst{31-30} = opc;
4599   let Inst{29-27} = 0b101;
4600   let Inst{26}    = V;
4601   let Inst{25-23} = 0b001;
4602   let Inst{22}    = L;
4603   let Inst{21-15} = offset;
4604   let Inst{14-10} = Rt2;
4605   let Inst{9-5}   = Rn;
4606   let Inst{4-0}   = Rt;
4608   let DecoderMethod = "DecodePairLdStInstruction";
4611 let hasSideEffects = 0 in {
4612 let mayStore = 0, mayLoad = 1 in
4613 class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4614                       Operand idxtype, string asm>
4615     : BaseLoadStorePairPostIdx<opc, V, 1,
4616                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4617                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
4618       Sched<[WriteAdr, WriteLD, WriteLDHi]>;
4620 let mayStore = 1, mayLoad = 0 in
4621 class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4622                        Operand idxtype, string asm>
4623     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
4624                              (ins regtype:$Rt, regtype:$Rt2,
4625                                   GPR64sp:$Rn, idxtype:$offset),
4626                              asm>,
4627       Sched<[WriteAdr, WriteSTP]>;
4628 } // hasSideEffects = 0
4630 //  (no-allocate)
4632 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
4633                               string asm>
4634     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4635   bits<5> Rt;
4636   bits<5> Rt2;
4637   bits<5> Rn;
4638   bits<7> offset;
4639   let Inst{31-30} = opc;
4640   let Inst{29-27} = 0b101;
4641   let Inst{26}    = V;
4642   let Inst{25-23} = 0b000;
4643   let Inst{22}    = L;
4644   let Inst{21-15} = offset;
4645   let Inst{14-10} = Rt2;
4646   let Inst{9-5}   = Rn;
4647   let Inst{4-0}   = Rt;
4649   let DecoderMethod = "DecodePairLdStInstruction";
4652 multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,
4653                            Operand indextype, string asm> {
4654   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4655   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
4656                                    (outs regtype:$Rt, regtype:$Rt2),
4657                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
4658           Sched<[WriteLD, WriteLDHi]>;
4661   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4662                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4663                                                   GPR64sp:$Rn, 0)>;
4666 multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,
4667                       Operand indextype, string asm> {
4668   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
4669   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
4670                                    (ins regtype:$Rt, regtype:$Rt2,
4671                                         GPR64sp:$Rn, indextype:$offset),
4672                                    asm>,
4673           Sched<[WriteSTP]>;
4675   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4676                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4677                                                   GPR64sp:$Rn, 0)>;
4680 //---
4681 // Load/store exclusive
4682 //---
4684 // True exclusive operations write to and/or read from the system's exclusive
4685 // monitors, which as far as a compiler is concerned can be modelled as a
4686 // random shared memory address. Hence LoadExclusive mayStore.
4688 // Since these instructions have the undefined register bits set to 1 in
4689 // their canonical form, we need a post encoder method to set those bits
4690 // to 1 when encoding these instructions. We do this using the
4691 // fixLoadStoreExclusive function. This function has template parameters:
4693 // fixLoadStoreExclusive<int hasRs, int hasRt2>
4695 // hasRs indicates that the instruction uses the Rs field, so we won't set
4696 // it to 1 (and the same for Rt2). We don't need template parameters for
4697 // the other register fields since Rt and Rn are always used.
4699 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
4700 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4701                              dag oops, dag iops, string asm, string operands>
4702     : I<oops, iops, asm, operands, "", []> {
4703   let Inst{31-30} = sz;
4704   let Inst{29-24} = 0b001000;
4705   let Inst{23}    = o2;
4706   let Inst{22}    = L;
4707   let Inst{21}    = o1;
4708   let Inst{15}    = o0;
4710   let DecoderMethod = "DecodeExclusiveLdStInstruction";
4713 // Neither Rs nor Rt2 operands.
4714 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4715                                dag oops, dag iops, string asm, string operands>
4716     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
4717   bits<5> Rt;
4718   bits<5> Rn;
4719   let Inst{20-16} = 0b11111;
4720   let Unpredictable{20-16} = 0b11111;
4721   let Inst{14-10} = 0b11111;
4722   let Unpredictable{14-10} = 0b11111;
4723   let Inst{9-5} = Rn;
4724   let Inst{4-0} = Rt;
4726   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
4729 // Simple load acquires don't set the exclusive monitor
4730 let mayLoad = 1, mayStore = 0 in
4731 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4732                   RegisterClass regtype, string asm>
4733     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4734                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4735       Sched<[WriteLD]>;
4737 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4738                     RegisterClass regtype, string asm>
4739     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4740                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4741       Sched<[WriteLD]>;
4743 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4744                        RegisterClass regtype, string asm>
4745     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4746                              (outs regtype:$Rt, regtype:$Rt2),
4747                              (ins GPR64sp0:$Rn), asm,
4748                              "\t$Rt, $Rt2, [$Rn]">,
4749       Sched<[WriteLD, WriteLDHi]> {
4750   bits<5> Rt;
4751   bits<5> Rt2;
4752   bits<5> Rn;
4753   let Inst{14-10} = Rt2;
4754   let Inst{9-5} = Rn;
4755   let Inst{4-0} = Rt;
4757   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
4760 // Simple store release operations do not check the exclusive monitor.
4761 let mayLoad = 0, mayStore = 1 in
4762 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4763                    RegisterClass regtype, string asm>
4764     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
4765                                (ins regtype:$Rt, GPR64sp:$Rn),
4766                                asm, "\t$Rt, [$Rn]">,
4767       Sched<[WriteST]>;
4769 let mayLoad = 1, mayStore = 1 in
4770 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4771                      RegisterClass regtype, string asm>
4772     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
4773                              (ins regtype:$Rt, GPR64sp0:$Rn),
4774                              asm, "\t$Ws, $Rt, [$Rn]">,
4775       Sched<[WriteSTX]> {
4776   bits<5> Ws;
4777   bits<5> Rt;
4778   bits<5> Rn;
4779   let Inst{20-16} = Ws;
4780   let Inst{9-5} = Rn;
4781   let Inst{4-0} = Rt;
4783   let Constraints = "@earlyclobber $Ws";
4784   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
4787 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4788                          RegisterClass regtype, string asm>
4789     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4790                              (outs GPR32:$Ws),
4791                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
4792                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
4793       Sched<[WriteSTX]> {
4794   bits<5> Ws;
4795   bits<5> Rt;
4796   bits<5> Rt2;
4797   bits<5> Rn;
4798   let Inst{20-16} = Ws;
4799   let Inst{14-10} = Rt2;
4800   let Inst{9-5} = Rn;
4801   let Inst{4-0} = Rt;
4803   let Constraints = "@earlyclobber $Ws";
4806 // Armv8.5-A Memory Tagging Extension
4807 class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn,
4808                  string asm_opnds, string cstr, dag oops, dag iops>
4809     : I<oops, iops, asm_insn, asm_opnds, cstr, []>,
4810       Sched<[]> {
4811   bits<5> Rn;
4813   let Inst{31-24} = 0b11011001;
4814   let Inst{23-22} = opc1;
4815   let Inst{21}    = 1;
4816   // Inst{20-12} defined by subclass
4817   let Inst{11-10} = opc2;
4818   let Inst{9-5}   = Rn;
4819   // Inst{4-0} defined by subclass
4822 class MemTagVector<bit Load, string asm_insn, string asm_opnds,
4823                    dag oops, dag iops>
4824     : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,
4825                   "", oops, iops> {
4826   bits<5> Rt;
4828   let Inst{20-12} = 0b000000000;
4829   let Inst{4-0}   = Rt;
4831   let mayLoad = Load;
4834 class MemTagLoad<string asm_insn, string asm_opnds>
4835     : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback",
4836                  (outs GPR64:$wback),
4837                  (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> {
4838   bits<5> Rt;
4839   bits<9> offset;
4841   let Inst{20-12} = offset;
4842   let Inst{4-0}   = Rt;
4844   let mayLoad = 1;
4847 class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn,
4848                      string asm_opnds, string cstr, dag oops, dag iops>
4849     : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> {
4850   bits<5> Rt;
4851   bits<9> offset;
4853   let Inst{20-12} = offset;
4854   let Inst{4-0}   = Rt;
4856   let mayStore = 1;
4859 multiclass MemTagStore<bits<2> opc1, string insn> {
4860   def i :
4861     BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",
4862                     (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4863   def PreIndex :
4864     BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",
4865                     "$Rn = $wback",
4866                     (outs GPR64sp:$wback),
4867                     (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4868   def PostIndex :
4869     BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",
4870                     "$Rn = $wback",
4871                     (outs GPR64sp:$wback),
4872                     (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4874   def : InstAlias<insn # "\t$Rt, [$Rn]",
4875                   (!cast<Instruction>(NAME # "i") GPR64sp:$Rt, GPR64sp:$Rn, 0)>;
4878 //---
4879 // Exception generation
4880 //---
4882 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
4883 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm,
4884                           list<dag> pattern = []>
4885     : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>,
4886       Sched<[WriteSys]> {
4887   bits<16> imm;
4888   let Inst{31-24} = 0b11010100;
4889   let Inst{23-21} = op1;
4890   let Inst{20-5}  = imm;
4891   let Inst{4-2}   = 0b000;
4892   let Inst{1-0}   = ll;
4895 //---
4896 // UDF : Permanently UNDEFINED instructions.  Format: Opc = 0x0000, 16 bit imm.
4897 //--
4898 let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in {
4899 class UDFType<bits<16> opc, string asm>
4900   : I<(outs), (ins uimm16:$imm),
4901        asm, "\t$imm", "", []>,
4902     Sched<[]> {
4903   bits<16> imm;
4904   let Inst{31-16} = opc;
4905   let Inst{15-0} = imm;
4908 let Predicates = [HasFPARMv8] in {
4910 //---
4911 // Floating point to integer conversion
4912 //---
4914 let mayRaiseFPException = 1, Uses = [FPCR] in
4915 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
4916                       RegisterClass srcType, RegisterClass dstType,
4917                       string asm, list<dag> pattern>
4918     : I<(outs dstType:$Rd), (ins srcType:$Rn),
4919          asm, "\t$Rd, $Rn", "", pattern>,
4920       Sched<[WriteFCvt]> {
4921   bits<5> Rd;
4922   bits<5> Rn;
4923   let Inst{30-29} = 0b00;
4924   let Inst{28-24} = 0b11110;
4925   let Inst{23-22} = type;
4926   let Inst{21}    = 1;
4927   let Inst{20-19} = rmode;
4928   let Inst{18-16} = opcode;
4929   let Inst{15-10} = 0;
4930   let Inst{9-5}   = Rn;
4931   let Inst{4-0}   = Rd;
4934 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
4935 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
4936                       RegisterClass srcType, RegisterClass dstType,
4937                       Operand immType, string asm, list<dag> pattern>
4938     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4939          asm, "\t$Rd, $Rn, $scale", "", pattern>,
4940       Sched<[WriteFCvt]> {
4941   bits<5> Rd;
4942   bits<5> Rn;
4943   bits<6> scale;
4944   let Inst{30-29} = 0b00;
4945   let Inst{28-24} = 0b11110;
4946   let Inst{23-22} = type;
4947   let Inst{21}    = 0;
4948   let Inst{20-19} = rmode;
4949   let Inst{18-16} = opcode;
4950   let Inst{15-10} = scale;
4951   let Inst{9-5}   = Rn;
4952   let Inst{4-0}   = Rd;
4955 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
4956            SDPatternOperator OpN> {
4957   // Unscaled half-precision to 32-bit
4958   def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
4959                                      [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4960     let Inst{31} = 0; // 32-bit GPR flag
4961     let Predicates = [HasFullFP16];
4962   }
4964   // Unscaled half-precision to 64-bit
4965   def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
4966                                      [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4967     let Inst{31} = 1; // 64-bit GPR flag
4968     let Predicates = [HasFullFP16];
4969   }
4971   // Unscaled single-precision to 32-bit
4972   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
4973                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
4974     let Inst{31} = 0; // 32-bit GPR flag
4975   }
4977   // Unscaled single-precision to 64-bit
4978   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
4979                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
4980     let Inst{31} = 1; // 64-bit GPR flag
4981   }
4983   // Unscaled double-precision to 32-bit
4984   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
4985                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4986     let Inst{31} = 0; // 32-bit GPR flag
4987   }
4989   // Unscaled double-precision to 64-bit
4990   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
4991                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4992     let Inst{31} = 1; // 64-bit GPR flag
4993   }
4996 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
4997                              SDPatternOperator OpN> {
4998   // Scaled half-precision to 32-bit
4999   def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
5000                               fixedpoint_f16_i32, asm,
5001               [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn),
5002                                           fixedpoint_f16_i32:$scale)))]> {
5003     let Inst{31} = 0; // 32-bit GPR flag
5004     let scale{5} = 1;
5005     let Predicates = [HasFullFP16];
5006   }
5008   // Scaled half-precision to 64-bit
5009   def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
5010                               fixedpoint_f16_i64, asm,
5011               [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn),
5012                                           fixedpoint_f16_i64:$scale)))]> {
5013     let Inst{31} = 1; // 64-bit GPR flag
5014     let Predicates = [HasFullFP16];
5015   }
5017   // Scaled single-precision to 32-bit
5018   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
5019                               fixedpoint_f32_i32, asm,
5020               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
5021                                           fixedpoint_f32_i32:$scale)))]> {
5022     let Inst{31} = 0; // 32-bit GPR flag
5023     let scale{5} = 1;
5024   }
5026   // Scaled single-precision to 64-bit
5027   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
5028                               fixedpoint_f32_i64, asm,
5029               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
5030                                           fixedpoint_f32_i64:$scale)))]> {
5031     let Inst{31} = 1; // 64-bit GPR flag
5032   }
5034   // Scaled double-precision to 32-bit
5035   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
5036                               fixedpoint_f64_i32, asm,
5037               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
5038                                           fixedpoint_f64_i32:$scale)))]> {
5039     let Inst{31} = 0; // 32-bit GPR flag
5040     let scale{5} = 1;
5041   }
5043   // Scaled double-precision to 64-bit
5044   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
5045                               fixedpoint_f64_i64, asm,
5046               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
5047                                           fixedpoint_f64_i64:$scale)))]> {
5048     let Inst{31} = 1; // 64-bit GPR flag
5049   }
5052 //---
5053 // Integer to floating point conversion
5054 //---
5056 let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
5057 class BaseIntegerToFP<bit isUnsigned,
5058                       RegisterClass srcType, RegisterClass dstType,
5059                       Operand immType, string asm, list<dag> pattern>
5060     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
5061          asm, "\t$Rd, $Rn, $scale", "", pattern>,
5062       Sched<[WriteFCvt]> {
5063   bits<5> Rd;
5064   bits<5> Rn;
5065   bits<6> scale;
5066   let Inst{30-24} = 0b0011110;
5067   let Inst{21-17} = 0b00001;
5068   let Inst{16}    = isUnsigned;
5069   let Inst{15-10} = scale;
5070   let Inst{9-5}   = Rn;
5071   let Inst{4-0}   = Rd;
5074 let mayRaiseFPException = 1, Uses = [FPCR] in
5075 class BaseIntegerToFPUnscaled<bit isUnsigned,
5076                       RegisterClass srcType, RegisterClass dstType,
5077                       ValueType dvt, string asm, SDPatternOperator node>
5078     : I<(outs dstType:$Rd), (ins srcType:$Rn),
5079          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
5080       Sched<[WriteFCvt]> {
5081   bits<5> Rd;
5082   bits<5> Rn;
5083   bits<6> scale;
5084   let Inst{30-24} = 0b0011110;
5085   let Inst{21-17} = 0b10001;
5086   let Inst{16}    = isUnsigned;
5087   let Inst{15-10} = 0b000000;
5088   let Inst{9-5}   = Rn;
5089   let Inst{4-0}   = Rd;
5092 multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> {
5093   // Unscaled
5094   def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
5095     let Inst{31} = 0; // 32-bit GPR flag
5096     let Inst{23-22} = 0b11; // 16-bit FPR flag
5097     let Predicates = [HasFullFP16];
5098   }
5100   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
5101     let Inst{31} = 0; // 32-bit GPR flag
5102     let Inst{23-22} = 0b00; // 32-bit FPR flag
5103   }
5105   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
5106     let Inst{31} = 0; // 32-bit GPR flag
5107     let Inst{23-22} = 0b01; // 64-bit FPR flag
5108   }
5110   def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
5111     let Inst{31} = 1; // 64-bit GPR flag
5112     let Inst{23-22} = 0b11; // 16-bit FPR flag
5113     let Predicates = [HasFullFP16];
5114   }
5116   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
5117     let Inst{31} = 1; // 64-bit GPR flag
5118     let Inst{23-22} = 0b00; // 32-bit FPR flag
5119   }
5121   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
5122     let Inst{31} = 1; // 64-bit GPR flag
5123     let Inst{23-22} = 0b01; // 64-bit FPR flag
5124   }
5126   // Scaled
5127   def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_recip_f16_i32, asm,
5128                              [(set (f16 FPR16:$Rd),
5129                                    (fmul (node GPR32:$Rn),
5130                                          fixedpoint_recip_f16_i32:$scale))]> {
5131     let Inst{31} = 0; // 32-bit GPR flag
5132     let Inst{23-22} = 0b11; // 16-bit FPR flag
5133     let scale{5} = 1;
5134     let Predicates = [HasFullFP16];
5135   }
5137   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_recip_f32_i32, asm,
5138                              [(set FPR32:$Rd,
5139                                    (fmul (node GPR32:$Rn),
5140                                          fixedpoint_recip_f32_i32:$scale))]> {
5141     let Inst{31} = 0; // 32-bit GPR flag
5142     let Inst{23-22} = 0b00; // 32-bit FPR flag
5143     let scale{5} = 1;
5144   }
5146   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_recip_f64_i32, asm,
5147                              [(set FPR64:$Rd,
5148                                    (fmul (node GPR32:$Rn),
5149                                          fixedpoint_recip_f64_i32:$scale))]> {
5150     let Inst{31} = 0; // 32-bit GPR flag
5151     let Inst{23-22} = 0b01; // 64-bit FPR flag
5152     let scale{5} = 1;
5153   }
5155   def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_recip_f16_i64, asm,
5156                              [(set (f16 FPR16:$Rd),
5157                                    (fmul (node GPR64:$Rn),
5158                                          fixedpoint_recip_f16_i64:$scale))]> {
5159     let Inst{31} = 1; // 64-bit GPR flag
5160     let Inst{23-22} = 0b11; // 16-bit FPR flag
5161     let Predicates = [HasFullFP16];
5162   }
5164   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_recip_f32_i64, asm,
5165                              [(set FPR32:$Rd,
5166                                    (fmul (node GPR64:$Rn),
5167                                          fixedpoint_recip_f32_i64:$scale))]> {
5168     let Inst{31} = 1; // 64-bit GPR flag
5169     let Inst{23-22} = 0b00; // 32-bit FPR flag
5170   }
5172   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_recip_f64_i64, asm,
5173                              [(set FPR64:$Rd,
5174                                    (fmul (node GPR64:$Rn),
5175                                          fixedpoint_recip_f64_i64:$scale))]> {
5176     let Inst{31} = 1; // 64-bit GPR flag
5177     let Inst{23-22} = 0b01; // 64-bit FPR flag
5178   }
5181 //---
5182 // Unscaled integer <-> floating point conversion (i.e. FMOV)
5183 //---
5185 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5186 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
5187                       RegisterClass srcType, RegisterClass dstType,
5188                       string asm>
5189     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
5190         // We use COPY_TO_REGCLASS for these bitconvert operations.
5191         // copyPhysReg() expands the resultant COPY instructions after
5192         // regalloc is done. This gives greater freedom for the allocator
5193         // and related passes (coalescing, copy propagation, et. al.) to
5194         // be more effective.
5195         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
5196       Sched<[WriteFCopy]> {
5197   bits<5> Rd;
5198   bits<5> Rn;
5199   let Inst{30-24} = 0b0011110;
5200   let Inst{21}    = 1;
5201   let Inst{20-19} = rmode;
5202   let Inst{18-16} = opcode;
5203   let Inst{15-10} = 0b000000;
5204   let Inst{9-5}   = Rn;
5205   let Inst{4-0}   = Rd;
5208 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5209 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
5210                      RegisterClass srcType, RegisterOperand dstType, string asm,
5211                      string kind>
5212     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
5213         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
5214       Sched<[WriteFCopy]> {
5215   bits<5> Rd;
5216   bits<5> Rn;
5217   let Inst{30-23} = 0b00111101;
5218   let Inst{21}    = 1;
5219   let Inst{20-19} = rmode;
5220   let Inst{18-16} = opcode;
5221   let Inst{15-10} = 0b000000;
5222   let Inst{9-5}   = Rn;
5223   let Inst{4-0}   = Rd;
5225   let DecoderMethod =  "DecodeFMOVLaneInstruction";
5228 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5229 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
5230                      RegisterOperand srcType, RegisterClass dstType, string asm,
5231                      string kind>
5232     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
5233         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
5234       Sched<[WriteFCopy]> {
5235   bits<5> Rd;
5236   bits<5> Rn;
5237   let Inst{30-23} = 0b00111101;
5238   let Inst{21}    = 1;
5239   let Inst{20-19} = rmode;
5240   let Inst{18-16} = opcode;
5241   let Inst{15-10} = 0b000000;
5242   let Inst{9-5}   = Rn;
5243   let Inst{4-0}   = Rd;
5245   let DecoderMethod =  "DecodeFMOVLaneInstruction";
5249 multiclass UnscaledConversion<string asm> {
5250   def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
5251     let Inst{31} = 0; // 32-bit GPR flag
5252     let Inst{23-22} = 0b11; // 16-bit FPR flag
5253     let Predicates = [HasFullFP16];
5254   }
5256   def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
5257     let Inst{31} = 1; // 64-bit GPR flag
5258     let Inst{23-22} = 0b11; // 16-bit FPR flag
5259     let Predicates = [HasFullFP16];
5260   }
5262   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
5263     let Inst{31} = 0; // 32-bit GPR flag
5264     let Inst{23-22} = 0b00; // 32-bit FPR flag
5265   }
5267   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
5268     let Inst{31} = 1; // 64-bit GPR flag
5269     let Inst{23-22} = 0b01; // 64-bit FPR flag
5270   }
5272   def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
5273     let Inst{31} = 0; // 32-bit GPR flag
5274     let Inst{23-22} = 0b11; // 16-bit FPR flag
5275     let Predicates = [HasFullFP16];
5276   }
5278   def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
5279     let Inst{31} = 1; // 64-bit GPR flag
5280     let Inst{23-22} = 0b11; // 16-bit FPR flag
5281     let Predicates = [HasFullFP16];
5282   }
5284   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
5285     let Inst{31} = 0; // 32-bit GPR flag
5286     let Inst{23-22} = 0b00; // 32-bit FPR flag
5287   }
5289   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
5290     let Inst{31} = 1; // 64-bit GPR flag
5291     let Inst{23-22} = 0b01; // 64-bit FPR flag
5292   }
5294   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
5295                                              asm, ".d"> {
5296     let Inst{31} = 1;
5297     let Inst{22} = 0;
5298   }
5300   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
5301                                                asm, ".d"> {
5302     let Inst{31} = 1;
5303     let Inst{22} = 0;
5304   }
5307 //---
5308 // Floating point conversion
5309 //---
5311 let mayRaiseFPException = 1, Uses = [FPCR] in
5312 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
5313                        RegisterClass srcType, string asm, list<dag> pattern>
5314     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
5315       Sched<[WriteFCvt]> {
5316   bits<5> Rd;
5317   bits<5> Rn;
5318   let Inst{31-24} = 0b00011110;
5319   let Inst{23-22} = type;
5320   let Inst{21-17} = 0b10001;
5321   let Inst{16-15} = opcode;
5322   let Inst{14-10} = 0b10000;
5323   let Inst{9-5}   = Rn;
5324   let Inst{4-0}   = Rd;
5327 multiclass FPConversion<string asm> {
5328   // Double-precision to Half-precision
5329   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
5330                              [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>;
5332   // Double-precision to Single-precision
5333   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
5334                              [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;
5336   // Half-precision to Double-precision
5337   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
5338                              [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>;
5340   // Half-precision to Single-precision
5341   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
5342                              [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>;
5344   // Single-precision to Double-precision
5345   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
5346                              [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>;
5348   // Single-precision to Half-precision
5349   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
5350                              [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>;
5353 //---
5354 // Single operand floating point data processing
5355 //---
5357 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5358 class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype,
5359                               ValueType vt, string asm, SDPatternOperator node>
5360     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
5361          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
5362       Sched<[WriteF]> {
5363   bits<5> Rd;
5364   bits<5> Rn;
5365   let Inst{31-24} = 0b00011110;
5366   let Inst{21}    = 0b1;
5367   let Inst{20-15} = opcode;
5368   let Inst{14-10} = 0b10000;
5369   let Inst{9-5}   = Rn;
5370   let Inst{4-0}   = Rd;
5373 multiclass SingleOperandFPData<bits<4> opcode, string asm,
5374                                SDPatternOperator node = null_frag,
5375                                int fpexceptions = 1> {
5376   let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in {
5377   def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> {
5378     let Inst{23-22} = 0b11; // 16-bit size flag
5379     let Predicates = [HasFullFP16];
5380   }
5382   def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {
5383     let Inst{23-22} = 0b00; // 32-bit size flag
5384   }
5386   def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {
5387     let Inst{23-22} = 0b01; // 64-bit size flag
5388   }
5389   }
5392 multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm,
5393                                        SDPatternOperator node = null_frag>
5394     : SingleOperandFPData<opcode, asm, node, 0>;
5396 let mayRaiseFPException = 1, Uses = [FPCR] in
5397 multiclass SingleOperandFPNo16<bits<6> opcode, string asm,
5398                   SDPatternOperator node = null_frag>{
5400   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
5401     let Inst{23-22} = 0b00; // 32-bit registers
5402   }
5404   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
5405     let Inst{23-22} = 0b01; // 64-bit registers
5406   }
5409 // FRInt[32|64][Z|N] instructions
5410 multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> :
5411       SingleOperandFPNo16<{0b0100,opcode}, asm, node>;
5413 //---
5414 // Two operand floating point data processing
5415 //---
5417 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
5418 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
5419                            string asm, list<dag> pat>
5420     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
5421          asm, "\t$Rd, $Rn, $Rm", "", pat>,
5422       Sched<[WriteF]> {
5423   bits<5> Rd;
5424   bits<5> Rn;
5425   bits<5> Rm;
5426   let Inst{31-24} = 0b00011110;
5427   let Inst{21}    = 1;
5428   let Inst{20-16} = Rm;
5429   let Inst{15-12} = opcode;
5430   let Inst{11-10} = 0b10;
5431   let Inst{9-5}   = Rn;
5432   let Inst{4-0}   = Rd;
5435 multiclass TwoOperandFPData<bits<4> opcode, string asm,
5436                             SDPatternOperator node = null_frag> {
5437   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
5438                          [(set (f16 FPR16:$Rd),
5439                                (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
5440     let Inst{23-22} = 0b11; // 16-bit size flag
5441     let Predicates = [HasFullFP16];
5442   }
5444   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
5445                          [(set (f32 FPR32:$Rd),
5446                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
5447     let Inst{23-22} = 0b00; // 32-bit size flag
5448   }
5450   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
5451                          [(set (f64 FPR64:$Rd),
5452                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
5453     let Inst{23-22} = 0b01; // 64-bit size flag
5454   }
5457 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm,
5458                                SDPatternOperator node> {
5459   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
5460                   [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> {
5461     let Inst{23-22} = 0b11; // 16-bit size flag
5462     let Predicates = [HasFullFP16];
5463   }
5465   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
5466                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
5467     let Inst{23-22} = 0b00; // 32-bit size flag
5468   }
5470   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
5471                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
5472     let Inst{23-22} = 0b01; // 64-bit size flag
5473   }
5477 //---
5478 // Three operand floating point data processing
5479 //---
5481 let mayRaiseFPException = 1, Uses = [FPCR] in
5482 class BaseThreeOperandFPData<bit isNegated, bit isSub,
5483                              RegisterClass regtype, string asm, list<dag> pat>
5484     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
5485          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
5486       Sched<[WriteFMul]> {
5487   bits<5> Rd;
5488   bits<5> Rn;
5489   bits<5> Rm;
5490   bits<5> Ra;
5491   let Inst{31-24} = 0b00011111;
5492   let Inst{21}    = isNegated;
5493   let Inst{20-16} = Rm;
5494   let Inst{15}    = isSub;
5495   let Inst{14-10} = Ra;
5496   let Inst{9-5}   = Rn;
5497   let Inst{4-0}   = Rd;
5500 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
5501                               SDPatternOperator node> {
5502   def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
5503             [(set (f16 FPR16:$Rd),
5504                   (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
5505     let Inst{23-22} = 0b11; // 16-bit size flag
5506     let Predicates = [HasFullFP16];
5507   }
5509   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
5510             [(set FPR32:$Rd,
5511                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
5512     let Inst{23-22} = 0b00; // 32-bit size flag
5513   }
5515   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
5516             [(set FPR64:$Rd,
5517                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
5518     let Inst{23-22} = 0b01; // 64-bit size flag
5519   }
5521   let Predicates = [HasFullFP16] in {
5522   def : Pat<(f16 (node (f16 FPR16:$Rn),
5523                        (f16 (extractelt (v8f16 V128:$Rm), (i64 0))),
5524                        (f16 FPR16:$Ra))),
5525             (!cast<Instruction>(NAME # Hrrr)
5526               FPR16:$Rn, (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>;
5528   def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))),
5529                        (f16 FPR16:$Rm),
5530                        (f16 FPR16:$Ra))),
5531             (!cast<Instruction>(NAME # Hrrr)
5532               (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), FPR16:$Rm, FPR16:$Ra)>;
5533   }
5535   def : Pat<(f32 (node (f32 FPR32:$Rn),
5536                        (f32 (extractelt (v4f32 V128:$Rm), (i64 0))),
5537                        (f32 FPR32:$Ra))),
5538             (!cast<Instruction>(NAME # Srrr)
5539               FPR32:$Rn, (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>;
5541   def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))),
5542                        (f32 FPR32:$Rm),
5543                        (f32 FPR32:$Ra))),
5544             (!cast<Instruction>(NAME # Srrr)
5545               (EXTRACT_SUBREG V128:$Rn, ssub), FPR32:$Rm, FPR32:$Ra)>;
5547   def : Pat<(f64 (node (f64 FPR64:$Rn),
5548                        (f64 (extractelt (v2f64 V128:$Rm), (i64 0))),
5549                        (f64 FPR64:$Ra))),
5550             (!cast<Instruction>(NAME # Drrr)
5551               FPR64:$Rn, (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>;
5553   def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))),
5554                        (f64 FPR64:$Rm),
5555                        (f64 FPR64:$Ra))),
5556             (!cast<Instruction>(NAME # Drrr)
5557               (EXTRACT_SUBREG V128:$Rn, dsub), FPR64:$Rm, FPR64:$Ra)>;
5560 //---
5561 // Floating point data comparisons
5562 //---
5564 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
5565 class BaseOneOperandFPComparison<bit signalAllNans,
5566                                  RegisterClass regtype, string asm,
5567                                  list<dag> pat>
5568     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
5569       Sched<[WriteFCmp]> {
5570   bits<5> Rn;
5571   let Inst{31-24} = 0b00011110;
5572   let Inst{21}    = 1;
5574   let Inst{15-10} = 0b001000;
5575   let Inst{9-5}   = Rn;
5576   let Inst{4}     = signalAllNans;
5577   let Inst{3-0}   = 0b1000;
5579   // Rm should be 0b00000 canonically, but we need to accept any value.
5580   let PostEncoderMethod = "fixOneOperandFPComparison";
5583 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
5584 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
5585                                 string asm, list<dag> pat>
5586     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
5587       Sched<[WriteFCmp]> {
5588   bits<5> Rm;
5589   bits<5> Rn;
5590   let Inst{31-24} = 0b00011110;
5591   let Inst{21}    = 1;
5592   let Inst{20-16} = Rm;
5593   let Inst{15-10} = 0b001000;
5594   let Inst{9-5}   = Rn;
5595   let Inst{4}     = signalAllNans;
5596   let Inst{3-0}   = 0b0000;
5599 multiclass FPComparison<bit signalAllNans, string asm,
5600                         SDPatternOperator OpNode = null_frag> {
5601   let Defs = [NZCV] in {
5602   def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
5603       [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> {
5604     let Inst{23-22} = 0b11;
5605     let Predicates = [HasFullFP16];
5606   }
5608   def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
5609       [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
5610     let Inst{23-22} = 0b11;
5611     let Predicates = [HasFullFP16];
5612   }
5614   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
5615       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
5616     let Inst{23-22} = 0b00;
5617   }
5619   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
5620       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
5621     let Inst{23-22} = 0b00;
5622   }
5624   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
5625       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
5626     let Inst{23-22} = 0b01;
5627   }
5629   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
5630       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
5631     let Inst{23-22} = 0b01;
5632   }
5633   } // Defs = [NZCV]
5636 //---
5637 // Floating point conditional comparisons
5638 //---
5640 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
5641 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
5642                            string mnemonic, list<dag> pat>
5643     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
5644          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
5645       Sched<[WriteFCmp]> {
5646   let Uses = [NZCV];
5647   let Defs = [NZCV];
5649   bits<5> Rn;
5650   bits<5> Rm;
5651   bits<4> nzcv;
5652   bits<4> cond;
5654   let Inst{31-24} = 0b00011110;
5655   let Inst{21}    = 1;
5656   let Inst{20-16} = Rm;
5657   let Inst{15-12} = cond;
5658   let Inst{11-10} = 0b01;
5659   let Inst{9-5}   = Rn;
5660   let Inst{4}     = signalAllNans;
5661   let Inst{3-0}   = nzcv;
5664 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
5665                             SDPatternOperator OpNode = null_frag> {
5666   def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,
5667       [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),
5668                           (i32 imm:$cond), NZCV))]> {
5669     let Inst{23-22} = 0b11;
5670     let Predicates = [HasFullFP16];
5671   }
5673   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
5674       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
5675                           (i32 imm:$cond), NZCV))]> {
5676     let Inst{23-22} = 0b00;
5677   }
5679   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
5680       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
5681                           (i32 imm:$cond), NZCV))]> {
5682     let Inst{23-22} = 0b01;
5683   }
5686 //---
5687 // Floating point conditional select
5688 //---
5690 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
5691     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
5692          asm, "\t$Rd, $Rn, $Rm, $cond", "",
5693          [(set regtype:$Rd,
5694                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
5695                           (i32 imm:$cond), NZCV))]>,
5696       Sched<[WriteF]> {
5697   bits<5> Rd;
5698   bits<5> Rn;
5699   bits<5> Rm;
5700   bits<4> cond;
5702   let Inst{31-24} = 0b00011110;
5703   let Inst{21}    = 1;
5704   let Inst{20-16} = Rm;
5705   let Inst{15-12} = cond;
5706   let Inst{11-10} = 0b11;
5707   let Inst{9-5}   = Rn;
5708   let Inst{4-0}   = Rd;
5711 multiclass FPCondSelect<string asm> {
5712   let Uses = [NZCV] in {
5713   def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
5714     let Inst{23-22} = 0b11;
5715     let Predicates = [HasFullFP16];
5716   }
5718   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
5719     let Inst{23-22} = 0b00;
5720   }
5722   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
5723     let Inst{23-22} = 0b01;
5724   }
5725   } // Uses = [NZCV]
5728 //---
5729 // Floating move immediate
5730 //---
5732 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
5733   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
5734       [(set regtype:$Rd, fpimmtype:$imm)]>,
5735     Sched<[WriteFImm]> {
5736   bits<5> Rd;
5737   bits<8> imm;
5738   let Inst{31-24} = 0b00011110;
5739   let Inst{21}    = 1;
5740   let Inst{20-13} = imm;
5741   let Inst{12-5}  = 0b10000000;
5742   let Inst{4-0}   = Rd;
5745 multiclass FPMoveImmediate<string asm> {
5746   def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
5747     let Inst{23-22} = 0b11;
5748     let Predicates = [HasFullFP16];
5749   }
5751   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
5752     let Inst{23-22} = 0b00;
5753   }
5755   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
5756     let Inst{23-22} = 0b01;
5757   }
5759 } // end of 'let Predicates = [HasFPARMv8]'
5761 //----------------------------------------------------------------------------
5762 // AdvSIMD
5763 //----------------------------------------------------------------------------
5765 let Predicates = [HasNEON] in {
5767 //----------------------------------------------------------------------------
5768 // AdvSIMD three register vector instructions
5769 //----------------------------------------------------------------------------
5771 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5772 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
5773                         RegisterOperand regtype, string asm, string kind,
5774                         list<dag> pattern>
5775   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5776       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5777       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
5778     Sched<[!if(Q, WriteVq, WriteVd)]> {
5779   bits<5> Rd;
5780   bits<5> Rn;
5781   bits<5> Rm;
5782   let Inst{31}    = 0;
5783   let Inst{30}    = Q;
5784   let Inst{29}    = U;
5785   let Inst{28-24} = 0b01110;
5786   let Inst{23-21} = size;
5787   let Inst{20-16} = Rm;
5788   let Inst{15-11} = opcode;
5789   let Inst{10}    = 1;
5790   let Inst{9-5}   = Rn;
5791   let Inst{4-0}   = Rd;
5794 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5795 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
5796                         RegisterOperand regtype, string asm, string kind,
5797                         list<dag> pattern>
5798   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
5799       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5800       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5801     Sched<[!if(Q, WriteVq, WriteVd)]> {
5802   bits<5> Rd;
5803   bits<5> Rn;
5804   bits<5> Rm;
5805   let Inst{31}    = 0;
5806   let Inst{30}    = Q;
5807   let Inst{29}    = U;
5808   let Inst{28-24} = 0b01110;
5809   let Inst{23-21} = size;
5810   let Inst{20-16} = Rm;
5811   let Inst{15-11} = opcode;
5812   let Inst{10}    = 1;
5813   let Inst{9-5}   = Rn;
5814   let Inst{4-0}   = Rd;
5817 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5818 class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern>
5819   : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>,
5820     Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>;
5822 multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> {
5823   def v8i8  : BaseSIMDThreeSameVectorPseudo<V64,
5824              [(set (v8i8 V64:$dst),
5825                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5826   def v16i8  : BaseSIMDThreeSameVectorPseudo<V128,
5827              [(set (v16i8 V128:$dst),
5828                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5829                            (v16i8 V128:$Rm)))]>;
5831   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5832                            (v4i16 V64:$RHS))),
5833           (!cast<Instruction>(NAME#"v8i8")
5834             V64:$LHS, V64:$MHS, V64:$RHS)>;
5835   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5836                            (v2i32 V64:$RHS))),
5837           (!cast<Instruction>(NAME#"v8i8")
5838             V64:$LHS, V64:$MHS, V64:$RHS)>;
5839   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5840                            (v1i64 V64:$RHS))),
5841           (!cast<Instruction>(NAME#"v8i8")
5842             V64:$LHS, V64:$MHS, V64:$RHS)>;
5844   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5845                            (v8i16 V128:$RHS))),
5846       (!cast<Instruction>(NAME#"v16i8")
5847         V128:$LHS, V128:$MHS, V128:$RHS)>;
5848   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5849                            (v4i32 V128:$RHS))),
5850       (!cast<Instruction>(NAME#"v16i8")
5851         V128:$LHS, V128:$MHS, V128:$RHS)>;
5852   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5853                            (v2i64 V128:$RHS))),
5854       (!cast<Instruction>(NAME#"v16i8")
5855         V128:$LHS, V128:$MHS, V128:$RHS)>;
5858 // All operand sizes distinguished in the encoding.
5859 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
5860                                SDPatternOperator OpNode> {
5861   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5862                                       asm, ".8b",
5863          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5864   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5865                                       asm, ".16b",
5866          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5867   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5868                                       asm, ".4h",
5869          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5870   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5871                                       asm, ".8h",
5872          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5873   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5874                                       asm, ".2s",
5875          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5876   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5877                                       asm, ".4s",
5878          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5879   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
5880                                       asm, ".2d",
5881          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5884 multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> {
5885   def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)),
5886           (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>;
5887   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5888           (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>;
5889   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5890           (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>;
5892   def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)),
5893           (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>;
5894   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5895           (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>;
5896   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5897           (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>;
5898   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5899           (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>;
5902 // As above, but D sized elements unsupported.
5903 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
5904                                   SDPatternOperator OpNode> {
5905   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5906                                       asm, ".8b",
5907         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
5908   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5909                                       asm, ".16b",
5910         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
5911   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5912                                       asm, ".4h",
5913         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
5914   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5915                                       asm, ".8h",
5916         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
5917   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5918                                       asm, ".2s",
5919         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
5920   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5921                                       asm, ".4s",
5922         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
5925 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
5926                                   SDPatternOperator OpNode> {
5927   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
5928                                       asm, ".8b",
5929       [(set (v8i8 V64:$dst),
5930             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5931   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
5932                                       asm, ".16b",
5933       [(set (v16i8 V128:$dst),
5934             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5935   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
5936                                       asm, ".4h",
5937       [(set (v4i16 V64:$dst),
5938             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5939   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
5940                                       asm, ".8h",
5941       [(set (v8i16 V128:$dst),
5942             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5943   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
5944                                       asm, ".2s",
5945       [(set (v2i32 V64:$dst),
5946             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5947   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
5948                                       asm, ".4s",
5949       [(set (v4i32 V128:$dst),
5950             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5953 // As above, but only B sized elements supported.
5954 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
5955                                 SDPatternOperator OpNode> {
5956   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5957                                       asm, ".8b",
5958     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5959   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5960                                       asm, ".16b",
5961     [(set (v16i8 V128:$Rd),
5962           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5965 // As above, but only floating point elements supported.
5966 let mayRaiseFPException = 1, Uses = [FPCR] in
5967 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
5968                                  string asm, SDPatternOperator OpNode> {
5969   let Predicates = [HasNEON, HasFullFP16] in {
5970   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5971                                       asm, ".4h",
5972         [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5973   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5974                                       asm, ".8h",
5975         [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5976   } // Predicates = [HasNEON, HasFullFP16]
5977   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5978                                       asm, ".2s",
5979         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5980   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5981                                       asm, ".4s",
5982         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5983   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5984                                       asm, ".2d",
5985         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5988 let mayRaiseFPException = 1, Uses = [FPCR] in
5989 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
5990                                     string asm,
5991                                     SDPatternOperator OpNode> {
5992   let Predicates = [HasNEON, HasFullFP16] in {
5993   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5994                                       asm, ".4h",
5995         [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5996   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5997                                       asm, ".8h",
5998         [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5999   } // Predicates = [HasNEON, HasFullFP16]
6000   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
6001                                       asm, ".2s",
6002         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
6003   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
6004                                       asm, ".4s",
6005         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
6006   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
6007                                       asm, ".2d",
6008         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
6011 let mayRaiseFPException = 1, Uses = [FPCR] in
6012 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
6013                                  string asm, SDPatternOperator OpNode> {
6014   let Predicates = [HasNEON, HasFullFP16] in {
6015   def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
6016                                       asm, ".4h",
6017      [(set (v4f16 V64:$dst),
6018            (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
6019   def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
6020                                       asm, ".8h",
6021      [(set (v8f16 V128:$dst),
6022            (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
6023   } // Predicates = [HasNEON, HasFullFP16]
6024   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
6025                                       asm, ".2s",
6026      [(set (v2f32 V64:$dst),
6027            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
6028   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
6029                                       asm, ".4s",
6030      [(set (v4f32 V128:$dst),
6031            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
6032   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
6033                                       asm, ".2d",
6034      [(set (v2f64 V128:$dst),
6035            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
6038 // As above, but D and B sized elements unsupported.
6039 let mayRaiseFPException = 1, Uses = [FPCR] in
6040 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
6041                                 SDPatternOperator OpNode> {
6042   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
6043                                       asm, ".4h",
6044         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6045   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
6046                                       asm, ".8h",
6047         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
6048   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
6049                                       asm, ".2s",
6050         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6051   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
6052                                       asm, ".4s",
6053         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
6056 // Logical three vector ops share opcode bits, and only use B sized elements.
6057 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
6058                                   SDPatternOperator OpNode = null_frag> {
6059   def v8i8  : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
6060                                      asm, ".8b",
6061                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
6062   def v16i8  : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
6063                                      asm, ".16b",
6064                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
6066   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
6067           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
6068   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
6069           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
6070   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
6071           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
6073   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
6074       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
6075   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
6076       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
6077   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
6078       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
6081 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
6082                                   string asm, SDPatternOperator OpNode = null_frag> {
6083   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
6084                                      asm, ".8b",
6085              [(set (v8i8 V64:$dst),
6086                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6087   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
6088                                      asm, ".16b",
6089              [(set (v16i8 V128:$dst),
6090                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
6091                            (v16i8 V128:$Rm)))]>;
6093   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
6094                            (v4i16 V64:$RHS))),
6095           (!cast<Instruction>(NAME#"v8i8")
6096             V64:$LHS, V64:$MHS, V64:$RHS)>;
6097   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
6098                            (v2i32 V64:$RHS))),
6099           (!cast<Instruction>(NAME#"v8i8")
6100             V64:$LHS, V64:$MHS, V64:$RHS)>;
6101   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
6102                            (v1i64 V64:$RHS))),
6103           (!cast<Instruction>(NAME#"v8i8")
6104             V64:$LHS, V64:$MHS, V64:$RHS)>;
6106   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
6107                            (v8i16 V128:$RHS))),
6108       (!cast<Instruction>(NAME#"v16i8")
6109         V128:$LHS, V128:$MHS, V128:$RHS)>;
6110   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
6111                            (v4i32 V128:$RHS))),
6112       (!cast<Instruction>(NAME#"v16i8")
6113         V128:$LHS, V128:$MHS, V128:$RHS)>;
6114   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
6115                            (v2i64 V128:$RHS))),
6116       (!cast<Instruction>(NAME#"v16i8")
6117         V128:$LHS, V128:$MHS, V128:$RHS)>;
6120 // ARMv8.2-A Dot Product Instructions (Vector): These instructions extract
6121 // bytes from S-sized elements.
6122 class BaseSIMDThreeSameVectorDot<bit Q, bit U, bits<2> sz, bits<4> opc, string asm,
6123                                  string kind1, string kind2, RegisterOperand RegType,
6124                                  ValueType AccumType, ValueType InputType,
6125                                  SDPatternOperator OpNode> :
6126         BaseSIMDThreeSameVectorTied<Q, U, {sz, 0b0}, {0b1, opc}, RegType, asm, kind1,
6127         [(set (AccumType RegType:$dst),
6128               (OpNode (AccumType RegType:$Rd),
6129                       (InputType RegType:$Rn),
6130                       (InputType RegType:$Rm)))]> {
6131   let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
6134 multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> {
6135   def v8i8  : BaseSIMDThreeSameVectorDot<0, U, 0b10, {0b001, Mixed}, asm, ".2s", ".8b", V64,
6136                                          v2i32, v8i8, OpNode>;
6137   def v16i8 : BaseSIMDThreeSameVectorDot<1, U, 0b10, {0b001, Mixed}, asm, ".4s", ".16b", V128,
6138                                          v4i32, v16i8, OpNode>;
6141 // ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions
6142 // select inputs from 4H vectors and accumulate outputs to a 2S vector (or from
6143 // 8H to 4S, when Q=1).
6144 let mayRaiseFPException = 1, Uses = [FPCR] in
6145 class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1,
6146                                  string kind2, RegisterOperand RegType,
6147                                  ValueType AccumType, ValueType InputType,
6148                                  SDPatternOperator OpNode> :
6149         BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1,
6150                 [(set (AccumType RegType:$dst),
6151               (OpNode (AccumType RegType:$Rd),
6152                       (InputType RegType:$Rn),
6153                       (InputType RegType:$Rm)))]> {
6154   let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
6155   let Inst{13} = b13;
6158 multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,
6159                                   SDPatternOperator OpNode> {
6160   def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64,
6161                                          v2f32, v4f16, OpNode>;
6162   def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128,
6163                                          v4f32, v8f16, OpNode>;
6166 multiclass SIMDThreeSameVectorMLA<bit Q, string asm>{
6167   def v8f16 : BaseSIMDThreeSameVectorDot<Q, 0b0, 0b11, 0b1111, asm, ".8h", ".16b",
6168                                          V128, v8f16, v16i8, null_frag>;
6171 multiclass SIMDThreeSameVectorMLAL<bit Q, bits<2> sz, string asm>{
6172   def v4f32 : BaseSIMDThreeSameVectorDot<Q, 0b0, sz, 0b1000, asm, ".4s", ".16b",
6173                                          V128, v4f32, v16i8, null_frag>;
6176 // FP8 assembly/disassembly classes
6178 //----------------------------------------------------------------------------
6179 // FP8 Advanced SIMD three-register extension
6180 //----------------------------------------------------------------------------
6181 class BaseSIMDThreeVectors<bit Q, bit U, bits<2> size, bits<4> op,
6182                            RegisterOperand regtype1,
6183                            RegisterOperand regtype2, string asm,
6184                            string kind1, string kind2>
6185   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, regtype2:$Rm), asm,
6186       "\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2, "", []>, Sched<[]> {
6187   bits<5> Rd;
6188   bits<5> Rn;
6189   bits<5> Rm;
6190   let Inst{31}    = 0;
6191   let Inst{30}    = Q;
6192   let Inst{29}    = U;
6193   let Inst{28-24} = 0b01110;
6194   let Inst{23-22} = size;
6195   let Inst{21}    = 0b0;
6196   let Inst{20-16} = Rm;
6197   let Inst{15}    = 0b1;
6198   let Inst{14-11} = op;
6199   let Inst{10}    = 0b1;
6200   let Inst{9-5}   = Rn;
6201   let Inst{4-0}   = Rd;
6205 // FCVTN (FP16 to FP8)
6206 multiclass SIMDThreeSameSizeVectorCvt<string asm> {
6207    def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b01, 0b1110, V64, V64, asm, ".8b",".4h">;
6208    def v16f8 : BaseSIMDThreeVectors<0b1, 0b0, 0b01, 0b1110,  V128, V128, asm, ".16b", ".8h">;
6211 // TODO : Create v16f8 value type
6212 // FCVTN, FCVTN2 (FP32 to FP8)
6213 multiclass SIMDThreeVectorCvt<string asm> {
6214    def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b00, 0b1110, V64, V128, asm, ".8b", ".4s">;
6215    def 2v16f8 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1110, asm#2, ".16b", ".4s",
6216                                            V128, v16i8, v4f32, null_frag>;
6219 // TODO: Create a new Value Type v8f8 and v16f8
6220 multiclass SIMDThreeSameVectorDOT2<string asm> {
6221    def v4f16 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b01, 0b1111, asm, ".4h", ".8b",
6222                                           V64, v4f16, v8i8, null_frag>;
6223    def v8f16 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b01, 0b1111, asm, ".8h", ".16b",
6224                                           V128, v8f16, v16i8, null_frag>;
6227 multiclass SIMDThreeSameVectorDOT4<string asm> {
6228    def v2f32 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b00, 0b1111, asm, ".2s", ".8b",
6229                                           V64, v2f32, v8i8, null_frag>;
6230    def v4f32 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1111, asm, ".4s", ".16b",
6231                                           V128, v4f32, v16i8, null_frag>;
6234 //----------------------------------------------------------------------------
6235 // AdvSIMD two register vector instructions.
6236 //----------------------------------------------------------------------------
6238 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6239 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
6240                             bits<2> size2, RegisterOperand regtype, string asm,
6241                             string dstkind, string srckind, list<dag> pattern>
6242   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6243       "{\t$Rd" # dstkind # ", $Rn" # srckind #
6244       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
6245     Sched<[!if(Q, WriteVq, WriteVd)]> {
6246   bits<5> Rd;
6247   bits<5> Rn;
6248   let Inst{31}    = 0;
6249   let Inst{30}    = Q;
6250   let Inst{29}    = U;
6251   let Inst{28-24} = 0b01110;
6252   let Inst{23-22} = size;
6253   let Inst{21} = 0b1;
6254   let Inst{20-19} = size2;
6255   let Inst{18-17} = 0b00;
6256   let Inst{16-12} = opcode;
6257   let Inst{11-10} = 0b10;
6258   let Inst{9-5}   = Rn;
6259   let Inst{4-0}   = Rd;
6262 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6263 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
6264                                 bits<2> size2, RegisterOperand regtype,
6265                                 string asm, string dstkind, string srckind,
6266                                 list<dag> pattern>
6267   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
6268       "{\t$Rd" # dstkind # ", $Rn" # srckind #
6269       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
6270     Sched<[!if(Q, WriteVq, WriteVd)]> {
6271   bits<5> Rd;
6272   bits<5> Rn;
6273   let Inst{31}    = 0;
6274   let Inst{30}    = Q;
6275   let Inst{29}    = U;
6276   let Inst{28-24} = 0b01110;
6277   let Inst{23-22} = size;
6278   let Inst{21} = 0b1;
6279   let Inst{20-19} = size2;
6280   let Inst{18-17} = 0b00;
6281   let Inst{16-12} = opcode;
6282   let Inst{11-10} = 0b10;
6283   let Inst{9-5}   = Rn;
6284   let Inst{4-0}   = Rd;
6287 // Supports B, H, and S element sizes.
6288 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
6289                             SDPatternOperator OpNode> {
6290   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
6291                                       asm, ".8b", ".8b",
6292                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
6293   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
6294                                       asm, ".16b", ".16b",
6295                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
6296   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
6297                                       asm, ".4h", ".4h",
6298                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6299   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
6300                                       asm, ".8h", ".8h",
6301                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6302   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
6303                                       asm, ".2s", ".2s",
6304                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6305   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
6306                                       asm, ".4s", ".4s",
6307                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6310 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
6311                             RegisterOperand regtype, string asm, string dstkind,
6312                             string srckind, string amount>
6313   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
6314       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
6315       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
6316     Sched<[WriteVq]> {
6317   bits<5> Rd;
6318   bits<5> Rn;
6319   let Inst{31}    = 0;
6320   let Inst{30}    = Q;
6321   let Inst{29-24} = 0b101110;
6322   let Inst{23-22} = size;
6323   let Inst{21-10} = 0b100001001110;
6324   let Inst{9-5}   = Rn;
6325   let Inst{4-0}   = Rd;
6328 multiclass SIMDVectorLShiftLongBySizeBHS {
6329   let hasSideEffects = 0 in {
6330   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
6331                                              "shll", ".8h",  ".8b", "8">;
6332   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
6333                                              "shll2", ".8h", ".16b", "8">;
6334   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
6335                                              "shll", ".4s",  ".4h", "16">;
6336   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
6337                                              "shll2", ".4s", ".8h", "16">;
6338   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
6339                                              "shll", ".2d",  ".2s", "32">;
6340   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
6341                                              "shll2", ".2d", ".4s", "32">;
6342   }
6345 // Supports all element sizes.
6346 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
6347                              SDPatternOperator OpNode> {
6348   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
6349                                       asm, ".4h", ".8b",
6350                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
6351   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
6352                                       asm, ".8h", ".16b",
6353                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
6354   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
6355                                       asm, ".2s", ".4h",
6356                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6357   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
6358                                       asm, ".4s", ".8h",
6359                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6360   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
6361                                       asm, ".1d", ".2s",
6362                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6363   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
6364                                       asm, ".2d", ".4s",
6365                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6368 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
6369                                  SDPatternOperator OpNode> {
6370   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
6371                                           asm, ".4h", ".8b",
6372       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
6373                                       (v8i8 V64:$Rn)))]>;
6374   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
6375                                           asm, ".8h", ".16b",
6376       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
6377                                       (v16i8 V128:$Rn)))]>;
6378   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
6379                                           asm, ".2s", ".4h",
6380       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
6381                                       (v4i16 V64:$Rn)))]>;
6382   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
6383                                           asm, ".4s", ".8h",
6384       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
6385                                       (v8i16 V128:$Rn)))]>;
6386   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
6387                                           asm, ".1d", ".2s",
6388       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
6389                                       (v2i32 V64:$Rn)))]>;
6390   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
6391                                           asm, ".2d", ".4s",
6392       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
6393                                       (v4i32 V128:$Rn)))]>;
6396 // Supports all element sizes, except 1xD.
6397 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
6398                                   SDPatternOperator OpNode> {
6399   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
6400                                     asm, ".8b", ".8b",
6401     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
6402   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
6403                                     asm, ".16b", ".16b",
6404     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
6405   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
6406                                     asm, ".4h", ".4h",
6407     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
6408   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
6409                                     asm, ".8h", ".8h",
6410     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
6411   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
6412                                     asm, ".2s", ".2s",
6413     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
6414   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
6415                                     asm, ".4s", ".4s",
6416     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
6417   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
6418                                     asm, ".2d", ".2d",
6419     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
6422 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
6423                              SDPatternOperator OpNode = null_frag> {
6424   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
6425                                 asm, ".8b", ".8b",
6426     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
6427   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
6428                                 asm, ".16b", ".16b",
6429     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
6430   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
6431                                 asm, ".4h", ".4h",
6432     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6433   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
6434                                 asm, ".8h", ".8h",
6435     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6436   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
6437                                 asm, ".2s", ".2s",
6438     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6439   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
6440                                 asm, ".4s", ".4s",
6441     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6442   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
6443                                 asm, ".2d", ".2d",
6444     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
6448 // Supports only B element sizes.
6449 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
6450                           SDPatternOperator OpNode> {
6451   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
6452                                 asm, ".8b", ".8b",
6453                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
6454   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
6455                                 asm, ".16b", ".16b",
6456                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
6460 // Supports only B and H element sizes.
6461 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
6462                                 SDPatternOperator OpNode> {
6463   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
6464                                 asm, ".8b", ".8b",
6465                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
6466   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
6467                                 asm, ".16b", ".16b",
6468                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
6469   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
6470                                 asm, ".4h", ".4h",
6471                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
6472   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
6473                                 asm, ".8h", ".8h",
6474                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
6477 // Supports H, S and D element sizes, uses high bit of the size field
6478 // as an extra opcode bit.
6479 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
6480                            SDPatternOperator OpNode,
6481                            int fpexceptions = 1> {
6482   let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in {
6483   let Predicates = [HasNEON, HasFullFP16] in {
6484   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
6485                                 asm, ".4h", ".4h",
6486                           [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
6487   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6488                                 asm, ".8h", ".8h",
6489                           [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
6490   } // Predicates = [HasNEON, HasFullFP16]
6491   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6492                                 asm, ".2s", ".2s",
6493                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
6494   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6495                                 asm, ".4s", ".4s",
6496                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
6497   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
6498                                 asm, ".2d", ".2d",
6499                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6500   }
6503 multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm,
6504                                       SDPatternOperator OpNode>
6505     : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>;
6507 // Supports only S and D element sizes
6508 let mayRaiseFPException = 1, Uses = [FPCR] in
6509 multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm,
6510                            SDPatternOperator OpNode = null_frag> {
6512   def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64,
6513                                 asm, ".2s", ".2s",
6514                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
6515   def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,
6516                                 asm, ".4s", ".4s",
6517                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
6518   def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,
6519                                 asm, ".2d", ".2d",
6520                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6523 multiclass FRIntNNTVector<bit U, bit op, string asm,
6524                           SDPatternOperator OpNode = null_frag> :
6525            SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>;
6527 // Supports only S element size.
6528 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
6529                            SDPatternOperator OpNode> {
6530   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6531                                 asm, ".2s", ".2s",
6532                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6533   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6534                                 asm, ".4s", ".4s",
6535                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6538 let mayRaiseFPException = 1, Uses = [FPCR] in
6539 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
6540                            SDPatternOperator OpNode> {
6541   let Predicates = [HasNEON, HasFullFP16] in {
6542   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
6543                                 asm, ".4h", ".4h",
6544                           [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
6545   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6546                                 asm, ".8h", ".8h",
6547                           [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
6548   } // Predicates = [HasNEON, HasFullFP16]
6549   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6550                                 asm, ".2s", ".2s",
6551                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
6552   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6553                                 asm, ".4s", ".4s",
6554                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
6555   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
6556                                 asm, ".2d", ".2d",
6557                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6560 let mayRaiseFPException = 1, Uses = [FPCR] in
6561 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
6562                            SDPatternOperator OpNode> {
6563   let Predicates = [HasNEON, HasFullFP16] in {
6564   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
6565                                 asm, ".4h", ".4h",
6566                           [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6567   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6568                                 asm, ".8h", ".8h",
6569                           [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6570   } // Predicates = [HasNEON, HasFullFP16]
6571   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6572                                 asm, ".2s", ".2s",
6573                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6574   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6575                                 asm, ".4s", ".4s",
6576                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6577   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
6578                                 asm, ".2d", ".2d",
6579                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
6582 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6583 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
6584                            RegisterOperand inreg, RegisterOperand outreg,
6585                            string asm, string outkind, string inkind,
6586                            list<dag> pattern>
6587   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
6588       "{\t$Rd" # outkind # ", $Rn" # inkind #
6589       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
6590     Sched<[WriteVq]> {
6591   bits<5> Rd;
6592   bits<5> Rn;
6593   let Inst{31}    = 0;
6594   let Inst{30}    = Q;
6595   let Inst{29}    = U;
6596   let Inst{28-24} = 0b01110;
6597   let Inst{23-22} = size;
6598   let Inst{21-17} = 0b10000;
6599   let Inst{16-12} = opcode;
6600   let Inst{11-10} = 0b10;
6601   let Inst{9-5}   = Rn;
6602   let Inst{4-0}   = Rd;
6605 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6606 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
6607                            RegisterOperand inreg, RegisterOperand outreg,
6608                            string asm, string outkind, string inkind,
6609                            list<dag> pattern>
6610   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
6611       "{\t$Rd" # outkind # ", $Rn" # inkind #
6612       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
6613     Sched<[WriteVq]> {
6614   bits<5> Rd;
6615   bits<5> Rn;
6616   let Inst{31}    = 0;
6617   let Inst{30}    = Q;
6618   let Inst{29}    = U;
6619   let Inst{28-24} = 0b01110;
6620   let Inst{23-22} = size;
6621   let Inst{21-17} = 0b10000;
6622   let Inst{16-12} = opcode;
6623   let Inst{11-10} = 0b10;
6624   let Inst{9-5}   = Rn;
6625   let Inst{4-0}   = Rd;
6628 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
6629                               SDPatternOperator OpNode> {
6630   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
6631                                       asm, ".8b", ".8h",
6632         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6633   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
6634                                       asm#"2", ".16b", ".8h", []>;
6635   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
6636                                       asm, ".4h", ".4s",
6637         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6638   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
6639                                       asm#"2", ".8h", ".4s", []>;
6640   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
6641                                       asm, ".2s", ".2d",
6642         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
6643   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
6644                                       asm#"2", ".4s", ".2d", []>;
6646   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
6647             (!cast<Instruction>(NAME # "v16i8")
6648                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6649   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
6650             (!cast<Instruction>(NAME # "v8i16")
6651                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6652   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
6653             (!cast<Instruction>(NAME # "v4i32")
6654                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6657 //----------------------------------------------------------------------------
6658 // FP8 Advanced SIMD two-register miscellaneous
6659 //----------------------------------------------------------------------------
6660 multiclass SIMDMixedTwoVectorFP8<bits<2>sz, string asm> {
6661   def v8f16 : BaseSIMDMixedTwoVector<0b0, 0b1, sz, 0b10111, V64, V128,
6662                                      asm, ".8h", ".8b", []>;
6663   def 2v8f16 : BaseSIMDMixedTwoVector<0b1, 0b1, sz, 0b10111, V128, V128,
6664                                      asm#2, ".8h", ".16b", []>;
6667 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
6668                            bits<5> opcode, RegisterOperand regtype, string asm,
6669                            string kind, string zero, ValueType dty,
6670                            ValueType sty, SDNode OpNode>
6671   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6672       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
6673       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
6674       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
6675     Sched<[!if(Q, WriteVq, WriteVd)]> {
6676   bits<5> Rd;
6677   bits<5> Rn;
6678   let Inst{31}    = 0;
6679   let Inst{30}    = Q;
6680   let Inst{29}    = U;
6681   let Inst{28-24} = 0b01110;
6682   let Inst{23-22} = size;
6683   let Inst{21} = 0b1;
6684   let Inst{20-19} = size2;
6685   let Inst{18-17} = 0b00;
6686   let Inst{16-12} = opcode;
6687   let Inst{11-10} = 0b10;
6688   let Inst{9-5}   = Rn;
6689   let Inst{4-0}   = Rd;
6692 // Comparisons support all element sizes, except 1xD.
6693 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
6694                             SDNode OpNode> {
6695   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
6696                                      asm, ".8b", "0",
6697                                      v8i8, v8i8, OpNode>;
6698   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
6699                                      asm, ".16b", "0",
6700                                      v16i8, v16i8, OpNode>;
6701   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
6702                                      asm, ".4h", "0",
6703                                      v4i16, v4i16, OpNode>;
6704   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
6705                                      asm, ".8h", "0",
6706                                      v8i16, v8i16, OpNode>;
6707   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
6708                                      asm, ".2s", "0",
6709                                      v2i32, v2i32, OpNode>;
6710   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
6711                                      asm, ".4s", "0",
6712                                      v4i32, v4i32, OpNode>;
6713   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
6714                                      asm, ".2d", "0",
6715                                      v2i64, v2i64, OpNode>;
6718 // FP Comparisons support only S and D element sizes (and H for v8.2a).
6719 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
6720                               string asm, SDNode OpNode> {
6722   let mayRaiseFPException = 1, Uses = [FPCR] in {
6723   let Predicates = [HasNEON, HasFullFP16] in {
6724   def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
6725                                      asm, ".4h", "0.0",
6726                                      v4i16, v4f16, OpNode>;
6727   def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
6728                                      asm, ".8h", "0.0",
6729                                      v8i16, v8f16, OpNode>;
6730   } // Predicates = [HasNEON, HasFullFP16]
6731   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
6732                                      asm, ".2s", "0.0",
6733                                      v2i32, v2f32, OpNode>;
6734   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
6735                                      asm, ".4s", "0.0",
6736                                      v4i32, v4f32, OpNode>;
6737   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
6738                                      asm, ".2d", "0.0",
6739                                      v2i64, v2f64, OpNode>;
6740   }
6742   let Predicates = [HasNEON, HasFullFP16] in {
6743   def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
6744                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6745   def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
6746                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6747   }
6748   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
6749                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6750   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
6751                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6752   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
6753                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6754   let Predicates = [HasNEON, HasFullFP16] in {
6755   def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
6756                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6757   def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
6758                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6759   }
6760   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
6761                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6762   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
6763                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6764   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
6765                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6768 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
6769 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
6770                              RegisterOperand outtype, RegisterOperand intype,
6771                              string asm, string VdTy, string VnTy,
6772                              list<dag> pattern>
6773   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
6774       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
6775     Sched<[WriteVq]> {
6776   bits<5> Rd;
6777   bits<5> Rn;
6778   let Inst{31}    = 0;
6779   let Inst{30}    = Q;
6780   let Inst{29}    = U;
6781   let Inst{28-24} = 0b01110;
6782   let Inst{23-22} = size;
6783   let Inst{21-17} = 0b10000;
6784   let Inst{16-12} = opcode;
6785   let Inst{11-10} = 0b10;
6786   let Inst{9-5}   = Rn;
6787   let Inst{4-0}   = Rd;
6790 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
6791 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
6792                              RegisterOperand outtype, RegisterOperand intype,
6793                              string asm, string VdTy, string VnTy,
6794                              list<dag> pattern>
6795   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
6796       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
6797     Sched<[WriteVq]> {
6798   bits<5> Rd;
6799   bits<5> Rn;
6800   let Inst{31}    = 0;
6801   let Inst{30}    = Q;
6802   let Inst{29}    = U;
6803   let Inst{28-24} = 0b01110;
6804   let Inst{23-22} = size;
6805   let Inst{21-17} = 0b10000;
6806   let Inst{16-12} = opcode;
6807   let Inst{11-10} = 0b10;
6808   let Inst{9-5}   = Rn;
6809   let Inst{4-0}   = Rd;
6812 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
6813   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
6814                                     asm, ".4s", ".4h", []>;
6815   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
6816                                     asm#"2", ".4s", ".8h", []>;
6817   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
6818                                     asm, ".2d", ".2s", []>;
6819   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
6820                                     asm#"2", ".2d", ".4s", []>;
6823 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
6824   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
6825                                     asm, ".4h", ".4s", []>;
6826   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
6827                                     asm#"2", ".8h", ".4s", []>;
6828   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6829                                     asm, ".2s", ".2d", []>;
6830   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6831                                     asm#"2", ".4s", ".2d", []>;
6834 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
6835                                      SDPatternOperator OpNode> {
6836   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6837                                      asm, ".2s", ".2d",
6838                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6839   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6840                                     asm#"2", ".4s", ".2d", []>;
6842   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
6843             (!cast<Instruction>(NAME # "v4f32")
6844                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6847 //----------------------------------------------------------------------------
6848 // AdvSIMD three register different-size vector instructions.
6849 //----------------------------------------------------------------------------
6851 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6852 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
6853                       RegisterOperand outtype, RegisterOperand intype1,
6854                       RegisterOperand intype2, string asm,
6855                       string outkind, string inkind1, string inkind2,
6856                       list<dag> pattern>
6857   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
6858       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6859       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
6860     Sched<[WriteVq]> {
6861   bits<5> Rd;
6862   bits<5> Rn;
6863   bits<5> Rm;
6864   let Inst{31}    = 0;
6865   let Inst{30}    = size{0};
6866   let Inst{29}    = U;
6867   let Inst{28-24} = 0b01110;
6868   let Inst{23-22} = size{2-1};
6869   let Inst{21}    = 1;
6870   let Inst{20-16} = Rm;
6871   let Inst{15-12} = opcode;
6872   let Inst{11-10} = 0b00;
6873   let Inst{9-5}   = Rn;
6874   let Inst{4-0}   = Rd;
6877 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6878 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
6879                       RegisterOperand outtype, RegisterOperand intype1,
6880                       RegisterOperand intype2, string asm,
6881                       string outkind, string inkind1, string inkind2,
6882                       list<dag> pattern>
6883   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
6884       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6885       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
6886     Sched<[WriteVq]> {
6887   bits<5> Rd;
6888   bits<5> Rn;
6889   bits<5> Rm;
6890   let Inst{31}    = 0;
6891   let Inst{30}    = size{0};
6892   let Inst{29}    = U;
6893   let Inst{28-24} = 0b01110;
6894   let Inst{23-22} = size{2-1};
6895   let Inst{21}    = 1;
6896   let Inst{20-16} = Rm;
6897   let Inst{15-12} = opcode;
6898   let Inst{11-10} = 0b00;
6899   let Inst{9-5}   = Rn;
6900   let Inst{4-0}   = Rd;
6903 // FIXME: TableGen doesn't know how to deal with expanded types that also
6904 //        change the element count (in this case, placing the results in
6905 //        the high elements of the result register rather than the low
6906 //        elements). Until that's fixed, we can't code-gen those.
6907 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
6908                                     Intrinsic IntOp> {
6909   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6910                                                   V64, V128, V128,
6911                                                   asm, ".8b", ".8h", ".8h",
6912      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
6913   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6914                                                   V128, V128, V128,
6915                                                   asm#"2", ".16b", ".8h", ".8h",
6916      []>;
6917   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6918                                                   V64, V128, V128,
6919                                                   asm, ".4h", ".4s", ".4s",
6920      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
6921   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6922                                                   V128, V128, V128,
6923                                                   asm#"2", ".8h", ".4s", ".4s",
6924      []>;
6925   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6926                                                   V64, V128, V128,
6927                                                   asm, ".2s", ".2d", ".2d",
6928      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
6929   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6930                                                   V128, V128, V128,
6931                                                   asm#"2", ".4s", ".2d", ".2d",
6932      []>;
6935   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
6936   // a version attached to an instruction.
6937   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
6938                                                    (v8i16 V128:$Rm))),
6939             (!cast<Instruction>(NAME # "v8i16_v16i8")
6940                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6941                 V128:$Rn, V128:$Rm)>;
6942   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
6943                                                     (v4i32 V128:$Rm))),
6944             (!cast<Instruction>(NAME # "v4i32_v8i16")
6945                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6946                 V128:$Rn, V128:$Rm)>;
6947   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
6948                                                     (v2i64 V128:$Rm))),
6949             (!cast<Instruction>(NAME # "v2i64_v4i32")
6950                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6951                 V128:$Rn, V128:$Rm)>;
6954 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
6955                                       SDPatternOperator OpNode> {
6956   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6957                                             V128, V64, V64,
6958                                             asm, ".8h", ".8b", ".8b",
6959       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6960   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6961                                             V128, V128, V128,
6962                                             asm#"2", ".8h", ".16b", ".16b", []>;
6963   let Predicates = [HasAES] in {
6964     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
6965                                               V128, V64, V64,
6966                                               asm, ".1q", ".1d", ".1d",
6967         [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>;
6968     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
6969                                               V128, V128, V128,
6970                                               asm#"2", ".1q", ".2d", ".2d",
6971         [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)),
6972                                         (extract_high_v2i64 (v2i64 V128:$Rm))))]>;
6973   }
6975   def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))),
6976                           (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))),
6977       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
6980 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
6981                                  SDPatternOperator OpNode> {
6982   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6983                                                   V128, V64, V64,
6984                                                   asm, ".4s", ".4h", ".4h",
6985       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6986   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6987                                                   V128, V128, V128,
6988                                                   asm#"2", ".4s", ".8h", ".8h",
6989       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),
6990                                       (extract_high_v8i16 (v8i16 V128:$Rm))))]>;
6991   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6992                                                   V128, V64, V64,
6993                                                   asm, ".2d", ".2s", ".2s",
6994       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6995   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6996                                                   V128, V128, V128,
6997                                                   asm#"2", ".2d", ".4s", ".4s",
6998       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),
6999                                       (extract_high_v4i32 (v4i32 V128:$Rm))))]>;
7002 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
7003                                   SDPatternOperator OpNode = null_frag> {
7004   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
7005                                                   V128, V64, V64,
7006                                                   asm, ".8h", ".8b", ".8b",
7007       [(set (v8i16 V128:$Rd),
7008             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
7009   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
7010                                                  V128, V128, V128,
7011                                                  asm#"2", ".8h", ".16b", ".16b",
7012       [(set (v8i16 V128:$Rd),
7013             (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)),
7014                                 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>;
7015   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
7016                                                   V128, V64, V64,
7017                                                   asm, ".4s", ".4h", ".4h",
7018       [(set (v4i32 V128:$Rd),
7019             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
7020   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
7021                                                   V128, V128, V128,
7022                                                   asm#"2", ".4s", ".8h", ".8h",
7023       [(set (v4i32 V128:$Rd),
7024             (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),
7025                                   (extract_high_v8i16 (v8i16 V128:$Rm))))))]>;
7026   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
7027                                                   V128, V64, V64,
7028                                                   asm, ".2d", ".2s", ".2s",
7029       [(set (v2i64 V128:$Rd),
7030             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
7031   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
7032                                                   V128, V128, V128,
7033                                                   asm#"2", ".2d", ".4s", ".4s",
7034       [(set (v2i64 V128:$Rd),
7035             (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),
7036                                  (extract_high_v4i32 (v4i32 V128:$Rm))))))]>;
7039 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
7040                                           string asm,
7041                                           SDPatternOperator OpNode> {
7042   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
7043                                                   V128, V64, V64,
7044                                                   asm, ".8h", ".8b", ".8b",
7045     [(set (v8i16 V128:$dst),
7046           (add (v8i16 V128:$Rd),
7047                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
7048   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
7049                                                  V128, V128, V128,
7050                                                  asm#"2", ".8h", ".16b", ".16b",
7051     [(set (v8i16 V128:$dst),
7052           (add (v8i16 V128:$Rd),
7053                (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)),
7054                                    (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>;
7055   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
7056                                                   V128, V64, V64,
7057                                                   asm, ".4s", ".4h", ".4h",
7058     [(set (v4i32 V128:$dst),
7059           (add (v4i32 V128:$Rd),
7060                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
7061   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
7062                                                   V128, V128, V128,
7063                                                   asm#"2", ".4s", ".8h", ".8h",
7064     [(set (v4i32 V128:$dst),
7065           (add (v4i32 V128:$Rd),
7066                (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),
7067                                     (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>;
7068   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
7069                                                   V128, V64, V64,
7070                                                   asm, ".2d", ".2s", ".2s",
7071     [(set (v2i64 V128:$dst),
7072           (add (v2i64 V128:$Rd),
7073                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
7074   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
7075                                                   V128, V128, V128,
7076                                                   asm#"2", ".2d", ".4s", ".4s",
7077     [(set (v2i64 V128:$dst),
7078           (add (v2i64 V128:$Rd),
7079                (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),
7080                                     (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>;
7083 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
7084                                   SDPatternOperator OpNode = null_frag> {
7085   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
7086                                                   V128, V64, V64,
7087                                                   asm, ".8h", ".8b", ".8b",
7088       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
7089   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
7090                                                  V128, V128, V128,
7091                                                  asm#"2", ".8h", ".16b", ".16b",
7092       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)),
7093                                       (extract_high_v16i8 (v16i8 V128:$Rm))))]>;
7094   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
7095                                                   V128, V64, V64,
7096                                                   asm, ".4s", ".4h", ".4h",
7097       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
7098   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
7099                                                   V128, V128, V128,
7100                                                   asm#"2", ".4s", ".8h", ".8h",
7101       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),
7102                                       (extract_high_v8i16 (v8i16 V128:$Rm))))]>;
7103   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
7104                                                   V128, V64, V64,
7105                                                   asm, ".2d", ".2s", ".2s",
7106       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
7107   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
7108                                                   V128, V128, V128,
7109                                                   asm#"2", ".2d", ".4s", ".4s",
7110       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),
7111                                       (extract_high_v4i32 (v4i32 V128:$Rm))))]>;
7114 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
7115                                       string asm,
7116                                       SDPatternOperator OpNode> {
7117   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
7118                                                   V128, V64, V64,
7119                                                   asm, ".8h", ".8b", ".8b",
7120     [(set (v8i16 V128:$dst),
7121           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
7122   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
7123                                                  V128, V128, V128,
7124                                                  asm#"2", ".8h", ".16b", ".16b",
7125     [(set (v8i16 V128:$dst),
7126           (OpNode (v8i16 V128:$Rd),
7127                   (extract_high_v16i8 (v16i8 V128:$Rn)),
7128                   (extract_high_v16i8 (v16i8 V128:$Rm))))]>;
7129   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
7130                                                   V128, V64, V64,
7131                                                   asm, ".4s", ".4h", ".4h",
7132     [(set (v4i32 V128:$dst),
7133           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
7134   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
7135                                                   V128, V128, V128,
7136                                                   asm#"2", ".4s", ".8h", ".8h",
7137     [(set (v4i32 V128:$dst),
7138           (OpNode (v4i32 V128:$Rd),
7139                   (extract_high_v8i16 (v8i16 V128:$Rn)),
7140                   (extract_high_v8i16 (v8i16 V128:$Rm))))]>;
7141   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
7142                                                   V128, V64, V64,
7143                                                   asm, ".2d", ".2s", ".2s",
7144     [(set (v2i64 V128:$dst),
7145           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
7146   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
7147                                                   V128, V128, V128,
7148                                                   asm#"2", ".2d", ".4s", ".4s",
7149     [(set (v2i64 V128:$dst),
7150           (OpNode (v2i64 V128:$Rd),
7151                   (extract_high_v4i32 (v4i32 V128:$Rn)),
7152                   (extract_high_v4i32 (v4i32 V128:$Rm))))]>;
7155 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
7156                                            SDPatternOperator Accum> {
7157   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
7158                                                   V128, V64, V64,
7159                                                   asm, ".4s", ".4h", ".4h",
7160     [(set (v4i32 V128:$dst),
7161           (Accum (v4i32 V128:$Rd),
7162                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7163                                                 (v4i16 V64:$Rm)))))]>;
7164   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
7165                                                   V128, V128, V128,
7166                                                   asm#"2", ".4s", ".8h", ".8h",
7167     [(set (v4i32 V128:$dst),
7168           (Accum (v4i32 V128:$Rd),
7169                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)),
7170                                             (extract_high_v8i16 (v8i16 V128:$Rm))))))]>;
7171   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
7172                                                   V128, V64, V64,
7173                                                   asm, ".2d", ".2s", ".2s",
7174     [(set (v2i64 V128:$dst),
7175           (Accum (v2i64 V128:$Rd),
7176                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
7177                                                 (v2i32 V64:$Rm)))))]>;
7178   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
7179                                                   V128, V128, V128,
7180                                                   asm#"2", ".2d", ".4s", ".4s",
7181     [(set (v2i64 V128:$dst),
7182           (Accum (v2i64 V128:$Rd),
7183                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)),
7184                                             (extract_high_v4i32 (v4i32 V128:$Rm))))))]>;
7187 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
7188                                   SDPatternOperator OpNode> {
7189   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
7190                                                   V128, V128, V64,
7191                                                   asm, ".8h", ".8h", ".8b",
7192        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
7193   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
7194                                                   V128, V128, V128,
7195                                                   asm#"2", ".8h", ".8h", ".16b",
7196        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7197                                        (extract_high_v16i8 (v16i8 V128:$Rm))))]>;
7198   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
7199                                                   V128, V128, V64,
7200                                                   asm, ".4s", ".4s", ".4h",
7201        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
7202   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
7203                                                   V128, V128, V128,
7204                                                   asm#"2", ".4s", ".4s", ".8h",
7205        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7206                                        (extract_high_v8i16 (v8i16 V128:$Rm))))]>;
7207   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
7208                                                   V128, V128, V64,
7209                                                   asm, ".2d", ".2d", ".2s",
7210        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
7211   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
7212                                                   V128, V128, V128,
7213                                                   asm#"2", ".2d", ".2d", ".4s",
7214        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7215                                        (extract_high_v4i32 (v4i32 V128:$Rm))))]>;
7218 //----------------------------------------------------------------------------
7219 // AdvSIMD bitwise extract from vector
7220 //----------------------------------------------------------------------------
7222 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
7223                              string asm, string kind>
7224   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
7225       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
7226       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
7227       [(set (vty regtype:$Rd),
7228             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
7229     Sched<[!if(size, WriteVq, WriteVd)]> {
7230   bits<5> Rd;
7231   bits<5> Rn;
7232   bits<5> Rm;
7233   bits<4> imm;
7234   let Inst{31}    = 0;
7235   let Inst{30}    = size;
7236   let Inst{29-21} = 0b101110000;
7237   let Inst{20-16} = Rm;
7238   let Inst{15}    = 0;
7239   let Inst{14-11} = imm;
7240   let Inst{10}    = 0;
7241   let Inst{9-5}   = Rn;
7242   let Inst{4-0}   = Rd;
7246 multiclass SIMDBitwiseExtract<string asm> {
7247   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
7248     let imm{3} = 0;
7249   }
7250   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
7253 //----------------------------------------------------------------------------
7254 // AdvSIMD zip vector
7255 //----------------------------------------------------------------------------
7257 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
7258                         string asm, string kind, SDNode OpNode, ValueType valty>
7259   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
7260       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
7261       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
7262       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
7263     Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> {
7264   bits<5> Rd;
7265   bits<5> Rn;
7266   bits<5> Rm;
7267   let Inst{31}    = 0;
7268   let Inst{30}    = size{0};
7269   let Inst{29-24} = 0b001110;
7270   let Inst{23-22} = size{2-1};
7271   let Inst{21}    = 0;
7272   let Inst{20-16} = Rm;
7273   let Inst{15}    = 0;
7274   let Inst{14-12} = opc;
7275   let Inst{11-10} = 0b10;
7276   let Inst{9-5}   = Rn;
7277   let Inst{4-0}   = Rd;
7280 multiclass SIMDZipVector<bits<3>opc, string asm,
7281                          SDNode OpNode> {
7282   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
7283       asm, ".8b", OpNode, v8i8>;
7284   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
7285       asm, ".16b", OpNode, v16i8>;
7286   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
7287       asm, ".4h", OpNode, v4i16>;
7288   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
7289       asm, ".8h", OpNode, v8i16>;
7290   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
7291       asm, ".2s", OpNode, v2i32>;
7292   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
7293       asm, ".4s", OpNode, v4i32>;
7294   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
7295       asm, ".2d", OpNode, v2i64>;
7297   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
7298         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
7299   def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)),
7300         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
7301   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
7302         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
7303   def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)),
7304         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
7305   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
7306         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
7307   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
7308         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
7309   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
7310         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
7313 //----------------------------------------------------------------------------
7314 // AdvSIMD three register scalar instructions
7315 //----------------------------------------------------------------------------
7317 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7318 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
7319                         RegisterClass regtype, string asm,
7320                         list<dag> pattern>
7321   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
7322       "\t$Rd, $Rn, $Rm", "", pattern>,
7323     Sched<[WriteVd]> {
7324   bits<5> Rd;
7325   bits<5> Rn;
7326   bits<5> Rm;
7327   let Inst{31-30} = 0b01;
7328   let Inst{29}    = U;
7329   let Inst{28-24} = 0b11110;
7330   let Inst{23-21} = size;
7331   let Inst{20-16} = Rm;
7332   let Inst{15-11} = opcode;
7333   let Inst{10}    = 1;
7334   let Inst{9-5}   = Rn;
7335   let Inst{4-0}   = Rd;
7338 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7339 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
7340                         dag oops, dag iops, string asm,
7341             list<dag> pattern>
7342   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
7343     Sched<[WriteVd]> {
7344   bits<5> Rd;
7345   bits<5> Rn;
7346   bits<5> Rm;
7347   let Inst{31-30} = 0b01;
7348   let Inst{29}    = U;
7349   let Inst{28-24} = 0b11110;
7350   let Inst{23-22} = size;
7351   let Inst{21}    = R;
7352   let Inst{20-16} = Rm;
7353   let Inst{15-11} = opcode;
7354   let Inst{10}    = 1;
7355   let Inst{9-5}   = Rn;
7356   let Inst{4-0}   = Rd;
7359 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
7360                             SDPatternOperator OpNode> {
7361   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
7362     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
7365 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
7366                                SDPatternOperator OpNode> {
7367   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
7368     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
7369   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
7370   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
7371   def v1i8   : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
7373   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
7374             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
7375   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
7376             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
7379 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
7380                              SDPatternOperator OpNode> {
7381   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
7382                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
7383   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
7386 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> {
7387   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
7388                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
7389                                      asm, []>;
7390   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
7391                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
7392                                      asm, []>;
7395 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
7396                              SDPatternOperator OpNode = null_frag,
7397                              Predicate pred = HasNEON> {
7398   let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in {
7399     let Predicates = [pred] in {
7400     def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
7401       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
7402     def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
7403       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
7404     }
7405     let Predicates = [pred, HasFullFP16] in {
7406     def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
7407       [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>;
7408     }
7409   }
7411   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
7412             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
7415 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
7416                                 SDPatternOperator OpNode = null_frag> {
7417   let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in {
7418     def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
7419       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
7420     def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
7421       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
7422     let Predicates = [HasNEON, HasFullFP16] in {
7423     def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
7424       []>;
7425     } // Predicates = [HasNEON, HasFullFP16]
7426   }
7428   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
7429             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
7432 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
7433               dag oops, dag iops, string asm, string cstr, list<dag> pat>
7434   : I<oops, iops, asm,
7435       "\t$Rd, $Rn, $Rm", cstr, pat>,
7436     Sched<[WriteVd]> {
7437   bits<5> Rd;
7438   bits<5> Rn;
7439   bits<5> Rm;
7440   let Inst{31-30} = 0b01;
7441   let Inst{29}    = U;
7442   let Inst{28-24} = 0b11110;
7443   let Inst{23-22} = size;
7444   let Inst{21}    = 1;
7445   let Inst{20-16} = Rm;
7446   let Inst{15-11} = opcode;
7447   let Inst{10}    = 0;
7448   let Inst{9-5}   = Rn;
7449   let Inst{4-0}   = Rd;
7452 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7453 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
7454                                   SDPatternOperator OpNode = null_frag> {
7455   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
7456                                       (outs FPR32:$Rd),
7457                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
7458   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
7459                                       (outs FPR64:$Rd),
7460                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
7461             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
7464 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7465 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
7466                                   SDPatternOperator OpNode = null_frag> {
7467   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
7468                                       (outs FPR32:$dst),
7469                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
7470                                       asm, "$Rd = $dst", []>;
7471   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
7472                                       (outs FPR64:$dst),
7473                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
7474                                       asm, "$Rd = $dst",
7475             [(set (i64 FPR64:$dst),
7476                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
7479 //----------------------------------------------------------------------------
7480 // AdvSIMD two register scalar instructions
7481 //----------------------------------------------------------------------------
7483 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7484 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
7485                         RegisterClass regtype, RegisterClass regtype2,
7486                         string asm, list<dag> pat>
7487   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
7488       "\t$Rd, $Rn", "", pat>,
7489     Sched<[WriteVd]> {
7490   bits<5> Rd;
7491   bits<5> Rn;
7492   let Inst{31-30} = 0b01;
7493   let Inst{29}    = U;
7494   let Inst{28-24} = 0b11110;
7495   let Inst{23-22} = size;
7496   let Inst{21} = 0b1;
7497   let Inst{20-19} = size2;
7498   let Inst{18-17} = 0b00;
7499   let Inst{16-12} = opcode;
7500   let Inst{11-10} = 0b10;
7501   let Inst{9-5}   = Rn;
7502   let Inst{4-0}   = Rd;
7505 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7506 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
7507                         RegisterClass regtype, RegisterClass regtype2,
7508                         string asm, list<dag> pat>
7509   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
7510       "\t$Rd, $Rn", "$Rd = $dst", pat>,
7511     Sched<[WriteVd]> {
7512   bits<5> Rd;
7513   bits<5> Rn;
7514   let Inst{31-30} = 0b01;
7515   let Inst{29}    = U;
7516   let Inst{28-24} = 0b11110;
7517   let Inst{23-22} = size;
7518   let Inst{21-17} = 0b10000;
7519   let Inst{16-12} = opcode;
7520   let Inst{11-10} = 0b10;
7521   let Inst{9-5}   = Rn;
7522   let Inst{4-0}   = Rd;
7526 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7527 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
7528                         RegisterClass regtype, string asm, string zero>
7529   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
7530       "\t$Rd, $Rn, #" # zero, "", []>,
7531     Sched<[WriteVd]> {
7532   bits<5> Rd;
7533   bits<5> Rn;
7534   let Inst{31-30} = 0b01;
7535   let Inst{29}    = U;
7536   let Inst{28-24} = 0b11110;
7537   let Inst{23-22} = size;
7538   let Inst{21} = 0b1;
7539   let Inst{20-19} = size2;
7540   let Inst{18-17} = 0b00;
7541   let Inst{16-12} = opcode;
7542   let Inst{11-10} = 0b10;
7543   let Inst{9-5}   = Rn;
7544   let Inst{4-0}   = Rd;
7547 let mayRaiseFPException = 1, Uses = [FPCR] in
7548 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
7549   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
7550      [(set (f32 FPR32:$Rd), (AArch64fcvtxnsdr (f64 FPR64:$Rn)))]>,
7551     Sched<[WriteVd]> {
7552   bits<5> Rd;
7553   bits<5> Rn;
7554   let Inst{31-17} = 0b011111100110000;
7555   let Inst{16-12} = opcode;
7556   let Inst{11-10} = 0b10;
7557   let Inst{9-5}   = Rn;
7558   let Inst{4-0}   = Rd;
7561 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
7562                              SDPatternOperator OpNode> {
7563   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
7565   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
7566             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
7569 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
7570                               SDPatternOperator OpNode> {
7571   let mayRaiseFPException = 1, Uses = [FPCR] in {
7572   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
7573   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
7574   let Predicates = [HasNEON, HasFullFP16] in {
7575   def v1i16rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
7576   }
7577   }
7579   def : InstAlias<asm # "\t$Rd, $Rn, #0",
7580                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
7581   def : InstAlias<asm # "\t$Rd, $Rn, #0",
7582                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
7583   let Predicates = [HasNEON, HasFullFP16] in {
7584   def : InstAlias<asm # "\t$Rd, $Rn, #0",
7585                   (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
7586   }
7588   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
7589             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
7592 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
7593                           SDPatternOperator OpNode = null_frag,
7594                           list<Predicate> preds = []> {
7595   def v1i64       : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
7596     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
7598   let Predicates = preds in {
7599   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
7600             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
7601   }
7604 let mayRaiseFPException = 1, Uses = [FPCR] in
7605 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm,
7606                            Predicate pred = HasNEON> {
7607   let Predicates = [pred] in {
7608   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
7609   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
7610   }
7611   let Predicates = [pred, HasFullFP16] in {
7612   def v1f16       : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
7613   }
7616 let mayRaiseFPException = 1, Uses = [FPCR] in
7617 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
7618                               SDPatternOperator OpNode> {
7619   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
7620                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
7621   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
7622                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
7623   let Predicates = [HasNEON, HasFullFP16] in {
7624   def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
7625                                 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>;
7626   }
7629 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
7630                              SDPatternOperator OpNode = null_frag> {
7631   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7632     def v1i64  : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
7633            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
7634     def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
7635            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
7636     def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
7637     def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
7638   }
7640   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
7641             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
7644 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
7645                                  Intrinsic OpNode> {
7646   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7647     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
7648         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
7649     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
7650         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
7651     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
7652     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
7653   }
7655   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
7656             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
7661 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7662 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
7663                                  SDPatternOperator OpNode = null_frag> {
7664   def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
7665         [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>;
7666   def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
7667   def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
7670 //----------------------------------------------------------------------------
7671 // AdvSIMD scalar pairwise instructions
7672 //----------------------------------------------------------------------------
7674 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7675 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
7676                         RegisterOperand regtype, RegisterOperand vectype,
7677                         string asm, string kind>
7678   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7679       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
7680     Sched<[WriteVd]> {
7681   bits<5> Rd;
7682   bits<5> Rn;
7683   let Inst{31-30} = 0b01;
7684   let Inst{29}    = U;
7685   let Inst{28-24} = 0b11110;
7686   let Inst{23-22} = size;
7687   let Inst{21-17} = 0b11000;
7688   let Inst{16-12} = opcode;
7689   let Inst{11-10} = 0b10;
7690   let Inst{9-5}   = Rn;
7691   let Inst{4-0}   = Rd;
7694 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
7695   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
7696                                       asm, ".2d">;
7699 let mayRaiseFPException = 1, Uses = [FPCR] in
7700 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
7701   let Predicates = [HasNEON, HasFullFP16] in {
7702   def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
7703                                       asm, ".2h">;
7704   }
7705   def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
7706                                       asm, ".2s">;
7707   def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
7708                                       asm, ".2d">;
7711 //----------------------------------------------------------------------------
7712 // AdvSIMD across lanes instructions
7713 //----------------------------------------------------------------------------
7715 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7716 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
7717                           RegisterClass regtype, RegisterOperand vectype,
7718                           string asm, string kind, list<dag> pattern>
7719   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7720       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
7721     Sched<[!if(Q, WriteVq, WriteVd)]> {
7722   bits<5> Rd;
7723   bits<5> Rn;
7724   let Inst{31}    = 0;
7725   let Inst{30}    = Q;
7726   let Inst{29}    = U;
7727   let Inst{28-24} = 0b01110;
7728   let Inst{23-22} = size;
7729   let Inst{21-17} = 0b11000;
7730   let Inst{16-12} = opcode;
7731   let Inst{11-10} = 0b10;
7732   let Inst{9-5}   = Rn;
7733   let Inst{4-0}   = Rd;
7736 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
7737                               string asm> {
7738   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
7739                                    asm, ".8b", []>;
7740   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
7741                                    asm, ".16b", []>;
7742   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
7743                                    asm, ".4h", []>;
7744   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
7745                                    asm, ".8h", []>;
7746   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
7747                                    asm, ".4s", []>;
7750 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
7751   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
7752                                    asm, ".8b", []>;
7753   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
7754                                    asm, ".16b", []>;
7755   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
7756                                    asm, ".4h", []>;
7757   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
7758                                    asm, ".8h", []>;
7759   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
7760                                    asm, ".4s", []>;
7763 let mayRaiseFPException = 1, Uses = [FPCR] in
7764 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
7765                             SDPatternOperator intOp> {
7766   let Predicates = [HasNEON, HasFullFP16] in {
7767   def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
7768                                    asm, ".4h",
7769         [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>;
7770   def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
7771                                    asm, ".8h",
7772         [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>;
7773   } // Predicates = [HasNEON, HasFullFP16]
7774   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
7775                                    asm, ".4s",
7776         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
7779 //----------------------------------------------------------------------------
7780 // AdvSIMD INS/DUP instructions
7781 //----------------------------------------------------------------------------
7783 // FIXME: There has got to be a better way to factor these. ugh.
7785 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
7786                      string operands, string constraints, list<dag> pattern>
7787   : I<outs, ins, asm, operands, constraints, pattern>,
7788     Sched<[!if(Q, WriteVq, WriteVd)]> {
7789   bits<5> Rd;
7790   bits<5> Rn;
7791   let Inst{31} = 0;
7792   let Inst{30} = Q;
7793   let Inst{29} = op;
7794   let Inst{28-21} = 0b01110000;
7795   let Inst{15} = 0;
7796   let Inst{10} = 1;
7797   let Inst{9-5} = Rn;
7798   let Inst{4-0} = Rd;
7801 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
7802                       RegisterOperand vecreg, RegisterClass regtype>
7803   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
7804                    "{\t$Rd" # size # ", $Rn" #
7805                    "|" # size # "\t$Rd, $Rn}", "",
7806                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
7807   let Inst{20-16} = imm5;
7808   let Inst{14-11} = 0b0001;
7811 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
7812                          ValueType vectype, ValueType insreg,
7813                          RegisterOperand vecreg, Operand idxtype,
7814                          SDNode OpNode>
7815   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
7816                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
7817                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
7818                  [(set (vectype vecreg:$Rd),
7819                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
7820   let Inst{14-11} = 0b0000;
7823 class SIMDDup64FromElement
7824   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
7825                        VectorIndexD, AArch64duplane64> {
7826   bits<1> idx;
7827   let Inst{20} = idx;
7828   let Inst{19-16} = 0b1000;
7831 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
7832                            RegisterOperand vecreg>
7833   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
7834                        VectorIndexS, AArch64duplane32> {
7835   bits<2> idx;
7836   let Inst{20-19} = idx;
7837   let Inst{18-16} = 0b100;
7840 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
7841                            RegisterOperand vecreg>
7842   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
7843                        VectorIndexH, AArch64duplane16> {
7844   bits<3> idx;
7845   let Inst{20-18} = idx;
7846   let Inst{17-16} = 0b10;
7849 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
7850                           RegisterOperand vecreg>
7851   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
7852                        VectorIndexB, AArch64duplane8> {
7853   bits<4> idx;
7854   let Inst{20-17} = idx;
7855   let Inst{16} = 1;
7858 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
7859                   Operand idxtype, string asm, list<dag> pattern>
7860   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
7861                    "{\t$Rd, $Rn" # size # "$idx" #
7862                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
7863   let Inst{14-11} = imm4;
7866 class SIMDSMov<bit Q, string size, RegisterClass regtype,
7867                Operand idxtype>
7868   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
7869 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
7870                Operand idxtype>
7871   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
7872       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
7874 class SIMDMovAlias<string asm, string size, Instruction inst,
7875                    RegisterClass regtype, Operand idxtype>
7876     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
7877                     "|" # size # "\t$dst, $src$idx}",
7878                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
7880 multiclass SMov {
7881   // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)
7882   // streaming mode.
7883   let Predicates = [HasNEONorSME] in {
7884     def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> {
7885       let Inst{20-16} = 0b00001;
7886     }
7887     def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> {
7888       let Inst{20-16} = 0b00001;
7889     }
7890     def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> {
7891       let Inst{20-16} = 0b00010;
7892     }
7893     def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> {
7894       let Inst{20-16} = 0b00010;
7895     }
7896     def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> {
7897       let Inst{20-16} = 0b00100;
7898     }
7899   }
7900   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
7901     bits<4> idx;
7902     let Inst{20-17} = idx;
7903     let Inst{16} = 1;
7904   }
7905   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
7906     bits<4> idx;
7907     let Inst{20-17} = idx;
7908     let Inst{16} = 1;
7909   }
7910   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
7911     bits<3> idx;
7912     let Inst{20-18} = idx;
7913     let Inst{17-16} = 0b10;
7914   }
7915   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
7916     bits<3> idx;
7917     let Inst{20-18} = idx;
7918     let Inst{17-16} = 0b10;
7919   }
7920   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
7921     bits<2> idx;
7922     let Inst{20-19} = idx;
7923     let Inst{18-16} = 0b100;
7924   }
7927 multiclass UMov {
7928   // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)
7929   // streaming mode.
7930   let Predicates = [HasNEONorSME] in {
7931     def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> {
7932       let Inst{20-16} = 0b00001;
7933     }
7934     def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> {
7935       let Inst{20-16} = 0b00010;
7936     }
7937     def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> {
7938       let Inst{20-16} = 0b00100;
7939     }
7940     def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> {
7941       let Inst{20-16} = 0b01000;
7942     }
7943     def : SIMDMovAlias<"mov", ".s",
7944                        !cast<Instruction>(NAME # vi32_idx0),
7945                        GPR32, VectorIndex0>;
7946     def : SIMDMovAlias<"mov", ".d",
7947                        !cast<Instruction>(NAME # vi64_idx0),
7948                        GPR64, VectorIndex0>;
7949   }
7950   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
7951     bits<4> idx;
7952     let Inst{20-17} = idx;
7953     let Inst{16} = 1;
7954   }
7955   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
7956     bits<3> idx;
7957     let Inst{20-18} = idx;
7958     let Inst{17-16} = 0b10;
7959   }
7960   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
7961     bits<2> idx;
7962     let Inst{20-19} = idx;
7963     let Inst{18-16} = 0b100;
7964   }
7965   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
7966     bits<1> idx;
7967     let Inst{20} = idx;
7968     let Inst{19-16} = 0b1000;
7969   }
7970   def : SIMDMovAlias<"mov", ".s",
7971                      !cast<Instruction>(NAME#"vi32"),
7972                      GPR32, VectorIndexS>;
7973   def : SIMDMovAlias<"mov", ".d",
7974                      !cast<Instruction>(NAME#"vi64"),
7975                      GPR64, VectorIndexD>;
7978 class SIMDInsFromMain<string size, ValueType vectype,
7979                       RegisterClass regtype, Operand idxtype>
7980   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
7981                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
7982                    "{\t$Rd" # size # "$idx, $Rn" #
7983                    "|" # size # "\t$Rd$idx, $Rn}",
7984                    "$Rd = $dst",
7985             [(set V128:$dst,
7986               (vector_insert (vectype V128:$Rd), regtype:$Rn, (i64 idxtype:$idx)))]> {
7987   let Inst{14-11} = 0b0011;
7990 class SIMDInsFromElement<string size, ValueType vectype,
7991                          ValueType elttype, Operand idxtype>
7992   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
7993                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
7994                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
7995                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
7996                    "$Rd = $dst",
7997          [(set V128:$dst,
7998                (vector_insert
7999                  (vectype V128:$Rd),
8000                  (elttype (vector_extract (vectype V128:$Rn), (i64 idxtype:$idx2))),
8001                  (i64 idxtype:$idx)))]>;
8003 class SIMDInsMainMovAlias<string size, Instruction inst,
8004                           RegisterClass regtype, Operand idxtype>
8005     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
8006                         "|" # size #"\t$dst$idx, $src}",
8007                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
8008 class SIMDInsElementMovAlias<string size, Instruction inst,
8009                              Operand idxtype>
8010     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2"
8011                       # "|" # size #"\t$dst$idx, $src$idx2}",
8012                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
8015 multiclass SIMDIns {
8016   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
8017     bits<4> idx;
8018     let Inst{20-17} = idx;
8019     let Inst{16} = 1;
8020   }
8021   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
8022     bits<3> idx;
8023     let Inst{20-18} = idx;
8024     let Inst{17-16} = 0b10;
8025   }
8026   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
8027     bits<2> idx;
8028     let Inst{20-19} = idx;
8029     let Inst{18-16} = 0b100;
8030   }
8031   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
8032     bits<1> idx;
8033     let Inst{20} = idx;
8034     let Inst{19-16} = 0b1000;
8035   }
8037   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
8038     bits<4> idx;
8039     bits<4> idx2;
8040     let Inst{20-17} = idx;
8041     let Inst{16} = 1;
8042     let Inst{14-11} = idx2;
8043   }
8044   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
8045     bits<3> idx;
8046     bits<3> idx2;
8047     let Inst{20-18} = idx;
8048     let Inst{17-16} = 0b10;
8049     let Inst{14-12} = idx2;
8050     let Inst{11} = {?};
8051   }
8052   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
8053     bits<2> idx;
8054     bits<2> idx2;
8055     let Inst{20-19} = idx;
8056     let Inst{18-16} = 0b100;
8057     let Inst{14-13} = idx2;
8058     let Inst{12-11} = {?,?};
8059   }
8060   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
8061     bits<1> idx;
8062     bits<1> idx2;
8063     let Inst{20} = idx;
8064     let Inst{19-16} = 0b1000;
8065     let Inst{14} = idx2;
8066     let Inst{13-11} = {?,?,?};
8067   }
8069   // For all forms of the INS instruction, the "mov" mnemonic is the
8070   // preferred alias. Why they didn't just call the instruction "mov" in
8071   // the first place is a very good question indeed...
8072   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
8073                          GPR32, VectorIndexB>;
8074   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
8075                          GPR32, VectorIndexH>;
8076   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
8077                          GPR32, VectorIndexS>;
8078   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
8079                          GPR64, VectorIndexD>;
8081   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
8082                          VectorIndexB>;
8083   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
8084                          VectorIndexH>;
8085   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
8086                          VectorIndexS>;
8087   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
8088                          VectorIndexD>;
8091 //----------------------------------------------------------------------------
8092 // AdvSIMD TBL/TBX
8093 //----------------------------------------------------------------------------
8095 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8096 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
8097                           RegisterOperand listtype, string asm, string kind>
8098   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
8099        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
8100     Sched<[!if(Q, WriteVq, WriteVd)]> {
8101   bits<5> Vd;
8102   bits<5> Vn;
8103   bits<5> Vm;
8104   let Inst{31}    = 0;
8105   let Inst{30}    = Q;
8106   let Inst{29-21} = 0b001110000;
8107   let Inst{20-16} = Vm;
8108   let Inst{15}    = 0;
8109   let Inst{14-13} = len;
8110   let Inst{12}    = op;
8111   let Inst{11-10} = 0b00;
8112   let Inst{9-5}   = Vn;
8113   let Inst{4-0}   = Vd;
8116 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8117 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
8118                           RegisterOperand listtype, string asm, string kind>
8119   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
8120        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
8121     Sched<[!if(Q, WriteVq, WriteVd)]> {
8122   bits<5> Vd;
8123   bits<5> Vn;
8124   bits<5> Vm;
8125   let Inst{31}    = 0;
8126   let Inst{30}    = Q;
8127   let Inst{29-21} = 0b001110000;
8128   let Inst{20-16} = Vm;
8129   let Inst{15}    = 0;
8130   let Inst{14-13} = len;
8131   let Inst{12}    = op;
8132   let Inst{11-10} = 0b00;
8133   let Inst{9-5}   = Vn;
8134   let Inst{4-0}   = Vd;
8137 class SIMDTableLookupAlias<string asm, Instruction inst,
8138                           RegisterOperand vectype, RegisterOperand listtype>
8139     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
8140                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
8142 multiclass SIMDTableLookup<bit op, string asm> {
8143   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
8144                                       asm, ".8b">;
8145   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
8146                                       asm, ".8b">;
8147   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
8148                                       asm, ".8b">;
8149   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
8150                                       asm, ".8b">;
8151   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
8152                                       asm, ".16b">;
8153   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
8154                                       asm, ".16b">;
8155   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
8156                                       asm, ".16b">;
8157   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
8158                                       asm, ".16b">;
8160   def : SIMDTableLookupAlias<asm # ".8b",
8161                          !cast<Instruction>(NAME#"v8i8One"),
8162                          V64, VecListOne128>;
8163   def : SIMDTableLookupAlias<asm # ".8b",
8164                          !cast<Instruction>(NAME#"v8i8Two"),
8165                          V64, VecListTwo128>;
8166   def : SIMDTableLookupAlias<asm # ".8b",
8167                          !cast<Instruction>(NAME#"v8i8Three"),
8168                          V64, VecListThree128>;
8169   def : SIMDTableLookupAlias<asm # ".8b",
8170                          !cast<Instruction>(NAME#"v8i8Four"),
8171                          V64, VecListFour128>;
8172   def : SIMDTableLookupAlias<asm # ".16b",
8173                          !cast<Instruction>(NAME#"v16i8One"),
8174                          V128, VecListOne128>;
8175   def : SIMDTableLookupAlias<asm # ".16b",
8176                          !cast<Instruction>(NAME#"v16i8Two"),
8177                          V128, VecListTwo128>;
8178   def : SIMDTableLookupAlias<asm # ".16b",
8179                          !cast<Instruction>(NAME#"v16i8Three"),
8180                          V128, VecListThree128>;
8181   def : SIMDTableLookupAlias<asm # ".16b",
8182                          !cast<Instruction>(NAME#"v16i8Four"),
8183                          V128, VecListFour128>;
8186 multiclass SIMDTableLookupTied<bit op, string asm> {
8187   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
8188                                       asm, ".8b">;
8189   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
8190                                       asm, ".8b">;
8191   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
8192                                       asm, ".8b">;
8193   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
8194                                       asm, ".8b">;
8195   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
8196                                       asm, ".16b">;
8197   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
8198                                       asm, ".16b">;
8199   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
8200                                       asm, ".16b">;
8201   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
8202                                       asm, ".16b">;
8204   def : SIMDTableLookupAlias<asm # ".8b",
8205                          !cast<Instruction>(NAME#"v8i8One"),
8206                          V64, VecListOne128>;
8207   def : SIMDTableLookupAlias<asm # ".8b",
8208                          !cast<Instruction>(NAME#"v8i8Two"),
8209                          V64, VecListTwo128>;
8210   def : SIMDTableLookupAlias<asm # ".8b",
8211                          !cast<Instruction>(NAME#"v8i8Three"),
8212                          V64, VecListThree128>;
8213   def : SIMDTableLookupAlias<asm # ".8b",
8214                          !cast<Instruction>(NAME#"v8i8Four"),
8215                          V64, VecListFour128>;
8216   def : SIMDTableLookupAlias<asm # ".16b",
8217                          !cast<Instruction>(NAME#"v16i8One"),
8218                          V128, VecListOne128>;
8219   def : SIMDTableLookupAlias<asm # ".16b",
8220                          !cast<Instruction>(NAME#"v16i8Two"),
8221                          V128, VecListTwo128>;
8222   def : SIMDTableLookupAlias<asm # ".16b",
8223                          !cast<Instruction>(NAME#"v16i8Three"),
8224                          V128, VecListThree128>;
8225   def : SIMDTableLookupAlias<asm # ".16b",
8226                          !cast<Instruction>(NAME#"v16i8Four"),
8227                          V128, VecListFour128>;
8230 //----------------------------------------------------------------------------
8231 // AdvSIMD LUT
8232 //----------------------------------------------------------------------------
8233 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8234 class BaseSIMDTableLookupIndexed<bit Q, bits<5> opc, RegisterOperand vectype,
8235                             RegisterOperand listtype, Operand idx_type,
8236                             string asm, string kind>
8237   : I<(outs vectype:$Rd),
8238       (ins listtype:$Rn, vectype:$Rm, idx_type:$idx),
8239       asm, "\t$Rd" # kind # ", $Rn, $Rm$idx", "", []>,
8240     Sched<[]> {
8241   bits<5> Rd;
8242   bits<5> Rn;
8243   bits<5> Rm;
8244   let Inst{31}    = 0;
8245   let Inst{30}    = Q;
8246   let Inst{29-24} = 0b001110;
8247   let Inst{23-22} = opc{4-3};
8248   let Inst{21}    = 0;
8249   let Inst{20-16} = Rm;
8250   let Inst{15}    = 0;
8251   let Inst{14-12} = opc{2-0};
8252   let Inst{11-10} = 0b00;
8253   let Inst{9-5}   = Rn;
8254   let Inst{4-0}   = Rd;
8257 multiclass BaseSIMDTableLookupIndexed2<string asm> {
8258   def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b10,?,?,0b1}, V128, VecListOne16b, VectorIndexS, asm, ".16b"> {
8259     bits<2> idx;
8260     let Inst{14-13} = idx;
8261   }
8262   def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b11,?,?,?}, V128, VecListOne8h, VectorIndexH, asm, ".8h" > {
8263     bits<3> idx;
8264     let Inst{14-12} = idx;
8265   }
8268 multiclass BaseSIMDTableLookupIndexed4<string asm> {
8269   def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,0b10}, V128, VecListOne16b, VectorIndexD, asm, ".16b"> {
8270     bit idx;
8271     let Inst{14} = idx;
8272   }
8273   def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,?,0b1}, V128, VecListTwo8h, VectorIndexS, asm, ".8h" > {
8274     bits<2> idx;
8275     let Inst{14-13} = idx;
8276   }
8279 //----------------------------------------------------------------------------
8280 // AdvSIMD scalar DUP
8281 //----------------------------------------------------------------------------
8282 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8283 class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype,
8284                         string asm, string kind, Operand idxtype>
8285   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm,
8286        "{\t$dst, $src" # kind # "$idx" #
8287        "|\t$dst, $src$idx}", "", []>,
8288     Sched<[WriteVd]> {
8289   bits<5> dst;
8290   bits<5> src;
8291   let Inst{31-21} = 0b01011110000;
8292   let Inst{15-10} = 0b000001;
8293   let Inst{9-5}   = src;
8294   let Inst{4-0}   = dst;
8297 class SIMDScalarDUPAlias<string asm, string size, Instruction inst,
8298       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
8299     : InstAlias<asm # "{\t$dst, $src" # size # "$index"
8300                     # "|\t$dst, $src$index}",
8301                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
8304 multiclass SIMDScalarDUP<string asm> {
8305   def i8  : BaseSIMDScalarDUP<FPR8,  V128, asm, ".b", VectorIndexB> {
8306     bits<4> idx;
8307     let Inst{20-17} = idx;
8308     let Inst{16} = 1;
8309   }
8310   def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> {
8311     bits<3> idx;
8312     let Inst{20-18} = idx;
8313     let Inst{17-16} = 0b10;
8314   }
8315   def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> {
8316     bits<2> idx;
8317     let Inst{20-19} = idx;
8318     let Inst{18-16} = 0b100;
8319   }
8320   def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> {
8321     bits<1> idx;
8322     let Inst{20} = idx;
8323     let Inst{19-16} = 0b1000;
8324   }
8326   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
8327                                                           VectorIndexD:$idx)))),
8328             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
8330   // 'DUP' mnemonic aliases.
8331   def : SIMDScalarDUPAlias<"dup", ".b",
8332                            !cast<Instruction>(NAME#"i8"),
8333                            FPR8, V128, VectorIndexB>;
8334   def : SIMDScalarDUPAlias<"dup", ".h",
8335                            !cast<Instruction>(NAME#"i16"),
8336                            FPR16, V128, VectorIndexH>;
8337   def : SIMDScalarDUPAlias<"dup", ".s",
8338                            !cast<Instruction>(NAME#"i32"),
8339                            FPR32, V128, VectorIndexS>;
8340   def : SIMDScalarDUPAlias<"dup", ".d",
8341                            !cast<Instruction>(NAME#"i64"),
8342                            FPR64, V128, VectorIndexD>;
8345 //----------------------------------------------------------------------------
8346 // AdvSIMD modified immediate instructions
8347 //----------------------------------------------------------------------------
8349 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
8350                           string asm, string op_string,
8351                           string cstr, list<dag> pattern>
8352   : I<oops, iops, asm, op_string, cstr, pattern>,
8353     Sched<[!if(Q, WriteVq, WriteVd)]> {
8354   bits<5> Rd;
8355   bits<8> imm8;
8356   let Inst{31}    = 0;
8357   let Inst{30}    = Q;
8358   let Inst{29}    = op;
8359   let Inst{28-19} = 0b0111100000;
8360   let Inst{18-16} = imm8{7-5};
8361   let Inst{11} = op2;
8362   let Inst{10} = 1;
8363   let Inst{9-5}   = imm8{4-0};
8364   let Inst{4-0}   = Rd;
8367 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
8368                                 Operand immtype, dag opt_shift_iop,
8369                                 string opt_shift, string asm, string kind,
8370                                 list<dag> pattern>
8371   : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
8372                         !con((ins immtype:$imm8), opt_shift_iop), asm,
8373                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
8374                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
8375                         "", pattern> {
8376   let DecoderMethod = "DecodeModImmInstruction";
8379 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
8380                                 Operand immtype, dag opt_shift_iop,
8381                                 string opt_shift, string asm, string kind,
8382                                 list<dag> pattern>
8383   : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
8384                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
8385                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
8386                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
8387                         "$Rd = $dst", pattern> {
8388   let DecoderMethod = "DecodeModImmTiedInstruction";
8391 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
8392                                      RegisterOperand vectype, string asm,
8393                                      string kind, list<dag> pattern>
8394   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
8395                               (ins logical_vec_shift:$shift),
8396                               "$shift", asm, kind, pattern> {
8397   bits<2> shift;
8398   let Inst{15}    = b15_b12{1};
8399   let Inst{14-13} = shift;
8400   let Inst{12}    = b15_b12{0};
8403 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
8404                                      RegisterOperand vectype, string asm,
8405                                      string kind, list<dag> pattern>
8406   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
8407                               (ins logical_vec_shift:$shift),
8408                               "$shift", asm, kind, pattern> {
8409   bits<2> shift;
8410   let Inst{15}    = b15_b12{1};
8411   let Inst{14-13} = shift;
8412   let Inst{12}    = b15_b12{0};
8416 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
8417                                          RegisterOperand vectype, string asm,
8418                                          string kind, list<dag> pattern>
8419   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
8420                               (ins logical_vec_hw_shift:$shift),
8421                               "$shift", asm, kind, pattern> {
8422   bits<2> shift;
8423   let Inst{15} = b15_b12{1};
8424   let Inst{14} = 0;
8425   let Inst{13} = shift{0};
8426   let Inst{12} = b15_b12{0};
8429 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
8430                                          RegisterOperand vectype, string asm,
8431                                          string kind, list<dag> pattern>
8432   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
8433                               (ins logical_vec_hw_shift:$shift),
8434                               "$shift", asm, kind, pattern> {
8435   bits<2> shift;
8436   let Inst{15} = b15_b12{1};
8437   let Inst{14} = 0;
8438   let Inst{13} = shift{0};
8439   let Inst{12} = b15_b12{0};
8442 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
8443                                       string asm> {
8444   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
8445                                                  asm, ".4h", []>;
8446   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
8447                                                  asm, ".8h", []>;
8449   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
8450                                              asm, ".2s", []>;
8451   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
8452                                              asm, ".4s", []>;
8455 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
8456                                       bits<2> w_cmode, string asm,
8457                                       SDNode OpNode> {
8458   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
8459                                                  asm, ".4h",
8460              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
8461                                              imm0_255:$imm8,
8462                                              (i32 imm:$shift)))]>;
8463   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
8464                                                  asm, ".8h",
8465              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
8466                                               imm0_255:$imm8,
8467                                               (i32 imm:$shift)))]>;
8469   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
8470                                              asm, ".2s",
8471              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
8472                                              imm0_255:$imm8,
8473                                              (i32 imm:$shift)))]>;
8474   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
8475                                              asm, ".4s",
8476              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
8477                                               imm0_255:$imm8,
8478                                               (i32 imm:$shift)))]>;
8481 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
8482                              RegisterOperand vectype, string asm,
8483                              string kind, list<dag> pattern>
8484   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
8485                               (ins move_vec_shift:$shift),
8486                               "$shift", asm, kind, pattern> {
8487   bits<1> shift;
8488   let Inst{15-13} = cmode{3-1};
8489   let Inst{12}    = shift;
8492 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
8493                                    RegisterOperand vectype,
8494                                    Operand imm_type, string asm,
8495                                    string kind, list<dag> pattern>
8496   : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
8497                               asm, kind, pattern> {
8498   let Inst{15-12} = cmode;
8501 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
8502                                    list<dag> pattern>
8503   : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
8504                         "\t$Rd, $imm8", "", pattern> {
8505   let Inst{15-12} = cmode;
8506   let DecoderMethod = "DecodeModImmInstruction";
8509 //----------------------------------------------------------------------------
8510 // AdvSIMD indexed element
8511 //----------------------------------------------------------------------------
8513 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8514 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
8515                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
8516                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
8517                       string apple_kind, string dst_kind, string lhs_kind,
8518                       string rhs_kind, list<dag> pattern>
8519   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
8520       asm,
8521       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
8522       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
8523     Sched<[WriteVd]> {
8524   bits<5> Rd;
8525   bits<5> Rn;
8526   bits<5> Rm;
8528   let Inst{31}    = 0;
8529   let Inst{30}    = Q;
8530   let Inst{29}    = U;
8531   let Inst{28}    = Scalar;
8532   let Inst{27-24} = 0b1111;
8533   let Inst{23-22} = size;
8534   // Bit 21 must be set by the derived class.
8535   let Inst{20-16} = Rm;
8536   let Inst{15-12} = opc;
8537   // Bit 11 must be set by the derived class.
8538   let Inst{10}    = 0;
8539   let Inst{9-5}   = Rn;
8540   let Inst{4-0}   = Rd;
8543 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8544 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
8545                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
8546                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
8547                       string apple_kind, string dst_kind, string lhs_kind,
8548                       string rhs_kind, list<dag> pattern>
8549   : I<(outs dst_reg:$dst),
8550       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
8551       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
8552       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
8553     Sched<[WriteVd]> {
8554   bits<5> Rd;
8555   bits<5> Rn;
8556   bits<5> Rm;
8558   let Inst{31}    = 0;
8559   let Inst{30}    = Q;
8560   let Inst{29}    = U;
8561   let Inst{28}    = Scalar;
8562   let Inst{27-24} = 0b1111;
8563   let Inst{23-22} = size;
8564   // Bit 21 must be set by the derived class.
8565   let Inst{20-16} = Rm;
8566   let Inst{15-12} = opc;
8567   // Bit 11 must be set by the derived class.
8568   let Inst{10}    = 0;
8569   let Inst{9-5}   = Rn;
8570   let Inst{4-0}   = Rd;
8574 //----------------------------------------------------------------------------
8575 // Armv8.6 BFloat16 Extension
8576 //----------------------------------------------------------------------------
8577 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in {
8579 class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1,
8580                                    string kind2, RegisterOperand RegType,
8581                                    ValueType AccumType, ValueType InputType>
8582   : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst),
8583                     (int_aarch64_neon_bfdot (AccumType RegType:$Rd),
8584                                             (InputType RegType:$Rn),
8585                                             (InputType RegType:$Rm)))]> {
8586   let AsmString = !strconcat(asm,
8587                              "{\t$Rd" # kind1 # ", $Rn" # kind2 #
8588                                ", $Rm" # kind2 # "}");
8591 multiclass SIMDThreeSameVectorBFDot<bit U, string asm> {
8592   def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64,
8593                                            v2f32, v4bf16>;
8594   def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,
8595                                            v4f32, v8bf16>;
8598 class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
8599                                       string dst_kind, string lhs_kind,
8600                                       string rhs_kind,
8601                                       RegisterOperand RegType,
8602                                       ValueType AccumType,
8603                                       ValueType InputType>
8604   : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111,
8605                         RegType, RegType, V128, VectorIndexS,
8606                         asm, "", dst_kind, lhs_kind, rhs_kind,
8607         [(set (AccumType RegType:$dst),
8608               (AccumType (int_aarch64_neon_bfdot
8609                                  (AccumType RegType:$Rd),
8610                                  (InputType RegType:$Rn),
8611                                  (InputType (bitconvert (AccumType
8612                                     (AArch64duplane32 (v4f32 V128:$Rm),
8613                                         VectorIndexS:$idx)))))))]> {
8615   bits<2> idx;
8616   let Inst{21}    = idx{0};  // L
8617   let Inst{11}    = idx{1};  // H
8620 multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> {
8622   def v4bf16  : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h",
8623                                                ".2h", V64, v2f32, v4bf16>;
8624   def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h",
8625                                               ".2h", V128, v4f32, v8bf16>;
8628 let mayRaiseFPException = 1, Uses = [FPCR] in
8629 class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode>
8630   : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s",
8631               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
8632                                                (v8bf16 V128:$Rn),
8633                                                (v8bf16 V128:$Rm)))]> {
8634   let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}");
8637 let mayRaiseFPException = 1, Uses = [FPCR] in
8638 class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode>
8639   : I<(outs V128:$dst),
8640       (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm,
8641       "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst",
8642           [(set (v4f32 V128:$dst),
8643                 (v4f32 (OpNode (v4f32 V128:$Rd),
8644                                (v8bf16 V128:$Rn),
8645                                (v8bf16
8646                                   (AArch64duplane16 (v8bf16 V128_lo:$Rm),
8647                                       VectorIndexH:$idx)))))]>,
8648     Sched<[WriteVq]> {
8649   bits<5> Rd;
8650   bits<5> Rn;
8651   bits<4> Rm;
8652   bits<3> idx;
8654   let Inst{31}    = 0;
8655   let Inst{30}    = Q;
8656   let Inst{29-22} = 0b00111111;
8657   let Inst{21-20} = idx{1-0};
8658   let Inst{19-16} = Rm;
8659   let Inst{15-12} = 0b1111;
8660   let Inst{11}    = idx{2};   // H
8661   let Inst{10}    = 0;
8662   let Inst{9-5}   = Rn;
8663   let Inst{4-0}   = Rd;
8666 class SIMDThreeSameVectorBF16MatrixMul<string asm>
8667   : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101,
8668                                 V128, asm, ".4s",
8669                           [(set (v4f32 V128:$dst),
8670                                 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd),
8671                                                          (v8bf16 V128:$Rn),
8672                                                          (v8bf16 V128:$Rm)))]> {
8673   let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h",
8674                                     ", $Rm", ".8h", "}");
8677 let mayRaiseFPException = 1, Uses = [FPCR] in
8678 class SIMD_BFCVTN
8679   : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128,
8680                            "bfcvtn", ".4h", ".4s",
8681     [(set (v8bf16 V128:$Rd),
8682           (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>;
8684 let mayRaiseFPException = 1, Uses = [FPCR] in
8685 class SIMD_BFCVTN2
8686   : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128,
8687                            "bfcvtn2", ".8h", ".4s",
8688     [(set (v8bf16 V128:$dst),
8689           (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>;
8691 let mayRaiseFPException = 1, Uses = [FPCR] in
8692 class BF16ToSinglePrecision<string asm>
8693   : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "",
8694     [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>,
8695     Sched<[WriteFCvt]> {
8696   bits<5> Rd;
8697   bits<5> Rn;
8698   let Inst{31-10} = 0b0001111001100011010000;
8699   let Inst{9-5}   = Rn;
8700   let Inst{4-0}   = Rd;
8702 } // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0
8704 //----------------------------------------------------------------------------
8705 class BaseSIMDThreeSameVectorIndexB<bit Q, bit U, bits<2> sz, bits<4> opc,
8706                                     string asm, string dst_kind,
8707                                     RegisterOperand RegType,
8708                                     RegisterOperand RegType_lo>
8709   : BaseSIMDIndexedTied<Q, U, 0b0, sz, opc,
8710                         RegType, RegType, RegType_lo, VectorIndexB,
8711                         asm, "", dst_kind, ".16b", ".b", []> {
8713   // idx = H:L:M
8714   bits<4> idx;
8715   let Inst{11}    = idx{3};
8716   let Inst{21-19} = idx{2-0};
8719 multiclass SIMDThreeSameVectorMLAIndex<bit Q, string asm> {
8720   def v8f16 : BaseSIMDThreeSameVectorIndexB<Q, 0b0, 0b11, 0b0000, asm, ".8h",
8721                                             V128, V128_0to7>;
8724 multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm> {
8725   def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s",
8726                                             V128, V128_0to7>;
8729 //----------------------------------------------------------------------------
8730 // Armv8.6 Matrix Multiply Extension
8731 //----------------------------------------------------------------------------
8733 class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode>
8734   : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s",
8735               [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
8736                                                (v16i8 V128:$Rn),
8737                                                (v16i8 V128:$Rm)))]> {
8738   let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}";
8741 //----------------------------------------------------------------------------
8742 // ARMv8.2-A Dot Product Instructions (Indexed)
8743 class BaseSIMDThreeSameVectorIndexS<bit Q, bit U, bits<2> size, bits<4> opc, string asm,
8744                                     string dst_kind, string lhs_kind, string rhs_kind,
8745                                     RegisterOperand RegType,
8746                                     ValueType AccumType, ValueType InputType,
8747                                     SDPatternOperator OpNode> :
8748         BaseSIMDIndexedTied<Q, U, 0b0, size, opc, RegType, RegType, V128,
8749                             VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
8750         [(set (AccumType RegType:$dst),
8751               (AccumType (OpNode (AccumType RegType:$Rd),
8752                                  (InputType RegType:$Rn),
8753                                  (InputType (bitconvert (AccumType
8754                                     (AArch64duplane32 (v4i32 V128:$Rm),
8755                                         VectorIndexS:$idx)))))))]> {
8756   bits<2> idx;
8757   let Inst{21}    = idx{0};  // L
8758   let Inst{11}    = idx{1};  // H
8761 multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm,
8762                                        SDPatternOperator OpNode> {
8763   def v8i8  : BaseSIMDThreeSameVectorIndexS<0, U, size, {0b111, Mixed}, asm, ".2s", ".8b", ".4b",
8764                                               V64, v2i32, v8i8, OpNode>;
8765   def v16i8 : BaseSIMDThreeSameVectorIndexS<1, U, size, {0b111, Mixed}, asm, ".4s", ".16b", ".4b",
8766                                               V128, v4i32, v16i8, OpNode>;
8769 // TODO: The vectors v8i8 and v16i8 should be v8f8 and v16f8
8770 multiclass SIMDThreeSameVectorFP8DOT4Index<string asm> {
8771   def v8f8 : BaseSIMDThreeSameVectorIndexS<0b0, 0b0, 0b00, 0b0000, asm, ".2s", ".8b", ".4b",
8772                                            V64, v2f32, v8i8, null_frag>;
8773   def v16f8 : BaseSIMDThreeSameVectorIndexS<0b1, 0b0, 0b00, 0b0000, asm, ".4s", ".16b",".4b",
8774                                             V128, v4f32, v16i8, null_frag>;
8777 // ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed)
8778 let mayRaiseFPException = 1, Uses = [FPCR] in
8779 class BaseSIMDThreeSameVectorIndexH<bit Q, bit U, bits<2> sz, bits<4> opc, string asm,
8780                                       string dst_kind, string lhs_kind,
8781                                       string rhs_kind, RegisterOperand RegType,
8782                                       RegisterOperand RegType_lo, ValueType AccumType,
8783                                       ValueType InputType, SDPatternOperator OpNode> :
8784         BaseSIMDIndexedTied<Q, U, 0, sz, opc, RegType, RegType, RegType_lo,
8785                             VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind,
8786           [(set (AccumType RegType:$dst),
8787                 (AccumType (OpNode (AccumType RegType:$Rd),
8788                                    (InputType RegType:$Rn),
8789                                    (InputType (AArch64duplane16 (v8f16 V128_lo:$Rm),
8790                                                 VectorIndexH:$idx)))))]> {
8791   // idx = H:L:M
8792   bits<3> idx;
8793   let Inst{11} = idx{2}; // H
8794   let Inst{21} = idx{1}; // L
8795   let Inst{20} = idx{0}; // M
8798 multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm,
8799                                        SDPatternOperator OpNode> {
8800   def v4f16 : BaseSIMDThreeSameVectorIndexH<0, U, 0b10, opc, asm, ".2s", ".2h", ".h",
8801                                               V64, V128_lo, v2f32, v4f16, OpNode>;
8802   def v8f16 : BaseSIMDThreeSameVectorIndexH<1, U, 0b10, opc, asm, ".4s", ".4h", ".h",
8803                                               V128, V128_lo, v4f32, v8f16, OpNode>;
8806 //----------------------------------------------------------------------------
8807 // FP8 Advanced SIMD vector x indexed element
8808 // TODO: Replace value types v8i8 and v16i8 by v8f8 and v16f8
8809 multiclass SIMDThreeSameVectorFP8DOT2Index<string asm> {
8810   def v4f16 : BaseSIMDThreeSameVectorIndexH<0b0, 0b0, 0b01, 0b0000, asm, ".4h", ".8b", ".2b",
8811                                             V64, V128_lo, v4f16, v8i8, null_frag>;
8812   def v8f16 : BaseSIMDThreeSameVectorIndexH<0b1, 0b0, 0b01, 0b0000, asm, ".8h", ".16b", ".2b",
8813                                             V128, V128_lo, v8f16, v8i16, null_frag>;
8816 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
8817                          SDPatternOperator OpNode> {
8818   let mayRaiseFPException = 1, Uses = [FPCR] in {
8819   let Predicates = [HasNEON, HasFullFP16] in {
8820   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
8821                                       V64, V64,
8822                                       V128_lo, VectorIndexH,
8823                                       asm, ".4h", ".4h", ".4h", ".h",
8824     [(set (v4f16 V64:$Rd),
8825         (OpNode (v4f16 V64:$Rn),
8826          (dup_v8f16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
8827     bits<3> idx;
8828     let Inst{11} = idx{2};
8829     let Inst{21} = idx{1};
8830     let Inst{20} = idx{0};
8831   }
8833   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
8834                                       V128, V128,
8835                                       V128_lo, VectorIndexH,
8836                                       asm, ".8h", ".8h", ".8h", ".h",
8837     [(set (v8f16 V128:$Rd),
8838         (OpNode (v8f16 V128:$Rn),
8839          (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8840     bits<3> idx;
8841     let Inst{11} = idx{2};
8842     let Inst{21} = idx{1};
8843     let Inst{20} = idx{0};
8844   }
8845   } // Predicates = [HasNEON, HasFullFP16]
8847   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8848                                       V64, V64,
8849                                       V128, VectorIndexS,
8850                                       asm, ".2s", ".2s", ".2s", ".s",
8851     [(set (v2f32 V64:$Rd),
8852         (OpNode (v2f32 V64:$Rn),
8853          (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> {
8854     bits<2> idx;
8855     let Inst{11} = idx{1};
8856     let Inst{21} = idx{0};
8857   }
8859   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8860                                       V128, V128,
8861                                       V128, VectorIndexS,
8862                                       asm, ".4s", ".4s", ".4s", ".s",
8863     [(set (v4f32 V128:$Rd),
8864         (OpNode (v4f32 V128:$Rn),
8865          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8866     bits<2> idx;
8867     let Inst{11} = idx{1};
8868     let Inst{21} = idx{0};
8869   }
8871   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
8872                                       V128, V128,
8873                                       V128, VectorIndexD,
8874                                       asm, ".2d", ".2d", ".2d", ".d",
8875     [(set (v2f64 V128:$Rd),
8876         (OpNode (v2f64 V128:$Rn),
8877          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
8878     bits<1> idx;
8879     let Inst{11} = idx{0};
8880     let Inst{21} = 0;
8881   }
8883   let Predicates = [HasNEON, HasFullFP16] in {
8884   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
8885                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8886                                       asm, ".h", "", "", ".h",
8887     [(set (f16 FPR16Op:$Rd),
8888           (OpNode (f16 FPR16Op:$Rn),
8889                   (f16 (vector_extract (v8f16 V128_lo:$Rm),
8890                                        VectorIndexH:$idx))))]> {
8891     bits<3> idx;
8892     let Inst{11} = idx{2};
8893     let Inst{21} = idx{1};
8894     let Inst{20} = idx{0};
8895   }
8896   } // Predicates = [HasNEON, HasFullFP16]
8898   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8899                                       FPR32Op, FPR32Op, V128, VectorIndexS,
8900                                       asm, ".s", "", "", ".s",
8901     [(set (f32 FPR32Op:$Rd),
8902           (OpNode (f32 FPR32Op:$Rn),
8903                   (f32 (vector_extract (v4f32 V128:$Rm),
8904                                        VectorIndexS:$idx))))]> {
8905     bits<2> idx;
8906     let Inst{11} = idx{1};
8907     let Inst{21} = idx{0};
8908   }
8910   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
8911                                       FPR64Op, FPR64Op, V128, VectorIndexD,
8912                                       asm, ".d", "", "", ".d",
8913     [(set (f64 FPR64Op:$Rd),
8914           (OpNode (f64 FPR64Op:$Rn),
8915                   (f64 (vector_extract (v2f64 V128:$Rm),
8916                                        VectorIndexD:$idx))))]> {
8917     bits<1> idx;
8918     let Inst{11} = idx{0};
8919     let Inst{21} = 0;
8920   }
8921   } // mayRaiseFPException = 1, Uses = [FPCR]
8923   let Predicates = [HasNEON, HasFullFP16] in {
8924   def : Pat<(f16 (OpNode
8925                    (f16 (vector_extract (v8f16 V128:$Rn), (i64 0))),
8926                    (f16 (vector_extract (v8f16 V128:$Rm), VectorIndexH:$idx)))),
8927             (!cast<Instruction>(NAME # v1i16_indexed)
8928               (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128:$Rm, VectorIndexH:$idx)>;
8929   }
8931   let Predicates = [HasNEON] in {
8932   def : Pat<(f32 (OpNode
8933                    (f32 (vector_extract (v4f32 V128:$Rn), (i64 0))),
8934                    (f32 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx)))),
8935             (!cast<Instruction>(NAME # v1i32_indexed)
8936               (EXTRACT_SUBREG V128:$Rn, ssub), V128:$Rm, VectorIndexS:$idx)>;
8938   def : Pat<(f64 (OpNode
8939                    (f64 (vector_extract (v2f64 V128:$Rn), (i64 0))),
8940                    (f64 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx)))),
8941             (!cast<Instruction>(NAME # v1i64_indexed)
8942               (EXTRACT_SUBREG V128:$Rn, dsub), V128:$Rm, VectorIndexD:$idx)>;
8943   }
8946 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
8947   let Predicates = [HasNEON, HasFullFP16] in {
8948   // Patterns for f16: DUPLANE, DUP scalar and vector_extract.
8949   def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8950                            (AArch64duplane16 (v8f16 V128_lo:$Rm),
8951                                            VectorIndexH:$idx))),
8952             (!cast<Instruction>(INST # "v8i16_indexed")
8953                 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8954   def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8955                            (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8956             (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn,
8957                 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8959   def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8960                            (AArch64duplane16 (v8f16 V128_lo:$Rm),
8961                                            VectorIndexH:$idx))),
8962             (!cast<Instruction>(INST # "v4i16_indexed")
8963                 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8964   def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8965                            (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8966             (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn,
8967                 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8969   def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn),
8970                          (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))),
8971             (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn,
8972                 V128_lo:$Rm, VectorIndexH:$idx)>;
8973   } // Predicates = [HasNEON, HasFullFP16]
8975   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
8976   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8977                            (AArch64duplane32 (v4f32 V128:$Rm),
8978                                            VectorIndexS:$idx))),
8979             (!cast<Instruction>(INST # v2i32_indexed)
8980                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8981   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8982                            (AArch64dup (f32 FPR32Op:$Rm)))),
8983             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
8984                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8987   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
8988   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8989                            (AArch64duplane32 (v4f32 V128:$Rm),
8990                                            VectorIndexS:$idx))),
8991             (!cast<Instruction>(INST # "v4i32_indexed")
8992                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8993   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8994                            (AArch64dup (f32 FPR32Op:$Rm)))),
8995             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
8996                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8998   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
8999   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
9000                            (AArch64duplane64 (v2f64 V128:$Rm),
9001                                            VectorIndexD:$idx))),
9002             (!cast<Instruction>(INST # "v2i64_indexed")
9003                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
9004   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
9005                            (AArch64dup (f64 FPR64Op:$Rm)))),
9006             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
9007                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
9009   // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s
9010   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
9011                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
9012             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
9013                 V128:$Rm, VectorIndexS:$idx)>;
9015   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
9016   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
9017                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
9018             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
9019                 V128:$Rm, VectorIndexD:$idx)>;
9022 let mayRaiseFPException = 1, Uses = [FPCR] in
9023 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
9024   let Predicates = [HasNEON, HasFullFP16] in {
9025   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
9026                                           V128_lo, VectorIndexH,
9027                                           asm, ".4h", ".4h", ".4h", ".h", []> {
9028     bits<3> idx;
9029     let Inst{11} = idx{2};
9030     let Inst{21} = idx{1};
9031     let Inst{20} = idx{0};
9032   }
9034   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
9035                                           V128, V128,
9036                                           V128_lo, VectorIndexH,
9037                                           asm, ".8h", ".8h", ".8h", ".h", []> {
9038     bits<3> idx;
9039     let Inst{11} = idx{2};
9040     let Inst{21} = idx{1};
9041     let Inst{20} = idx{0};
9042   }
9043   } // Predicates = [HasNEON, HasFullFP16]
9045   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
9046                                           V128, VectorIndexS,
9047                                           asm, ".2s", ".2s", ".2s", ".s", []> {
9048     bits<2> idx;
9049     let Inst{11} = idx{1};
9050     let Inst{21} = idx{0};
9051   }
9053   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9054                                       V128, V128,
9055                                       V128, VectorIndexS,
9056                                       asm, ".4s", ".4s", ".4s", ".s", []> {
9057     bits<2> idx;
9058     let Inst{11} = idx{1};
9059     let Inst{21} = idx{0};
9060   }
9062   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
9063                                       V128, V128,
9064                                       V128, VectorIndexD,
9065                                       asm, ".2d", ".2d", ".2d", ".d", []> {
9066     bits<1> idx;
9067     let Inst{11} = idx{0};
9068     let Inst{21} = 0;
9069   }
9071   let Predicates = [HasNEON, HasFullFP16] in {
9072   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
9073                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
9074                                       asm, ".h", "", "", ".h", []> {
9075     bits<3> idx;
9076     let Inst{11} = idx{2};
9077     let Inst{21} = idx{1};
9078     let Inst{20} = idx{0};
9079   }
9080   } // Predicates = [HasNEON, HasFullFP16]
9082   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9083                                       FPR32Op, FPR32Op, V128, VectorIndexS,
9084                                       asm, ".s", "", "", ".s", []> {
9085     bits<2> idx;
9086     let Inst{11} = idx{1};
9087     let Inst{21} = idx{0};
9088   }
9090   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
9091                                       FPR64Op, FPR64Op, V128, VectorIndexD,
9092                                       asm, ".d", "", "", ".d", []> {
9093     bits<1> idx;
9094     let Inst{11} = idx{0};
9095     let Inst{21} = 0;
9096   }
9099 multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane,
9100                                  SDPatternOperator OpNodeLaneQ> {
9102   def : Pat<(v4i16 (OpNodeLane
9103                      (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm),
9104                      VectorIndexS32b:$idx)),
9105             (!cast<Instruction>(NAME # v4i16_indexed) $Rn,
9106               (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub),
9107               (UImmS1XForm $idx))>;
9109   def : Pat<(v4i16 (OpNodeLaneQ
9110                      (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm),
9111                      VectorIndexH32b:$idx)),
9112             (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm,
9113               (UImmS1XForm $idx))>;
9115   def : Pat<(v8i16 (OpNodeLane
9116                      (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm),
9117                      VectorIndexS32b:$idx)),
9118             (!cast<Instruction>(NAME # v8i16_indexed) $Rn,
9119               (SUBREG_TO_REG (i32 0), $Rm, dsub),
9120               (UImmS1XForm $idx))>;
9122   def : Pat<(v8i16 (OpNodeLaneQ
9123                      (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm),
9124                      VectorIndexH32b:$idx)),
9125             (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm,
9126               (UImmS1XForm $idx))>;
9128   def : Pat<(v2i32 (OpNodeLane
9129                      (v2i32 V64:$Rn), (v2i32 V64:$Rm),
9130                      VectorIndexD32b:$idx)),
9131             (!cast<Instruction>(NAME # v2i32_indexed) $Rn,
9132               (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub),
9133               (UImmS1XForm $idx))>;
9135   def : Pat<(v2i32 (OpNodeLaneQ
9136                      (v2i32 V64:$Rn), (v4i32 V128:$Rm),
9137                      VectorIndexS32b:$idx)),
9138             (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm,
9139               (UImmS1XForm $idx))>;
9141   def : Pat<(v4i32 (OpNodeLane
9142                      (v4i32 V128:$Rn), (v2i32 V64:$Rm),
9143                      VectorIndexD32b:$idx)),
9144             (!cast<Instruction>(NAME # v4i32_indexed) $Rn,
9145               (SUBREG_TO_REG (i32 0), $Rm, dsub),
9146               (UImmS1XForm $idx))>;
9148   def : Pat<(v4i32 (OpNodeLaneQ
9149                      (v4i32 V128:$Rn),
9150                      (v4i32 V128:$Rm),
9151                      VectorIndexS32b:$idx)),
9152             (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm,
9153               (UImmS1XForm $idx))>;
9157 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
9158                          SDPatternOperator OpNode> {
9159   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
9160                                       V128_lo, VectorIndexH,
9161                                       asm, ".4h", ".4h", ".4h", ".h",
9162     [(set (v4i16 V64:$Rd),
9163         (OpNode (v4i16 V64:$Rn),
9164          (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9165     bits<3> idx;
9166     let Inst{11} = idx{2};
9167     let Inst{21} = idx{1};
9168     let Inst{20} = idx{0};
9169   }
9171   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
9172                                       V128, V128,
9173                                       V128_lo, VectorIndexH,
9174                                       asm, ".8h", ".8h", ".8h", ".h",
9175     [(set (v8i16 V128:$Rd),
9176        (OpNode (v8i16 V128:$Rn),
9177          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
9178     bits<3> idx;
9179     let Inst{11} = idx{2};
9180     let Inst{21} = idx{1};
9181     let Inst{20} = idx{0};
9182   }
9184   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9185                                       V64, V64,
9186                                       V128, VectorIndexS,
9187                                       asm, ".2s", ".2s", ".2s",  ".s",
9188     [(set (v2i32 V64:$Rd),
9189        (OpNode (v2i32 V64:$Rn),
9190           (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9191     bits<2> idx;
9192     let Inst{11} = idx{1};
9193     let Inst{21} = idx{0};
9194   }
9196   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
9197                                       V128, V128,
9198                                       V128, VectorIndexS,
9199                                       asm, ".4s", ".4s", ".4s", ".s",
9200     [(set (v4i32 V128:$Rd),
9201        (OpNode (v4i32 V128:$Rn),
9202           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
9203     bits<2> idx;
9204     let Inst{11} = idx{1};
9205     let Inst{21} = idx{0};
9206   }
9208   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
9209                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
9210                                       asm, ".h", "", "", ".h", []> {
9211     bits<3> idx;
9212     let Inst{11} = idx{2};
9213     let Inst{21} = idx{1};
9214     let Inst{20} = idx{0};
9215   }
9217   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
9218                                       FPR32Op, FPR32Op, V128, VectorIndexS,
9219                                       asm, ".s", "", "", ".s",
9220       [(set (i32 FPR32Op:$Rd),
9221             (OpNode FPR32Op:$Rn,
9222                     (i32 (vector_extract (v4i32 V128:$Rm),
9223                                          VectorIndexS:$idx))))]> {
9224     bits<2> idx;
9225     let Inst{11} = idx{1};
9226     let Inst{21} = idx{0};
9227   }
9230 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
9231                                SDPatternOperator OpNode> {
9232   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
9233                                       V64, V64,
9234                                       V128_lo, VectorIndexH,
9235                                       asm, ".4h", ".4h", ".4h", ".h",
9236     [(set (v4i16 V64:$Rd),
9237         (OpNode (v4i16 V64:$Rn),
9238          (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9239     bits<3> idx;
9240     let Inst{11} = idx{2};
9241     let Inst{21} = idx{1};
9242     let Inst{20} = idx{0};
9243   }
9245   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
9246                                       V128, V128,
9247                                       V128_lo, VectorIndexH,
9248                                       asm, ".8h", ".8h", ".8h", ".h",
9249     [(set (v8i16 V128:$Rd),
9250        (OpNode (v8i16 V128:$Rn),
9251          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
9252     bits<3> idx;
9253     let Inst{11} = idx{2};
9254     let Inst{21} = idx{1};
9255     let Inst{20} = idx{0};
9256   }
9258   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9259                                       V64, V64,
9260                                       V128, VectorIndexS,
9261                                       asm, ".2s", ".2s", ".2s", ".s",
9262     [(set (v2i32 V64:$Rd),
9263        (OpNode (v2i32 V64:$Rn),
9264           (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9265     bits<2> idx;
9266     let Inst{11} = idx{1};
9267     let Inst{21} = idx{0};
9268   }
9270   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
9271                                       V128, V128,
9272                                       V128, VectorIndexS,
9273                                       asm, ".4s", ".4s", ".4s", ".s",
9274     [(set (v4i32 V128:$Rd),
9275        (OpNode (v4i32 V128:$Rn),
9276           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
9277     bits<2> idx;
9278     let Inst{11} = idx{1};
9279     let Inst{21} = idx{0};
9280   }
9283 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
9284                                    SDPatternOperator OpNode> {
9285   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
9286                                           V128_lo, VectorIndexH,
9287                                           asm, ".4h", ".4h", ".4h", ".h",
9288     [(set (v4i16 V64:$dst),
9289         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
9290          (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9291     bits<3> idx;
9292     let Inst{11} = idx{2};
9293     let Inst{21} = idx{1};
9294     let Inst{20} = idx{0};
9295   }
9297   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9298                                       V128, V128,
9299                                       V128_lo, VectorIndexH,
9300                                       asm, ".8h", ".8h", ".8h", ".h",
9301     [(set (v8i16 V128:$dst),
9302        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9303          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
9304     bits<3> idx;
9305     let Inst{11} = idx{2};
9306     let Inst{21} = idx{1};
9307     let Inst{20} = idx{0};
9308   }
9310   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9311                                       V64, V64,
9312                                       V128, VectorIndexS,
9313                                       asm, ".2s", ".2s", ".2s", ".s",
9314     [(set (v2i32 V64:$dst),
9315        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9316           (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9317     bits<2> idx;
9318     let Inst{11} = idx{1};
9319     let Inst{21} = idx{0};
9320   }
9322   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9323                                       V128, V128,
9324                                       V128, VectorIndexS,
9325                                       asm, ".4s", ".4s", ".4s", ".s",
9326     [(set (v4i32 V128:$dst),
9327        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9328           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
9329     bits<2> idx;
9330     let Inst{11} = idx{1};
9331     let Inst{21} = idx{0};
9332   }
9335 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
9336                              SDPatternOperator OpNode> {
9337   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
9338                                       V128, V64,
9339                                       V128_lo, VectorIndexH,
9340                                       asm, ".4s", ".4s", ".4h", ".h",
9341     [(set (v4i32 V128:$Rd),
9342         (OpNode (v4i16 V64:$Rn),
9343          (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9344     bits<3> idx;
9345     let Inst{11} = idx{2};
9346     let Inst{21} = idx{1};
9347     let Inst{20} = idx{0};
9348   }
9350   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
9351                                       V128, V128,
9352                                       V128_lo, VectorIndexH,
9353                                       asm#"2", ".4s", ".4s", ".8h", ".h",
9354     [(set (v4i32 V128:$Rd),
9355           (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),
9356                   (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9358     bits<3> idx;
9359     let Inst{11} = idx{2};
9360     let Inst{21} = idx{1};
9361     let Inst{20} = idx{0};
9362   }
9364   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9365                                       V128, V64,
9366                                       V128, VectorIndexS,
9367                                       asm, ".2d", ".2d", ".2s", ".s",
9368     [(set (v2i64 V128:$Rd),
9369         (OpNode (v2i32 V64:$Rn),
9370          (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9371     bits<2> idx;
9372     let Inst{11} = idx{1};
9373     let Inst{21} = idx{0};
9374   }
9376   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
9377                                       V128, V128,
9378                                       V128, VectorIndexS,
9379                                       asm#"2", ".2d", ".2d", ".4s", ".s",
9380     [(set (v2i64 V128:$Rd),
9381           (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),
9382                   (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9383     bits<2> idx;
9384     let Inst{11} = idx{1};
9385     let Inst{21} = idx{0};
9386   }
9388   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
9389                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
9390                                       asm, ".h", "", "", ".h", []> {
9391     bits<3> idx;
9392     let Inst{11} = idx{2};
9393     let Inst{21} = idx{1};
9394     let Inst{20} = idx{0};
9395   }
9397   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
9398                                       FPR64Op, FPR32Op, V128, VectorIndexS,
9399                                       asm, ".s", "", "", ".s", []> {
9400     bits<2> idx;
9401     let Inst{11} = idx{1};
9402     let Inst{21} = idx{0};
9403   }
9406 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
9407                                        SDPatternOperator Accum> {
9408   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9409                                       V128, V64,
9410                                       V128_lo, VectorIndexH,
9411                                       asm, ".4s", ".4s", ".4h", ".h",
9412     [(set (v4i32 V128:$dst),
9413           (Accum (v4i32 V128:$Rd),
9414                  (v4i32 (int_aarch64_neon_sqdmull
9415                              (v4i16 V64:$Rn),
9416                              (dup_v8i16 (v8i16 V128_lo:$Rm),
9417                                          VectorIndexH:$idx)))))]> {
9418     bits<3> idx;
9419     let Inst{11} = idx{2};
9420     let Inst{21} = idx{1};
9421     let Inst{20} = idx{0};
9422   }
9424   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9425                                       V128, V128,
9426                                       V128_lo, VectorIndexH,
9427                                       asm#"2", ".4s", ".4s", ".8h", ".h",
9428     [(set (v4i32 V128:$dst),
9429           (Accum (v4i32 V128:$Rd),
9430                  (v4i32 (int_aarch64_neon_sqdmull
9431                             (extract_high_v8i16 (v8i16 V128:$Rn)),
9432                             (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> {
9433     bits<3> idx;
9434     let Inst{11} = idx{2};
9435     let Inst{21} = idx{1};
9436     let Inst{20} = idx{0};
9437   }
9439   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9440                                       V128, V64,
9441                                       V128, VectorIndexS,
9442                                       asm, ".2d", ".2d", ".2s", ".s",
9443     [(set (v2i64 V128:$dst),
9444         (Accum (v2i64 V128:$Rd),
9445                (v2i64 (int_aarch64_neon_sqdmull
9446                           (v2i32 V64:$Rn),
9447                           (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> {
9448     bits<2> idx;
9449     let Inst{11} = idx{1};
9450     let Inst{21} = idx{0};
9451   }
9453   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9454                                       V128, V128,
9455                                       V128, VectorIndexS,
9456                                       asm#"2", ".2d", ".2d", ".4s", ".s",
9457     [(set (v2i64 V128:$dst),
9458           (Accum (v2i64 V128:$Rd),
9459                  (v2i64 (int_aarch64_neon_sqdmull
9460                             (extract_high_v4i32 (v4i32 V128:$Rn)),
9461                             (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> {
9462     bits<2> idx;
9463     let Inst{11} = idx{1};
9464     let Inst{21} = idx{0};
9465   }
9467   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9468                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
9469                                       asm, ".h", "", "", ".h", []> {
9470     bits<3> idx;
9471     let Inst{11} = idx{2};
9472     let Inst{21} = idx{1};
9473     let Inst{20} = idx{0};
9474   }
9476   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9477                         (i32 (vector_extract
9478                                     (v4i32 (int_aarch64_neon_sqdmull
9479                                                 (v4i16 V64:$Rn),
9480                                                 (v4i16 V64:$Rm))),
9481                                     (i64 0))))),
9482             (!cast<Instruction>(NAME # v1i32_indexed)
9483                         FPR32Op:$Rd,
9484                         (f16 (EXTRACT_SUBREG V64:$Rn, hsub)),
9485                         (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub),
9486                         (i64 0))>;
9488   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9489                         (i32 (vector_extract
9490                                     (v4i32 (int_aarch64_neon_sqdmull
9491                                                 (v4i16 V64:$Rn),
9492                                                 (dup_v8i16 (v8i16 V128_lo:$Rm),
9493                                                             VectorIndexH:$idx))),
9494                                     (i64 0))))),
9495             (!cast<Instruction>(NAME # v1i32_indexed)
9496                         FPR32Op:$Rd,
9497                         (f16 (EXTRACT_SUBREG V64:$Rn, hsub)),
9498                         V128_lo:$Rm,
9499                         VectorIndexH:$idx)>;
9501   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9502                                       FPR64Op, FPR32Op, V128, VectorIndexS,
9503                                       asm, ".s", "", "", ".s",
9504     [(set (i64 FPR64Op:$dst),
9505           (Accum (i64 FPR64Op:$Rd),
9506                  (i64 (int_aarch64_neon_sqdmulls_scalar
9507                             (i32 FPR32Op:$Rn),
9508                             (i32 (vector_extract (v4i32 V128:$Rm),
9509                                                  VectorIndexS:$idx))))))]> {
9511     bits<2> idx;
9512     let Inst{11} = idx{1};
9513     let Inst{21} = idx{0};
9514   }
9517 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
9518                                    SDPatternOperator OpNode> {
9519   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
9520   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
9521                                       V128, V64,
9522                                       V128_lo, VectorIndexH,
9523                                       asm, ".4s", ".4s", ".4h", ".h",
9524     [(set (v4i32 V128:$Rd),
9525         (OpNode (v4i16 V64:$Rn),
9526          (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9527     bits<3> idx;
9528     let Inst{11} = idx{2};
9529     let Inst{21} = idx{1};
9530     let Inst{20} = idx{0};
9531   }
9533   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
9534                                       V128, V128,
9535                                       V128_lo, VectorIndexH,
9536                                       asm#"2", ".4s", ".4s", ".8h", ".h",
9537     [(set (v4i32 V128:$Rd),
9538           (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),
9539                   (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9541     bits<3> idx;
9542     let Inst{11} = idx{2};
9543     let Inst{21} = idx{1};
9544     let Inst{20} = idx{0};
9545   }
9547   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9548                                       V128, V64,
9549                                       V128, VectorIndexS,
9550                                       asm, ".2d", ".2d", ".2s", ".s",
9551     [(set (v2i64 V128:$Rd),
9552         (OpNode (v2i32 V64:$Rn),
9553          (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9554     bits<2> idx;
9555     let Inst{11} = idx{1};
9556     let Inst{21} = idx{0};
9557   }
9559   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
9560                                       V128, V128,
9561                                       V128, VectorIndexS,
9562                                       asm#"2", ".2d", ".2d", ".4s", ".s",
9563     [(set (v2i64 V128:$Rd),
9564           (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),
9565                   (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9566     bits<2> idx;
9567     let Inst{11} = idx{1};
9568     let Inst{21} = idx{0};
9569   }
9570   }
9573 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
9574                                        SDPatternOperator OpNode> {
9575   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
9576   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9577                                       V128, V64,
9578                                       V128_lo, VectorIndexH,
9579                                       asm, ".4s", ".4s", ".4h", ".h",
9580     [(set (v4i32 V128:$dst),
9581         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
9582          (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9583     bits<3> idx;
9584     let Inst{11} = idx{2};
9585     let Inst{21} = idx{1};
9586     let Inst{20} = idx{0};
9587   }
9589   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9590                                       V128, V128,
9591                                       V128_lo, VectorIndexH,
9592                                       asm#"2", ".4s", ".4s", ".8h", ".h",
9593     [(set (v4i32 V128:$dst),
9594           (OpNode (v4i32 V128:$Rd),
9595                   (extract_high_v8i16 (v8i16 V128:$Rn)),
9596                   (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {
9597     bits<3> idx;
9598     let Inst{11} = idx{2};
9599     let Inst{21} = idx{1};
9600     let Inst{20} = idx{0};
9601   }
9603   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9604                                       V128, V64,
9605                                       V128, VectorIndexS,
9606                                       asm, ".2d", ".2d", ".2s", ".s",
9607     [(set (v2i64 V128:$dst),
9608         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
9609          (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9610     bits<2> idx;
9611     let Inst{11} = idx{1};
9612     let Inst{21} = idx{0};
9613   }
9615   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9616                                       V128, V128,
9617                                       V128, VectorIndexS,
9618                                       asm#"2", ".2d", ".2d", ".4s", ".s",
9619     [(set (v2i64 V128:$dst),
9620           (OpNode (v2i64 V128:$Rd),
9621                   (extract_high_v4i32 (v4i32 V128:$Rn)),
9622                   (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9623     bits<2> idx;
9624     let Inst{11} = idx{1};
9625     let Inst{21} = idx{0};
9626   }
9627   }
9630 //----------------------------------------------------------------------------
9631 // AdvSIMD scalar shift by immediate
9632 //----------------------------------------------------------------------------
9634 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9635 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
9636                      RegisterClass regtype1, RegisterClass regtype2,
9637                      Operand immtype, string asm, list<dag> pattern>
9638   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
9639       asm, "\t$Rd, $Rn, $imm", "", pattern>,
9640     Sched<[WriteVd]> {
9641   bits<5> Rd;
9642   bits<5> Rn;
9643   bits<7> imm;
9644   let Inst{31-30} = 0b01;
9645   let Inst{29}    = U;
9646   let Inst{28-23} = 0b111110;
9647   let Inst{22-16} = fixed_imm;
9648   let Inst{15-11} = opc;
9649   let Inst{10}    = 1;
9650   let Inst{9-5} = Rn;
9651   let Inst{4-0} = Rd;
9654 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9655 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
9656                      RegisterClass regtype1, RegisterClass regtype2,
9657                      Operand immtype, string asm, list<dag> pattern>
9658   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
9659       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
9660     Sched<[WriteVd]> {
9661   bits<5> Rd;
9662   bits<5> Rn;
9663   bits<7> imm;
9664   let Inst{31-30} = 0b01;
9665   let Inst{29}    = U;
9666   let Inst{28-23} = 0b111110;
9667   let Inst{22-16} = fixed_imm;
9668   let Inst{15-11} = opc;
9669   let Inst{10}    = 1;
9670   let Inst{9-5} = Rn;
9671   let Inst{4-0} = Rd;
9675 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
9676   let Predicates = [HasNEON, HasFullFP16] in {
9677   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9678                               FPR16, FPR16, vecshiftR16, asm, []> {
9679     let Inst{19-16} = imm{3-0};
9680   }
9681   } // Predicates = [HasNEON, HasFullFP16]
9682   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9683                               FPR32, FPR32, vecshiftR32, asm, []> {
9684     let Inst{20-16} = imm{4-0};
9685   }
9686   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9687                               FPR64, FPR64, vecshiftR64, asm, []> {
9688     let Inst{21-16} = imm{5-0};
9689   }
9692 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
9693                              SDPatternOperator OpNode> {
9694   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9695                               FPR64, FPR64, vecshiftR64, asm,
9696   [(set (i64 FPR64:$Rd),
9697      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
9698     let Inst{21-16} = imm{5-0};
9699   }
9701   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
9702             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
9705 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
9706                                  SDPatternOperator OpNode = null_frag> {
9707   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
9708                               FPR64, FPR64, vecshiftR64, asm,
9709   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
9710                                                    (i32 vecshiftR64:$imm)))]> {
9711     let Inst{21-16} = imm{5-0};
9712   }
9714   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
9715                            (i32 vecshiftR64:$imm))),
9716             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
9717                                             vecshiftR64:$imm)>;
9720 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
9721                              SDPatternOperator OpNode> {
9722   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9723                               FPR64, FPR64, vecshiftL64, asm,
9724     [(set (i64 FPR64:$Rd),
9725        (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
9726     let Inst{21-16} = imm{5-0};
9727   }
9729   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
9730             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
9733 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9734 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
9735   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
9736                               FPR64, FPR64, vecshiftL64, asm, []> {
9737     let Inst{21-16} = imm{5-0};
9738   }
9741 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9742 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
9743                                SDPatternOperator OpNode = null_frag> {
9744   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
9745                               FPR8, FPR16, vecshiftR8, asm, []> {
9746     let Inst{18-16} = imm{2-0};
9747   }
9749   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9750                               FPR16, FPR32, vecshiftR16, asm, []> {
9751     let Inst{19-16} = imm{3-0};
9752   }
9754   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9755                               FPR32, FPR64, vecshiftR32, asm,
9756     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
9757     let Inst{20-16} = imm{4-0};
9758   }
9761 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
9762                                 SDPatternOperator OpNode> {
9763   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
9764                               FPR8, FPR8, vecshiftL8, asm, []> {
9765     let Inst{18-16} = imm{2-0};
9766   }
9768   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9769                               FPR16, FPR16, vecshiftL16, asm, []> {
9770     let Inst{19-16} = imm{3-0};
9771   }
9773   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9774                               FPR32, FPR32, vecshiftL32, asm,
9775     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
9776     let Inst{20-16} = imm{4-0};
9777   }
9779   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9780                               FPR64, FPR64, vecshiftL64, asm,
9781     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
9782     let Inst{21-16} = imm{5-0};
9783   }
9785   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
9786             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
9789 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
9790   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
9791                               FPR8, FPR8, vecshiftR8, asm, []> {
9792     let Inst{18-16} = imm{2-0};
9793   }
9795   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9796                               FPR16, FPR16, vecshiftR16, asm, []> {
9797     let Inst{19-16} = imm{3-0};
9798   }
9800   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9801                               FPR32, FPR32, vecshiftR32, asm, []> {
9802     let Inst{20-16} = imm{4-0};
9803   }
9805   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9806                               FPR64, FPR64, vecshiftR64, asm, []> {
9807     let Inst{21-16} = imm{5-0};
9808   }
9811 //----------------------------------------------------------------------------
9812 // AdvSIMD vector x indexed element
9813 //----------------------------------------------------------------------------
9815 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9816 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
9817                      RegisterOperand dst_reg, RegisterOperand src_reg,
9818                      Operand immtype,
9819                      string asm, string dst_kind, string src_kind,
9820                      list<dag> pattern>
9821   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
9822       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
9823            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
9824     Sched<[!if(Q, WriteVq, WriteVd)]> {
9825   bits<5> Rd;
9826   bits<5> Rn;
9827   let Inst{31}    = 0;
9828   let Inst{30}    = Q;
9829   let Inst{29}    = U;
9830   let Inst{28-23} = 0b011110;
9831   let Inst{22-16} = fixed_imm;
9832   let Inst{15-11} = opc;
9833   let Inst{10}    = 1;
9834   let Inst{9-5}   = Rn;
9835   let Inst{4-0}   = Rd;
9838 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9839 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
9840                      RegisterOperand vectype1, RegisterOperand vectype2,
9841                      Operand immtype,
9842                      string asm, string dst_kind, string src_kind,
9843                      list<dag> pattern>
9844   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
9845       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
9846            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
9847     Sched<[!if(Q, WriteVq, WriteVd)]> {
9848   bits<5> Rd;
9849   bits<5> Rn;
9850   let Inst{31}    = 0;
9851   let Inst{30}    = Q;
9852   let Inst{29}    = U;
9853   let Inst{28-23} = 0b011110;
9854   let Inst{22-16} = fixed_imm;
9855   let Inst{15-11} = opc;
9856   let Inst{10}    = 1;
9857   let Inst{9-5}   = Rn;
9858   let Inst{4-0}   = Rd;
9861 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
9862                               Intrinsic OpNode> {
9863   let Predicates = [HasNEON, HasFullFP16] in {
9864   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9865                                   V64, V64, vecshiftR16,
9866                                   asm, ".4h", ".4h",
9867       [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
9868     bits<4> imm;
9869     let Inst{19-16} = imm;
9870   }
9872   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9873                                   V128, V128, vecshiftR16,
9874                                   asm, ".8h", ".8h",
9875       [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
9876     bits<4> imm;
9877     let Inst{19-16} = imm;
9878   }
9879   } // Predicates = [HasNEON, HasFullFP16]
9880   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9881                                   V64, V64, vecshiftR32,
9882                                   asm, ".2s", ".2s",
9883       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
9884     bits<5> imm;
9885     let Inst{20-16} = imm;
9886   }
9888   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9889                                   V128, V128, vecshiftR32,
9890                                   asm, ".4s", ".4s",
9891       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
9892     bits<5> imm;
9893     let Inst{20-16} = imm;
9894   }
9896   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9897                                   V128, V128, vecshiftR64,
9898                                   asm, ".2d", ".2d",
9899       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
9900     bits<6> imm;
9901     let Inst{21-16} = imm;
9902   }
9905 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
9906                                   Intrinsic OpNode> {
9907   let Predicates = [HasNEON, HasFullFP16] in {
9908   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9909                                   V64, V64, vecshiftR16,
9910                                   asm, ".4h", ".4h",
9911       [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
9912     bits<4> imm;
9913     let Inst{19-16} = imm;
9914   }
9916   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9917                                   V128, V128, vecshiftR16,
9918                                   asm, ".8h", ".8h",
9919       [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
9920     bits<4> imm;
9921     let Inst{19-16} = imm;
9922   }
9923   } // Predicates = [HasNEON, HasFullFP16]
9925   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9926                                   V64, V64, vecshiftR32,
9927                                   asm, ".2s", ".2s",
9928       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
9929     bits<5> imm;
9930     let Inst{20-16} = imm;
9931   }
9933   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9934                                   V128, V128, vecshiftR32,
9935                                   asm, ".4s", ".4s",
9936       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
9937     bits<5> imm;
9938     let Inst{20-16} = imm;
9939   }
9941   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9942                                   V128, V128, vecshiftR64,
9943                                   asm, ".2d", ".2d",
9944       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
9945     bits<6> imm;
9946     let Inst{21-16} = imm;
9947   }
9950 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
9951                                      SDPatternOperator OpNode> {
9952   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9953                                   V64, V128, vecshiftR16Narrow,
9954                                   asm, ".8b", ".8h",
9955       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
9956     bits<3> imm;
9957     let Inst{18-16} = imm;
9958   }
9960   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9961                                   V128, V128, vecshiftR16Narrow,
9962                                   asm#"2", ".16b", ".8h", []> {
9963     bits<3> imm;
9964     let Inst{18-16} = imm;
9965     let hasSideEffects = 0;
9966   }
9968   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9969                                   V64, V128, vecshiftR32Narrow,
9970                                   asm, ".4h", ".4s",
9971       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
9972     bits<4> imm;
9973     let Inst{19-16} = imm;
9974   }
9976   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9977                                   V128, V128, vecshiftR32Narrow,
9978                                   asm#"2", ".8h", ".4s", []> {
9979     bits<4> imm;
9980     let Inst{19-16} = imm;
9981     let hasSideEffects = 0;
9982   }
9984   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9985                                   V64, V128, vecshiftR64Narrow,
9986                                   asm, ".2s", ".2d",
9987       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
9988     bits<5> imm;
9989     let Inst{20-16} = imm;
9990   }
9992   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9993                                   V128, V128, vecshiftR64Narrow,
9994                                   asm#"2", ".4s", ".2d", []> {
9995     bits<5> imm;
9996     let Inst{20-16} = imm;
9997     let hasSideEffects = 0;
9998   }
10000   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
10001   // themselves, so put them here instead.
10003   // Patterns involving what's effectively an insert high and a normal
10004   // intrinsic, represented by CONCAT_VECTORS.
10005   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
10006                                                    vecshiftR16Narrow:$imm)),
10007             (!cast<Instruction>(NAME # "v16i8_shift")
10008                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
10009                 V128:$Rn, vecshiftR16Narrow:$imm)>;
10010   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
10011                                                      vecshiftR32Narrow:$imm)),
10012             (!cast<Instruction>(NAME # "v8i16_shift")
10013                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
10014                 V128:$Rn, vecshiftR32Narrow:$imm)>;
10015   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
10016                                                      vecshiftR64Narrow:$imm)),
10017             (!cast<Instruction>(NAME # "v4i32_shift")
10018                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
10019                 V128:$Rn, vecshiftR64Narrow:$imm)>;
10022 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
10023                                 SDPatternOperator OpNode> {
10024   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
10025                                   V64, V64, vecshiftL8,
10026                                   asm, ".8b", ".8b",
10027                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
10028                        (i32 vecshiftL8:$imm)))]> {
10029     bits<3> imm;
10030     let Inst{18-16} = imm;
10031   }
10033   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
10034                                   V128, V128, vecshiftL8,
10035                                   asm, ".16b", ".16b",
10036              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
10037                    (i32 vecshiftL8:$imm)))]> {
10038     bits<3> imm;
10039     let Inst{18-16} = imm;
10040   }
10042   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
10043                                   V64, V64, vecshiftL16,
10044                                   asm, ".4h", ".4h",
10045               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
10046                     (i32 vecshiftL16:$imm)))]> {
10047     bits<4> imm;
10048     let Inst{19-16} = imm;
10049   }
10051   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
10052                                   V128, V128, vecshiftL16,
10053                                   asm, ".8h", ".8h",
10054             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
10055                   (i32 vecshiftL16:$imm)))]> {
10056     bits<4> imm;
10057     let Inst{19-16} = imm;
10058   }
10060   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
10061                                   V64, V64, vecshiftL32,
10062                                   asm, ".2s", ".2s",
10063               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
10064                     (i32 vecshiftL32:$imm)))]> {
10065     bits<5> imm;
10066     let Inst{20-16} = imm;
10067   }
10069   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
10070                                   V128, V128, vecshiftL32,
10071                                   asm, ".4s", ".4s",
10072             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
10073                   (i32 vecshiftL32:$imm)))]> {
10074     bits<5> imm;
10075     let Inst{20-16} = imm;
10076   }
10078   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
10079                                   V128, V128, vecshiftL64,
10080                                   asm, ".2d", ".2d",
10081             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
10082                   (i32 vecshiftL64:$imm)))]> {
10083     bits<6> imm;
10084     let Inst{21-16} = imm;
10085   }
10088 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
10089                                 SDPatternOperator OpNode> {
10090   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
10091                                   V64, V64, vecshiftR8,
10092                                   asm, ".8b", ".8b",
10093                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
10094                        (i32 vecshiftR8:$imm)))]> {
10095     bits<3> imm;
10096     let Inst{18-16} = imm;
10097   }
10099   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
10100                                   V128, V128, vecshiftR8,
10101                                   asm, ".16b", ".16b",
10102              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
10103                    (i32 vecshiftR8:$imm)))]> {
10104     bits<3> imm;
10105     let Inst{18-16} = imm;
10106   }
10108   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
10109                                   V64, V64, vecshiftR16,
10110                                   asm, ".4h", ".4h",
10111               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
10112                     (i32 vecshiftR16:$imm)))]> {
10113     bits<4> imm;
10114     let Inst{19-16} = imm;
10115   }
10117   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
10118                                   V128, V128, vecshiftR16,
10119                                   asm, ".8h", ".8h",
10120             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
10121                   (i32 vecshiftR16:$imm)))]> {
10122     bits<4> imm;
10123     let Inst{19-16} = imm;
10124   }
10126   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
10127                                   V64, V64, vecshiftR32,
10128                                   asm, ".2s", ".2s",
10129               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
10130                     (i32 vecshiftR32:$imm)))]> {
10131     bits<5> imm;
10132     let Inst{20-16} = imm;
10133   }
10135   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
10136                                   V128, V128, vecshiftR32,
10137                                   asm, ".4s", ".4s",
10138             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
10139                   (i32 vecshiftR32:$imm)))]> {
10140     bits<5> imm;
10141     let Inst{20-16} = imm;
10142   }
10144   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
10145                                   V128, V128, vecshiftR64,
10146                                   asm, ".2d", ".2d",
10147             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
10148                   (i32 vecshiftR64:$imm)))]> {
10149     bits<6> imm;
10150     let Inst{21-16} = imm;
10151   }
10154 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10155 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
10156                                     SDPatternOperator OpNode = null_frag> {
10157   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
10158                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
10159                  [(set (v8i8 V64:$dst),
10160                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
10161                            (i32 vecshiftR8:$imm)))]> {
10162     bits<3> imm;
10163     let Inst{18-16} = imm;
10164   }
10166   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
10167                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
10168              [(set (v16i8 V128:$dst),
10169                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
10170                        (i32 vecshiftR8:$imm)))]> {
10171     bits<3> imm;
10172     let Inst{18-16} = imm;
10173   }
10175   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
10176                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
10177               [(set (v4i16 V64:$dst),
10178                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
10179                         (i32 vecshiftR16:$imm)))]> {
10180     bits<4> imm;
10181     let Inst{19-16} = imm;
10182   }
10184   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
10185                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
10186             [(set (v8i16 V128:$dst),
10187               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
10188                       (i32 vecshiftR16:$imm)))]> {
10189     bits<4> imm;
10190     let Inst{19-16} = imm;
10191   }
10193   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
10194                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
10195               [(set (v2i32 V64:$dst),
10196                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
10197                         (i32 vecshiftR32:$imm)))]> {
10198     bits<5> imm;
10199     let Inst{20-16} = imm;
10200   }
10202   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
10203                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
10204             [(set (v4i32 V128:$dst),
10205               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
10206                       (i32 vecshiftR32:$imm)))]> {
10207     bits<5> imm;
10208     let Inst{20-16} = imm;
10209   }
10211   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
10212                                   V128, V128, vecshiftR64,
10213                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
10214               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
10215                       (i32 vecshiftR64:$imm)))]> {
10216     bits<6> imm;
10217     let Inst{21-16} = imm;
10218   }
10221 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
10222                                     SDPatternOperator OpNode = null_frag> {
10223   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
10224                                   V64, V64, vecshiftL8,
10225                                   asm, ".8b", ".8b",
10226                     [(set (v8i8 V64:$dst),
10227                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
10228                                   (i32 vecshiftL8:$imm)))]> {
10229     bits<3> imm;
10230     let Inst{18-16} = imm;
10231   }
10233   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
10234                                   V128, V128, vecshiftL8,
10235                                   asm, ".16b", ".16b",
10236                     [(set (v16i8 V128:$dst),
10237                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
10238                                   (i32 vecshiftL8:$imm)))]> {
10239     bits<3> imm;
10240     let Inst{18-16} = imm;
10241   }
10243   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
10244                                   V64, V64, vecshiftL16,
10245                                   asm, ".4h", ".4h",
10246                     [(set (v4i16 V64:$dst),
10247                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
10248                                    (i32 vecshiftL16:$imm)))]> {
10249     bits<4> imm;
10250     let Inst{19-16} = imm;
10251   }
10253   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
10254                                   V128, V128, vecshiftL16,
10255                                   asm, ".8h", ".8h",
10256                     [(set (v8i16 V128:$dst),
10257                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
10258                                   (i32 vecshiftL16:$imm)))]> {
10259     bits<4> imm;
10260     let Inst{19-16} = imm;
10261   }
10263   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
10264                                   V64, V64, vecshiftL32,
10265                                   asm, ".2s", ".2s",
10266                     [(set (v2i32 V64:$dst),
10267                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
10268                                   (i32 vecshiftL32:$imm)))]> {
10269     bits<5> imm;
10270     let Inst{20-16} = imm;
10271   }
10273   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
10274                                   V128, V128, vecshiftL32,
10275                                   asm, ".4s", ".4s",
10276                     [(set (v4i32 V128:$dst),
10277                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
10278                                   (i32 vecshiftL32:$imm)))]> {
10279     bits<5> imm;
10280     let Inst{20-16} = imm;
10281   }
10283   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
10284                                   V128, V128, vecshiftL64,
10285                                   asm, ".2d", ".2d",
10286                     [(set (v2i64 V128:$dst),
10287                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
10288                                   (i32 vecshiftL64:$imm)))]> {
10289     bits<6> imm;
10290     let Inst{21-16} = imm;
10291   }
10294 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
10295                                    SDPatternOperator OpNode> {
10296   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
10297                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
10298       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
10299     bits<3> imm;
10300     let Inst{18-16} = imm;
10301   }
10303   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
10304                                   V128, V128, vecshiftL8,
10305                                   asm#"2", ".8h", ".16b",
10306       [(set (v8i16 V128:$Rd),
10307             (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> {
10308     bits<3> imm;
10309     let Inst{18-16} = imm;
10310   }
10312   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
10313                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
10314       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
10315     bits<4> imm;
10316     let Inst{19-16} = imm;
10317   }
10319   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
10320                                   V128, V128, vecshiftL16,
10321                                   asm#"2", ".4s", ".8h",
10322       [(set (v4i32 V128:$Rd),
10323             (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> {
10325     bits<4> imm;
10326     let Inst{19-16} = imm;
10327   }
10329   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
10330                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
10331       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
10332     bits<5> imm;
10333     let Inst{20-16} = imm;
10334   }
10336   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
10337                                   V128, V128, vecshiftL32,
10338                                   asm#"2", ".2d", ".4s",
10339       [(set (v2i64 V128:$Rd),
10340             (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> {
10341     bits<5> imm;
10342     let Inst{20-16} = imm;
10343   }
10347 //---
10348 // Vector load/store
10349 //---
10350 // SIMD ldX/stX no-index memory references don't allow the optional
10351 // ", #0" constant and handle post-indexing explicitly, so we use
10352 // a more specialized parse method for them. Otherwise, it's the same as
10353 // the general GPR64sp handling.
10355 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
10356                    string asm, dag oops, dag iops, list<dag> pattern>
10357   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
10358   bits<5> Vt;
10359   bits<5> Rn;
10360   let Inst{31} = 0;
10361   let Inst{30} = Q;
10362   let Inst{29-23} = 0b0011000;
10363   let Inst{22} = L;
10364   let Inst{21-16} = 0b000000;
10365   let Inst{15-12} = opcode;
10366   let Inst{11-10} = size;
10367   let Inst{9-5} = Rn;
10368   let Inst{4-0} = Vt;
10371 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
10372                        string asm, dag oops, dag iops>
10373   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
10374   bits<5> Vt;
10375   bits<5> Rn;
10376   bits<5> Xm;
10377   let Inst{31} = 0;
10378   let Inst{30} = Q;
10379   let Inst{29-23} = 0b0011001;
10380   let Inst{22} = L;
10381   let Inst{21} = 0;
10382   let Inst{20-16} = Xm;
10383   let Inst{15-12} = opcode;
10384   let Inst{11-10} = size;
10385   let Inst{9-5} = Rn;
10386   let Inst{4-0} = Vt;
10389 // The immediate form of AdvSIMD post-indexed addressing is encoded with
10390 // register post-index addressing from the zero register.
10391 multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
10392                            int Offset, int Size> {
10393   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
10394   //      "ld1\t$Vt, [$Rn], #16"
10395   // may get mapped to
10396   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
10397   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
10398                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
10399                       GPR64sp:$Rn,
10400                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
10401                       XZR), 1>;
10403   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
10404   //      "ld1.8b\t$Vt, [$Rn], #16"
10405   // may get mapped to
10406   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
10407   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
10408                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
10409                       GPR64sp:$Rn,
10410                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10411                       XZR), 0>;
10413   // E.g. "ld1.8b { v0, v1 }, [x1]"
10414   //      "ld1\t$Vt, [$Rn]"
10415   // may get mapped to
10416   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
10417   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
10418                   (!cast<Instruction>(BaseName # Count # "v" # layout)
10419                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10420                       GPR64sp:$Rn), 0>;
10422   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
10423   //      "ld1\t$Vt, [$Rn], $Xm"
10424   // may get mapped to
10425   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
10426   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
10427                   (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
10428                       GPR64sp:$Rn,
10429                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10430                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
10433 multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
10434                        int Offset128, int Offset64, bits<4> opcode> {
10435   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
10436     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
10437                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
10438                            (ins GPR64sp:$Rn), []>;
10439     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
10440                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
10441                            (ins GPR64sp:$Rn), []>;
10442     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
10443                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
10444                            (ins GPR64sp:$Rn), []>;
10445     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
10446                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
10447                            (ins GPR64sp:$Rn), []>;
10448     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
10449                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
10450                            (ins GPR64sp:$Rn), []>;
10451     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
10452                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
10453                            (ins GPR64sp:$Rn), []>;
10454     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
10455                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
10456                            (ins GPR64sp:$Rn), []>;
10459     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
10460                        (outs GPR64sp:$wback,
10461                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
10462                        (ins GPR64sp:$Rn,
10463                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10464     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
10465                        (outs GPR64sp:$wback,
10466                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
10467                        (ins GPR64sp:$Rn,
10468                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10469     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
10470                        (outs GPR64sp:$wback,
10471                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
10472                        (ins GPR64sp:$Rn,
10473                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10474     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
10475                        (outs GPR64sp:$wback,
10476                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
10477                        (ins GPR64sp:$Rn,
10478                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10479     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
10480                        (outs GPR64sp:$wback,
10481                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
10482                        (ins GPR64sp:$Rn,
10483                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10484     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
10485                        (outs GPR64sp:$wback,
10486                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
10487                        (ins GPR64sp:$Rn,
10488                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10489     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
10490                        (outs GPR64sp:$wback,
10491                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
10492                        (ins GPR64sp:$Rn,
10493                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10494   }
10496   defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
10497   defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
10498   defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
10499   defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
10500   defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
10501   defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
10502   defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
10505 // Only ld1/st1 has a v1d version.
10506 multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
10507                        int Offset128, int Offset64, bits<4> opcode> {
10508   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
10509     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
10510                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
10511                                  GPR64sp:$Rn), []>;
10512     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
10513                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
10514                                 GPR64sp:$Rn), []>;
10515     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
10516                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
10517                                 GPR64sp:$Rn), []>;
10518     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
10519                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
10520                                 GPR64sp:$Rn), []>;
10521     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
10522                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
10523                                 GPR64sp:$Rn), []>;
10524     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
10525                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
10526                                 GPR64sp:$Rn), []>;
10527     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
10528                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
10529                                 GPR64sp:$Rn), []>;
10531     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
10532                        (outs GPR64sp:$wback),
10533                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
10534                             GPR64sp:$Rn,
10535                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10536     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
10537                        (outs GPR64sp:$wback),
10538                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
10539                             GPR64sp:$Rn,
10540                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10541     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
10542                        (outs GPR64sp:$wback),
10543                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
10544                             GPR64sp:$Rn,
10545                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10546     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
10547                        (outs GPR64sp:$wback),
10548                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
10549                             GPR64sp:$Rn,
10550                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
10551     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
10552                        (outs GPR64sp:$wback),
10553                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
10554                             GPR64sp:$Rn,
10555                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10556     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
10557                        (outs GPR64sp:$wback),
10558                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
10559                             GPR64sp:$Rn,
10560                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10561     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
10562                        (outs GPR64sp:$wback),
10563                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
10564                             GPR64sp:$Rn,
10565                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10566   }
10568   defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
10569   defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
10570   defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
10571   defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
10572   defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
10573   defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
10574   defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
10577 multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
10578                        int Offset128, int Offset64, bits<4> opcode>
10579   : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
10581   // LD1 instructions have extra "1d" variants.
10582   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
10583     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
10584                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
10585                            (ins GPR64sp:$Rn), []>;
10587     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
10588                        (outs GPR64sp:$wback,
10589                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
10590                        (ins GPR64sp:$Rn,
10591                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10592   }
10594   defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
10597 multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
10598                        int Offset128, int Offset64, bits<4> opcode>
10599   : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
10601   // ST1 instructions have extra "1d" variants.
10602   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
10603     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
10604                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
10605                                 GPR64sp:$Rn), []>;
10607     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
10608                        (outs GPR64sp:$wback),
10609                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
10610                             GPR64sp:$Rn,
10611                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
10612   }
10614   defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
10617 multiclass SIMDLd1Multiple<string asm> {
10618   defm One   : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8,  0b0111>;
10619   defm Two   : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
10620   defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
10621   defm Four  : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
10624 multiclass SIMDSt1Multiple<string asm> {
10625   defm One   : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8,  0b0111>;
10626   defm Two   : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
10627   defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
10628   defm Four  : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
10631 multiclass SIMDLd2Multiple<string asm> {
10632   defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
10635 multiclass SIMDSt2Multiple<string asm> {
10636   defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
10639 multiclass SIMDLd3Multiple<string asm> {
10640   defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
10643 multiclass SIMDSt3Multiple<string asm> {
10644   defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
10647 multiclass SIMDLd4Multiple<string asm> {
10648   defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
10651 multiclass SIMDSt4Multiple<string asm> {
10652   defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
10655 //---
10656 // AdvSIMD Load/store single-element
10657 //---
10659 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
10660                          string asm, string operands, string cst,
10661                          dag oops, dag iops, list<dag> pattern>
10662   : I<oops, iops, asm, operands, cst, pattern> {
10663   bits<5> Vt;
10664   bits<5> Rn;
10665   let Inst{31} = 0;
10666   let Inst{29-24} = 0b001101;
10667   let Inst{22} = L;
10668   let Inst{21} = R;
10669   let Inst{15-13} = opcode;
10670   let Inst{9-5} = Rn;
10671   let Inst{4-0} = Vt;
10674 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
10675                          string asm, string operands, string cst,
10676                          dag oops, dag iops, list<dag> pattern>
10677   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
10678   bits<5> Vt;
10679   bits<5> Rn;
10680   let Inst{31} = 0;
10681   let Inst{29-24} = 0b001101;
10682   let Inst{22} = L;
10683   let Inst{21} = R;
10684   let Inst{15-13} = opcode;
10685   let Inst{9-5} = Rn;
10686   let Inst{4-0} = Vt;
10690 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10691 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
10692                   DAGOperand listtype>
10693   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
10694                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
10695                        []> {
10696   let Inst{30} = Q;
10697   let Inst{23} = 0;
10698   let Inst{20-16} = 0b00000;
10699   let Inst{12} = S;
10700   let Inst{11-10} = size;
10702 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10703 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
10704                       string asm, DAGOperand listtype, DAGOperand GPR64pi>
10705   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
10706                        "$Rn = $wback",
10707                        (outs GPR64sp:$wback, listtype:$Vt),
10708                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
10709   bits<5> Xm;
10710   let Inst{30} = Q;
10711   let Inst{23} = 1;
10712   let Inst{20-16} = Xm;
10713   let Inst{12} = S;
10714   let Inst{11-10} = size;
10717 multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
10718                           int Offset, int Size> {
10719   // E.g. "ld1r { v0.8b }, [x1], #1"
10720   //      "ld1r.8b\t$Vt, [$Rn], #1"
10721   // may get mapped to
10722   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
10723   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
10724                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
10725                       GPR64sp:$Rn,
10726                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
10727                       XZR), 1>;
10729   // E.g. "ld1r.8b { v0 }, [x1], #1"
10730   //      "ld1r.8b\t$Vt, [$Rn], #1"
10731   // may get mapped to
10732   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
10733   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
10734                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
10735                       GPR64sp:$Rn,
10736                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10737                       XZR), 0>;
10739   // E.g. "ld1r.8b { v0 }, [x1]"
10740   //      "ld1r.8b\t$Vt, [$Rn]"
10741   // may get mapped to
10742   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
10743   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
10744                   (!cast<Instruction>(BaseName # "v" # layout)
10745                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10746                       GPR64sp:$Rn), 0>;
10748   // E.g. "ld1r.8b { v0 }, [x1], x2"
10749   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
10750   // may get mapped to
10751   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
10752   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
10753                   (!cast<Instruction>(BaseName # "v" # layout # "_POST")
10754                       GPR64sp:$Rn,
10755                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10756                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
10759 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
10760   int Offset1, int Offset2, int Offset4, int Offset8> {
10761   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
10762                         !cast<DAGOperand>("VecList" # Count # "8b")>;
10763   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
10764                         !cast<DAGOperand>("VecList" # Count #"16b")>;
10765   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
10766                         !cast<DAGOperand>("VecList" # Count #"4h")>;
10767   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
10768                         !cast<DAGOperand>("VecList" # Count #"8h")>;
10769   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
10770                         !cast<DAGOperand>("VecList" # Count #"2s")>;
10771   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
10772                         !cast<DAGOperand>("VecList" # Count #"4s")>;
10773   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
10774                         !cast<DAGOperand>("VecList" # Count #"1d")>;
10775   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
10776                         !cast<DAGOperand>("VecList" # Count #"2d")>;
10778   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
10779                                  !cast<DAGOperand>("VecList" # Count # "8b"),
10780                                  !cast<DAGOperand>("GPR64pi" # Offset1)>;
10781   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
10782                                  !cast<DAGOperand>("VecList" # Count # "16b"),
10783                                  !cast<DAGOperand>("GPR64pi" # Offset1)>;
10784   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
10785                                  !cast<DAGOperand>("VecList" # Count # "4h"),
10786                                  !cast<DAGOperand>("GPR64pi" # Offset2)>;
10787   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
10788                                  !cast<DAGOperand>("VecList" # Count # "8h"),
10789                                  !cast<DAGOperand>("GPR64pi" # Offset2)>;
10790   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
10791                                  !cast<DAGOperand>("VecList" # Count # "2s"),
10792                                  !cast<DAGOperand>("GPR64pi" # Offset4)>;
10793   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
10794                                  !cast<DAGOperand>("VecList" # Count # "4s"),
10795                                  !cast<DAGOperand>("GPR64pi" # Offset4)>;
10796   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
10797                                  !cast<DAGOperand>("VecList" # Count # "1d"),
10798                                  !cast<DAGOperand>("GPR64pi" # Offset8)>;
10799   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
10800                                  !cast<DAGOperand>("VecList" # Count # "2d"),
10801                                  !cast<DAGOperand>("GPR64pi" # Offset8)>;
10803   defm : SIMDLdrAliases<NAME, asm, "8b",  Count, Offset1,  64>;
10804   defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
10805   defm : SIMDLdrAliases<NAME, asm, "4h",  Count, Offset2,  64>;
10806   defm : SIMDLdrAliases<NAME, asm, "8h",  Count, Offset2, 128>;
10807   defm : SIMDLdrAliases<NAME, asm, "2s",  Count, Offset4,  64>;
10808   defm : SIMDLdrAliases<NAME, asm, "4s",  Count, Offset4, 128>;
10809   defm : SIMDLdrAliases<NAME, asm, "1d",  Count, Offset8,  64>;
10810   defm : SIMDLdrAliases<NAME, asm, "2d",  Count, Offset8, 128>;
10813 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
10814                       dag oops, dag iops, list<dag> pattern>
10815   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10816                        pattern> {
10817   // idx encoded in Q:S:size fields.
10818   bits<4> idx;
10819   let Inst{30} = idx{3};
10820   let Inst{23} = 0;
10821   let Inst{20-16} = 0b00000;
10822   let Inst{12} = idx{2};
10823   let Inst{11-10} = idx{1-0};
10825 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
10826                       dag oops, dag iops, list<dag> pattern>
10827   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10828                            oops, iops, pattern> {
10829   // idx encoded in Q:S:size fields.
10830   bits<4> idx;
10831   let Inst{30} = idx{3};
10832   let Inst{23} = 0;
10833   let Inst{20-16} = 0b00000;
10834   let Inst{12} = idx{2};
10835   let Inst{11-10} = idx{1-0};
10837 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
10838                           dag oops, dag iops>
10839   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10840                        "$Rn = $wback", oops, iops, []> {
10841   // idx encoded in Q:S:size fields.
10842   bits<4> idx;
10843   bits<5> Xm;
10844   let Inst{30} = idx{3};
10845   let Inst{23} = 1;
10846   let Inst{20-16} = Xm;
10847   let Inst{12} = idx{2};
10848   let Inst{11-10} = idx{1-0};
10850 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
10851                           dag oops, dag iops>
10852   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10853                            "$Rn = $wback", oops, iops, []> {
10854   // idx encoded in Q:S:size fields.
10855   bits<4> idx;
10856   bits<5> Xm;
10857   let Inst{30} = idx{3};
10858   let Inst{23} = 1;
10859   let Inst{20-16} = Xm;
10860   let Inst{12} = idx{2};
10861   let Inst{11-10} = idx{1-0};
10864 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
10865                       dag oops, dag iops, list<dag> pattern>
10866   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10867                        pattern> {
10868   // idx encoded in Q:S:size<1> fields.
10869   bits<3> idx;
10870   let Inst{30} = idx{2};
10871   let Inst{23} = 0;
10872   let Inst{20-16} = 0b00000;
10873   let Inst{12} = idx{1};
10874   let Inst{11} = idx{0};
10875   let Inst{10} = size;
10877 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
10878                       dag oops, dag iops, list<dag> pattern>
10879   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10880                            oops, iops, pattern> {
10881   // idx encoded in Q:S:size<1> fields.
10882   bits<3> idx;
10883   let Inst{30} = idx{2};
10884   let Inst{23} = 0;
10885   let Inst{20-16} = 0b00000;
10886   let Inst{12} = idx{1};
10887   let Inst{11} = idx{0};
10888   let Inst{10} = size;
10891 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10892                           dag oops, dag iops>
10893   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10894                        "$Rn = $wback", oops, iops, []> {
10895   // idx encoded in Q:S:size<1> fields.
10896   bits<3> idx;
10897   bits<5> Xm;
10898   let Inst{30} = idx{2};
10899   let Inst{23} = 1;
10900   let Inst{20-16} = Xm;
10901   let Inst{12} = idx{1};
10902   let Inst{11} = idx{0};
10903   let Inst{10} = size;
10905 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10906                           dag oops, dag iops>
10907   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10908                            "$Rn = $wback", oops, iops, []> {
10909   // idx encoded in Q:S:size<1> fields.
10910   bits<3> idx;
10911   bits<5> Xm;
10912   let Inst{30} = idx{2};
10913   let Inst{23} = 1;
10914   let Inst{20-16} = Xm;
10915   let Inst{12} = idx{1};
10916   let Inst{11} = idx{0};
10917   let Inst{10} = size;
10919 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10920                       dag oops, dag iops, list<dag> pattern>
10921   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10922                        pattern> {
10923   // idx encoded in Q:S fields.
10924   bits<2> idx;
10925   let Inst{30} = idx{1};
10926   let Inst{23} = 0;
10927   let Inst{20-16} = 0b00000;
10928   let Inst{12} = idx{0};
10929   let Inst{11-10} = size;
10931 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10932                       dag oops, dag iops, list<dag> pattern>
10933   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10934                            oops, iops, pattern> {
10935   // idx encoded in Q:S fields.
10936   bits<2> idx;
10937   let Inst{30} = idx{1};
10938   let Inst{23} = 0;
10939   let Inst{20-16} = 0b00000;
10940   let Inst{12} = idx{0};
10941   let Inst{11-10} = size;
10943 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
10944                           string asm, dag oops, dag iops>
10945   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10946                        "$Rn = $wback", oops, iops, []> {
10947   // idx encoded in Q:S fields.
10948   bits<2> idx;
10949   bits<5> Xm;
10950   let Inst{30} = idx{1};
10951   let Inst{23} = 1;
10952   let Inst{20-16} = Xm;
10953   let Inst{12} = idx{0};
10954   let Inst{11-10} = size;
10956 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
10957                           string asm, dag oops, dag iops>
10958   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10959                            "$Rn = $wback", oops, iops, []> {
10960   // idx encoded in Q:S fields.
10961   bits<2> idx;
10962   bits<5> Xm;
10963   let Inst{30} = idx{1};
10964   let Inst{23} = 1;
10965   let Inst{20-16} = Xm;
10966   let Inst{12} = idx{0};
10967   let Inst{11-10} = size;
10969 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10970                       dag oops, dag iops, list<dag> pattern>
10971   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10972                        pattern> {
10973   // idx encoded in Q field.
10974   bits<1> idx;
10975   let Inst{30} = idx;
10976   let Inst{23} = 0;
10977   let Inst{20-16} = 0b00000;
10978   let Inst{12} = 0;
10979   let Inst{11-10} = size;
10981 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10982                       dag oops, dag iops, list<dag> pattern>
10983   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10984                            oops, iops, pattern> {
10985   // idx encoded in Q field.
10986   bits<1> idx;
10987   let Inst{30} = idx;
10988   let Inst{23} = 0;
10989   let Inst{20-16} = 0b00000;
10990   let Inst{12} = 0;
10991   let Inst{11-10} = size;
10993 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
10994                           string asm, dag oops, dag iops>
10995   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10996                        "$Rn = $wback", oops, iops, []> {
10997   // idx encoded in Q field.
10998   bits<1> idx;
10999   bits<5> Xm;
11000   let Inst{30} = idx;
11001   let Inst{23} = 1;
11002   let Inst{20-16} = Xm;
11003   let Inst{12} = 0;
11004   let Inst{11-10} = size;
11006 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
11007                           string asm, dag oops, dag iops>
11008   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
11009                            "$Rn = $wback", oops, iops, []> {
11010   // idx encoded in Q field.
11011   bits<1> idx;
11012   bits<5> Xm;
11013   let Inst{30} = idx;
11014   let Inst{23} = 1;
11015   let Inst{20-16} = Xm;
11016   let Inst{12} = 0;
11017   let Inst{11-10} = size;
11020 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
11021 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
11022                          RegisterOperand listtype,
11023                          RegisterOperand GPR64pi> {
11024   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
11025                            (outs listtype:$dst),
11026                            (ins listtype:$Vt, VectorIndexB:$idx,
11027                                 GPR64sp:$Rn), []>;
11029   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
11030                             (outs GPR64sp:$wback, listtype:$dst),
11031                             (ins listtype:$Vt, VectorIndexB:$idx,
11032                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
11034 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
11035 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
11036                          RegisterOperand listtype,
11037                          RegisterOperand GPR64pi> {
11038   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
11039                             (outs listtype:$dst),
11040                             (ins listtype:$Vt, VectorIndexH:$idx,
11041                                  GPR64sp:$Rn), []>;
11043   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
11044                             (outs GPR64sp:$wback, listtype:$dst),
11045                             (ins listtype:$Vt, VectorIndexH:$idx,
11046                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
11048 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
11049 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
11050                          RegisterOperand listtype,
11051                          RegisterOperand GPR64pi> {
11052   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
11053                             (outs listtype:$dst),
11054                             (ins listtype:$Vt, VectorIndexS:$idx,
11055                                  GPR64sp:$Rn), []>;
11057   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
11058                             (outs GPR64sp:$wback, listtype:$dst),
11059                             (ins listtype:$Vt, VectorIndexS:$idx,
11060                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
11062 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
11063 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
11064                          RegisterOperand listtype, RegisterOperand GPR64pi> {
11065   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
11066                             (outs listtype:$dst),
11067                             (ins listtype:$Vt, VectorIndexD:$idx,
11068                                  GPR64sp:$Rn), []>;
11070   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
11071                             (outs GPR64sp:$wback, listtype:$dst),
11072                             (ins listtype:$Vt, VectorIndexD:$idx,
11073                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
11075 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
11076 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
11077                          RegisterOperand listtype, RegisterOperand GPR64pi> {
11078   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
11079                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
11080                                         GPR64sp:$Rn), []>;
11082   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
11083                                     (outs GPR64sp:$wback),
11084                                     (ins listtype:$Vt, VectorIndexB:$idx,
11085                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
11087 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
11088 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
11089                          RegisterOperand listtype, RegisterOperand GPR64pi> {
11090   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
11091                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
11092                                          GPR64sp:$Rn), []>;
11094   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
11095                             (outs GPR64sp:$wback),
11096                             (ins listtype:$Vt, VectorIndexH:$idx,
11097                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
11099 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
11100 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
11101                          RegisterOperand listtype, RegisterOperand GPR64pi> {
11102   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
11103                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
11104                                          GPR64sp:$Rn), []>;
11106   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
11107                             (outs GPR64sp:$wback),
11108                             (ins listtype:$Vt, VectorIndexS:$idx,
11109                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
11111 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
11112 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
11113                          RegisterOperand listtype, RegisterOperand GPR64pi> {
11114   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
11115                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
11116                                          GPR64sp:$Rn), []>;
11118   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
11119                             (outs GPR64sp:$wback),
11120                             (ins listtype:$Vt, VectorIndexD:$idx,
11121                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
11124 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
11125                                  string Count, int Offset, Operand idxtype> {
11126   // E.g. "ld1 { v0.8b }[0], [x1], #1"
11127   //      "ld1\t$Vt, [$Rn], #1"
11128   // may get mapped to
11129   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
11130   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
11131                   (!cast<Instruction>(NAME # Type  # "_POST")
11132                       GPR64sp:$Rn,
11133                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
11134                       idxtype:$idx, XZR), 1>;
11136   // E.g. "ld1.8b { v0 }[0], [x1], #1"
11137   //      "ld1.8b\t$Vt, [$Rn], #1"
11138   // may get mapped to
11139   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
11140   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
11141                   (!cast<Instruction>(NAME # Type # "_POST")
11142                       GPR64sp:$Rn,
11143                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
11144                       idxtype:$idx, XZR), 0>;
11146   // E.g. "ld1.8b { v0 }[0], [x1]"
11147   //      "ld1.8b\t$Vt, [$Rn]"
11148   // may get mapped to
11149   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
11150   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
11151                       (!cast<Instruction>(NAME # Type)
11152                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
11153                          idxtype:$idx, GPR64sp:$Rn), 0>;
11155   // E.g. "ld1.8b { v0 }[0], [x1], x2"
11156   //      "ld1.8b\t$Vt, [$Rn], $Xm"
11157   // may get mapped to
11158   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
11159   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
11160                       (!cast<Instruction>(NAME # Type # "_POST")
11161                          GPR64sp:$Rn,
11162                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
11163                          idxtype:$idx,
11164                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
11167 multiclass SIMDLdSt1SingleAliases<string asm> {
11168   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
11169   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
11170   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
11171   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
11174 multiclass SIMDLdSt2SingleAliases<string asm> {
11175   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
11176   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
11177   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
11178   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
11181 multiclass SIMDLdSt3SingleAliases<string asm> {
11182   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
11183   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
11184   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
11185   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
11188 multiclass SIMDLdSt4SingleAliases<string asm> {
11189   defm "" : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
11190   defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
11191   defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
11192   defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
11194 } // end of 'let Predicates = [HasNEON]'
11196 //----------------------------------------------------------------------------
11197 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
11198 //----------------------------------------------------------------------------
11200 let Predicates = [HasNEON, HasRDM] in {
11202 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
11203                                     RegisterOperand regtype, string asm,
11204                                     string kind, list<dag> pattern>
11205   : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
11206                                 pattern> {
11208 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
11209                                              SDPatternOperator op> {
11210   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
11211     [(set (v4i16 V64:$dst),
11212           (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
11213   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
11214     [(set (v8i16 V128:$dst),
11215           (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
11216   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
11217     [(set (v2i32 V64:$dst),
11218           (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
11219   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
11220     [(set (v4i32 V128:$dst),
11221           (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
11224 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
11225                                      SDPatternOperator op> {
11226   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
11227                                           V64, V64, V128_lo, VectorIndexH,
11228                                           asm, ".4h", ".4h", ".4h", ".h",
11229     [(set (v4i16 V64:$dst),
11230           (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn),
11231                      (dup_v8i16 (v8i16 V128_lo:$Rm),
11232                                  VectorIndexH:$idx))))]> {
11233     bits<3> idx;
11234     let Inst{11} = idx{2};
11235     let Inst{21} = idx{1};
11236     let Inst{20} = idx{0};
11237   }
11239   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
11240                                           V128, V128, V128_lo, VectorIndexH,
11241                                           asm, ".8h", ".8h", ".8h", ".h",
11242     [(set (v8i16 V128:$dst),
11243           (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn),
11244                      (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
11245                                               VectorIndexH:$idx)))))]> {
11246     bits<3> idx;
11247     let Inst{11} = idx{2};
11248     let Inst{21} = idx{1};
11249     let Inst{20} = idx{0};
11250   }
11252   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
11253                                           V64, V64, V128, VectorIndexS,
11254                                           asm, ".2s", ".2s", ".2s", ".s",
11255     [(set (v2i32 V64:$dst),
11256           (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn),
11257                      (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
11258     bits<2> idx;
11259     let Inst{11} = idx{1};
11260     let Inst{21} = idx{0};
11261   }
11263   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
11264                                           V128, V128, V128, VectorIndexS,
11265                                           asm, ".4s", ".4s", ".4s", ".s",
11266     [(set (v4i32 V128:$dst),
11267           (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn),
11268                      (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
11269                                               VectorIndexS:$idx)))))]> {
11270     bits<2> idx;
11271     let Inst{11} = idx{1};
11272     let Inst{21} = idx{0};
11273   }
11275   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
11276                                           FPR16Op, FPR16Op, V128_lo,
11277                                           VectorIndexH, asm, ".h", "", "", ".h",
11278                                           []> {
11279     bits<3> idx;
11280     let Inst{11} = idx{2};
11281     let Inst{21} = idx{1};
11282     let Inst{20} = idx{0};
11283   }
11285   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
11286                                           FPR32Op, FPR32Op, V128, VectorIndexS,
11287                                           asm, ".s", "", "", ".s",
11288     [(set (i32 FPR32Op:$dst),
11289           (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn),
11290                    (i32 (vector_extract (v4i32 V128:$Rm),
11291                                         VectorIndexS:$idx)))))]> {
11292     bits<2> idx;
11293     let Inst{11} = idx{1};
11294     let Inst{21} = idx{0};
11295   }
11297 } // let Predicates = [HasNeon, HasRDM]
11299 //----------------------------------------------------------------------------
11300 // ARMv8.3 Complex ADD/MLA instructions
11301 //----------------------------------------------------------------------------
11303 class ComplexRotationOperand<int Angle, int Remainder, string Type>
11304   : AsmOperandClass {
11305   let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
11306   let DiagnosticType = "InvalidComplexRotation" # Type;
11307   let Name = "ComplexRotation" # Type;
11309 def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270;  }],
11310                                                   SDNodeXForm<imm, [{
11311   return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32);
11312 }]>> {
11313   let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
11314   let PrintMethod = "printComplexRotationOp<90, 0>";
11316 def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270;  }],
11317                                                   SDNodeXForm<imm, [{
11318   return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32);
11319 }]>> {
11320   let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
11321   let PrintMethod = "printComplexRotationOp<180, 90>";
11323 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
11324 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
11325                                      RegisterOperand regtype, Operand rottype,
11326                                      string asm, string kind, list<dag> pattern>
11327   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
11328       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
11329       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
11330     Sched<[!if(Q, WriteVq, WriteVd)]> {
11331   bits<5> Rd;
11332   bits<5> Rn;
11333   bits<5> Rm;
11334   bits<1> rot;
11335   let Inst{31}    = 0;
11336   let Inst{30}    = Q;
11337   let Inst{29}    = U;
11338   let Inst{28-24} = 0b01110;
11339   let Inst{23-22} = size;
11340   let Inst{21}    = 0;
11341   let Inst{20-16} = Rm;
11342   let Inst{15-13} = opcode;
11343   // Non-tied version (FCADD) only has one rotation bit
11344   let Inst{12}    = rot;
11345   let Inst{11}    = 0;
11346   let Inst{10}    = 1;
11347   let Inst{9-5}   = Rn;
11348   let Inst{4-0}   = Rd;
11351 //8.3 CompNum - Floating-point complex number support
11352 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
11353                                           string asm, SDPatternOperator OpNode>{
11354   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
11355   def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
11356               asm, ".4h",
11357               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
11358                                               (v4f16 V64:$Rn),
11359                                               (v4f16 V64:$Rm),
11360                                               (i32 rottype:$rot)))]>;
11362   def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
11363               asm, ".8h",
11364               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
11365                                                (v8f16 V128:$Rn),
11366                                                (v8f16 V128:$Rm),
11367                                                (i32 rottype:$rot)))]>;
11368   }
11370   let Predicates = [HasComplxNum, HasNEON] in {
11371   def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
11372               asm, ".2s",
11373               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
11374                                               (v2f32 V64:$Rn),
11375                                               (v2f32 V64:$Rm),
11376                                               (i32 rottype:$rot)))]>;
11378   def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
11379               asm, ".4s",
11380               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
11381                                                (v4f32 V128:$Rn),
11382                                                (v4f32 V128:$Rm),
11383                                                (i32 rottype:$rot)))]>;
11385   def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
11386               asm, ".2d",
11387               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
11388                                                (v2f64 V128:$Rn),
11389                                                (v2f64 V128:$Rm),
11390                                                (i32 rottype:$rot)))]>;
11391   }
11394 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
11395 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
11396                                          bits<3> opcode,
11397                                          RegisterOperand regtype,
11398                                          Operand rottype, string asm,
11399                                          string kind, list<dag> pattern>
11400   : I<(outs regtype:$dst),
11401       (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
11402       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
11403       "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
11404     Sched<[!if(Q, WriteVq, WriteVd)]> {
11405   bits<5> Rd;
11406   bits<5> Rn;
11407   bits<5> Rm;
11408   bits<2> rot;
11409   let Inst{31}    = 0;
11410   let Inst{30}    = Q;
11411   let Inst{29}    = U;
11412   let Inst{28-24} = 0b01110;
11413   let Inst{23-22} = size;
11414   let Inst{21}    = 0;
11415   let Inst{20-16} = Rm;
11416   let Inst{15-13} = opcode;
11417   let Inst{12-11} = rot;
11418   let Inst{10}    = 1;
11419   let Inst{9-5}   = Rn;
11420   let Inst{4-0}   = Rd;
11423 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
11424                                              Operand rottype, string asm,
11425                                              SDPatternOperator OpNode> {
11426   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
11427   def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
11428               rottype, asm, ".4h",
11429               [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
11430                                               (v4f16 V64:$Rn),
11431                                               (v4f16 V64:$Rm),
11432                                               (i32 rottype:$rot)))]>;
11434   def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
11435               rottype, asm, ".8h",
11436               [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
11437                                                (v8f16 V128:$Rn),
11438                                                (v8f16 V128:$Rm),
11439                                                (i32 rottype:$rot)))]>;
11440   }
11442   let Predicates = [HasComplxNum, HasNEON] in {
11443   def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
11444               rottype, asm, ".2s",
11445               [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
11446                                               (v2f32 V64:$Rn),
11447                                               (v2f32 V64:$Rm),
11448                                               (i32 rottype:$rot)))]>;
11450   def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
11451               rottype, asm, ".4s",
11452               [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
11453                                                (v4f32 V128:$Rn),
11454                                                (v4f32 V128:$Rm),
11455                                                (i32 rottype:$rot)))]>;
11457   def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
11458               rottype, asm, ".2d",
11459               [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
11460                                                (v2f64 V128:$Rn),
11461                                                (v2f64 V128:$Rm),
11462                                                (i32 rottype:$rot)))]>;
11463   }
11466 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
11467 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
11468                                  bit opc1, bit opc2, RegisterOperand dst_reg,
11469                                  RegisterOperand lhs_reg,
11470                                  RegisterOperand rhs_reg, Operand vec_idx,
11471                                  Operand rottype, string asm, string apple_kind,
11472                                  string dst_kind, string lhs_kind,
11473                                  string rhs_kind, list<dag> pattern>
11474   : I<(outs dst_reg:$dst),
11475       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
11476       asm,
11477       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
11478       "$idx, $rot" # "|" # apple_kind #
11479       "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
11480     Sched<[!if(Q, WriteVq, WriteVd)]> {
11481   bits<5> Rd;
11482   bits<5> Rn;
11483   bits<5> Rm;
11484   bits<2> rot;
11486   let Inst{31}    = 0;
11487   let Inst{30}    = Q;
11488   let Inst{29}    = U;
11489   let Inst{28}    = Scalar;
11490   let Inst{27-24} = 0b1111;
11491   let Inst{23-22} = size;
11492   // Bit 21 must be set by the derived class.
11493   let Inst{20-16} = Rm;
11494   let Inst{15}    = opc1;
11495   let Inst{14-13} = rot;
11496   let Inst{12}    = opc2;
11497   // Bit 11 must be set by the derived class.
11498   let Inst{10}    = 0;
11499   let Inst{9-5}   = Rn;
11500   let Inst{4-0}   = Rd;
11503 // The complex instructions index by pairs of elements, so the VectorIndexes
11504 // don't match the lane types, and the index bits are different to the other
11505 // classes.
11506 multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype,
11507                                      string asm> {
11508   let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
11509   def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
11510                       V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
11511                       ".4h", ".h", []> {
11512     bits<1> idx;
11513     let Inst{11} = 0;
11514     let Inst{21} = idx{0};
11515   }
11517   def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
11518                       V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
11519                       ".8h", ".8h", ".h", []> {
11520     bits<2> idx;
11521     let Inst{11} = idx{1};
11522     let Inst{21} = idx{0};
11523   }
11524   } // Predicates = HasComplxNum, HasNEON, HasFullFP16]
11526   let Predicates = [HasComplxNum, HasNEON] in {
11527   def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
11528                       V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
11529                       ".4s", ".4s", ".s", []> {
11530     bits<1> idx;
11531     let Inst{11} = idx{0};
11532     let Inst{21} = 0;
11533   }
11534   } // Predicates = [HasComplxNum, HasNEON]
11537 //----------------------------------------------------------------------------
11538 // Crypto extensions
11539 //----------------------------------------------------------------------------
11541 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
11542 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
11543               list<dag> pat>
11544   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
11545     Sched<[WriteVq]>{
11546   bits<5> Rd;
11547   bits<5> Rn;
11548   let Inst{31-16} = 0b0100111000101000;
11549   let Inst{15-12} = opc;
11550   let Inst{11-10} = 0b10;
11551   let Inst{9-5}   = Rn;
11552   let Inst{4-0}   = Rd;
11555 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
11556   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
11557             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
11559 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
11560   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
11561             "$Rd = $dst",
11562             [(set (v16i8 V128:$dst),
11563                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
11565 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
11566 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
11567                      dag oops, dag iops, list<dag> pat>
11568   : I<oops, iops, asm,
11569       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
11570       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
11571     Sched<[WriteVq]>{
11572   bits<5> Rd;
11573   bits<5> Rn;
11574   bits<5> Rm;
11575   let Inst{31-21} = 0b01011110000;
11576   let Inst{20-16} = Rm;
11577   let Inst{15}    = 0;
11578   let Inst{14-12} = opc;
11579   let Inst{11-10} = 0b00;
11580   let Inst{9-5}   = Rn;
11581   let Inst{4-0}   = Rd;
11584 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
11585   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
11586                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
11587                    [(set (v4i32 FPR128:$dst),
11588                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
11589                                  (v4i32 V128:$Rm)))]>;
11591 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
11592   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
11593                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
11594                    [(set (v4i32 V128:$dst),
11595                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
11596                                  (v4i32 V128:$Rm)))]>;
11598 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
11599   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
11600                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
11601                    [(set (v4i32 FPR128:$dst),
11602                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
11603                                  (v4i32 V128:$Rm)))]>;
11605 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
11606 class SHA2OpInst<bits<4> opc, string asm, string kind,
11607                  string cstr, dag oops, dag iops,
11608                  list<dag> pat>
11609   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
11610                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
11611     Sched<[WriteVq]>{
11612   bits<5> Rd;
11613   bits<5> Rn;
11614   let Inst{31-16} = 0b0101111000101000;
11615   let Inst{15-12} = opc;
11616   let Inst{11-10} = 0b10;
11617   let Inst{9-5}   = Rn;
11618   let Inst{4-0}   = Rd;
11621 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
11622   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
11623                (ins V128:$Rd, V128:$Rn),
11624                [(set (v4i32 V128:$dst),
11625                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
11627 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
11628   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
11629                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
11631 // Armv8.2-A Crypto extensions
11632 class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
11633                     list<dag> pattern>
11634   : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> {
11635   bits<5> Vd;
11636   bits<5> Vn;
11637   let Inst{31-25} = 0b1100111;
11638   let Inst{9-5}   = Vn;
11639   let Inst{4-0}   = Vd;
11642 class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
11643   : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops,
11644                   "$Vd = $Vdst", []> {
11645   let Inst{31-25} = 0b1100111;
11646   let Inst{24-21} = 0b0110;
11647   let Inst{20-15} = 0b000001;
11648   let Inst{14}    = op0;
11649   let Inst{13-12} = 0b00;
11650   let Inst{11-10} = op1;
11652 class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
11653   : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">;
11654 class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
11655   : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">;
11657 class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
11658                 string asmops, string cst>
11659   : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
11660   bits<5> Vm;
11661   let Inst{24-21} = 0b0011;
11662   let Inst{20-16} = Vm;
11663   let Inst{15}    = 0b1;
11664   let Inst{14}    = op0;
11665   let Inst{13-12} = 0b00;
11666   let Inst{11-10} = op1;
11668 class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
11669   : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
11670               "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">;
11671 class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
11672   : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
11673               "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
11674 class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
11675   : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
11676               "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">;
11677 class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
11678   : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
11679               "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
11680 class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
11681   : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
11682               asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
11684 class CryptoRRRR<bits<2>op0, string asm, string asmops>
11685   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
11686                   asmops, "", []> {
11687   bits<5> Vm;
11688   bits<5> Va;
11689   let Inst{24-23} = 0b00;
11690   let Inst{22-21} = op0;
11691   let Inst{20-16} = Vm;
11692   let Inst{15}    = 0b0;
11693   let Inst{14-10} = Va;
11695 class CryptoRRRR_16B<bits<2>op0, string asm>
11696  : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" #
11697                         "|.16b\t$Vd, $Vn, $Vm, $Va}"> {
11699 class CryptoRRRR_4S<bits<2>op0, string asm>
11700  : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" #
11701                          "|.4s\t$Vd, $Vn, $Vm, $Va}"> {
11704 class CryptoRRRi6<string asm>
11705   : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
11706                   "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" #
11707                   "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> {
11708   bits<6> imm;
11709   bits<5> Vm;
11710   let Inst{24-21} = 0b0100;
11711   let Inst{20-16} = Vm;
11712   let Inst{15-10} = imm;
11713   let Inst{9-5}   = Vn;
11714   let Inst{4-0}   = Vd;
11717 class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
11718   : BaseCryptoV82<(outs V128:$Vdst),
11719                   (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
11720                   asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" #
11721                        "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> {
11722   bits<2> imm;
11723   bits<5> Vm;
11724   let Inst{24-21} = 0b0010;
11725   let Inst{20-16} = Vm;
11726   let Inst{15}    = 0b1;
11727   let Inst{14}    = op0;
11728   let Inst{13-12} = imm;
11729   let Inst{11-10} = op1;
11732 //----------------------------------------------------------------------------
11733 // v8.1 atomic instructions extension:
11734 // * CAS
11735 // * CASP
11736 // * SWP
11737 // * LDOPregister<OP>, and aliases STOPregister<OP>
11739 // Instruction encodings:
11741 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
11742 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
11743 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
11744 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
11745 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
11746 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
11748 // Instruction syntax:
11750 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
11751 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
11752 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
11753 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
11754 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
11755 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
11756 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
11757 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
11758 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
11759 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
11761 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
11762 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
11763                       string cstr, list<dag> pattern>
11764       : I<oops, iops, asm, operands, cstr, pattern> {
11765   bits<2> Sz;
11766   bit NP;
11767   bit Acq;
11768   bit Rel;
11769   bits<5> Rs;
11770   bits<5> Rn;
11771   bits<5> Rt;
11772   let Inst{31-30} = Sz;
11773   let Inst{29-24} = 0b001000;
11774   let Inst{23} = NP;
11775   let Inst{22} = Acq;
11776   let Inst{21} = 0b1;
11777   let Inst{20-16} = Rs;
11778   let Inst{15} = Rel;
11779   let Inst{14-10} = 0b11111;
11780   let Inst{9-5} = Rn;
11781   let Inst{4-0} = Rt;
11782   let Predicates = [HasLSE];
11785 class BaseCAS<string order, string size, RegisterClass RC>
11786       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11787                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
11788                         "$out = $Rs",[]>,
11789         Sched<[WriteAtomic]> {
11790   let NP = 1;
11793 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
11794   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
11795   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
11796   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
11797   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
11800 class BaseCASP<string order, string size, RegisterOperand RC>
11801       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11802                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
11803                         "$out = $Rs",[]>,
11804         Sched<[WriteAtomic]> {
11805   let NP = 0;
11808 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
11809   let Sz = 0b00, Acq = Acq, Rel = Rel in
11810     def W : BaseCASP<order, "", WSeqPairClassOperand>;
11811   let Sz = 0b01, Acq = Acq, Rel = Rel in
11812     def X : BaseCASP<order, "", XSeqPairClassOperand>;
11815 let Predicates = [HasLSE] in
11816 class BaseSWP<string order, string size, RegisterClass RC>
11817       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
11818           "\t$Rs, $Rt, [$Rn]","",[]>,
11819         Sched<[WriteAtomic]> {
11820   bits<2> Sz;
11821   bit Acq;
11822   bit Rel;
11823   bits<5> Rs;
11824   bits<3> opc = 0b000;
11825   bits<5> Rn;
11826   bits<5> Rt;
11827   let Inst{31-30} = Sz;
11828   let Inst{29-24} = 0b111000;
11829   let Inst{23} = Acq;
11830   let Inst{22} = Rel;
11831   let Inst{21} = 0b1;
11832   let Inst{20-16} = Rs;
11833   let Inst{15} = 0b1;
11834   let Inst{14-12} = opc;
11835   let Inst{11-10} = 0b00;
11836   let Inst{9-5} = Rn;
11837   let Inst{4-0} = Rt;
11838   let Predicates = [HasLSE];
11841 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
11842   let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
11843   let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
11844   let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
11845   let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
11848 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
11849 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
11850       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
11851           "\t$Rs, $Rt, [$Rn]","",[]>,
11852         Sched<[WriteAtomic]> {
11853   bits<2> Sz;
11854   bit Acq;
11855   bit Rel;
11856   bits<5> Rs;
11857   bits<3> opc;
11858   bits<5> Rn;
11859   bits<5> Rt;
11860   let Inst{31-30} = Sz;
11861   let Inst{29-24} = 0b111000;
11862   let Inst{23} = Acq;
11863   let Inst{22} = Rel;
11864   let Inst{21} = 0b1;
11865   let Inst{20-16} = Rs;
11866   let Inst{15} = 0b0;
11867   let Inst{14-12} = opc;
11868   let Inst{11-10} = 0b00;
11869   let Inst{9-5} = Rn;
11870   let Inst{4-0} = Rt;
11871   let Predicates = [HasLSE];
11874 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
11875                         string order> {
11876   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
11877     def B : BaseLDOPregister<op, order, "b", GPR32>;
11878   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
11879     def H : BaseLDOPregister<op, order, "h", GPR32>;
11880   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
11881     def W : BaseLDOPregister<op, order, "", GPR32>;
11882   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
11883     def X : BaseLDOPregister<op, order, "", GPR64>;
11886 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
11887 // complex DAG for DstRHS.
11888 let Predicates = [HasLSE] in
11889 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
11890                                          string size, dag SrcRHS, dag DstRHS> {
11891   def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
11892             (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
11893   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
11894             (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
11895   def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
11896             (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
11897   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
11898             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11899   def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
11900             (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11903 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
11904                                      string size, dag RHS> {
11905   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
11908 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
11909                                          string size, dag LHS, dag RHS> {
11910   defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
11913 multiclass LDOPregister_patterns<string inst, string op> {
11914   defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
11915   defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
11916   defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
11917   defm : LDOPregister_patterns_ord<inst, "B", op, "8",  (i32 GPR32:$Rm)>;
11920 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
11921   defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
11922                         (i64 GPR64:$Rm),
11923                         (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
11924   defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
11925                         (i32 GPR32:$Rm),
11926                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11927   defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
11928                         (i32 GPR32:$Rm),
11929                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11930   defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
11931                         (i32 GPR32:$Rm),
11932                         (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11935 let Predicates = [HasLSE] in
11936 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
11937                                         string size, dag OLD, dag NEW> {
11938   def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
11939             (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
11940   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
11941             (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11942   def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
11943             (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11944   def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
11945             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11946   def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
11947             (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11950 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
11951                                     string size, dag OLD, dag NEW> {
11952   defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
11955 multiclass CASregister_patterns<string inst, string op> {
11956   defm : CASregister_patterns_ord<inst, "X", op, "64",
11957                         (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
11958   defm : CASregister_patterns_ord<inst, "W", op, "32",
11959                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11960   defm : CASregister_patterns_ord<inst, "H", op, "16",
11961                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11962   defm : CASregister_patterns_ord<inst, "B", op, "8",
11963                         (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11966 let Predicates = [HasLSE] in
11967 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
11968                         Instruction inst> :
11969       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
11971 multiclass STOPregister<string asm, string instr> {
11972   def : BaseSTOPregister<asm # "lb", GPR32, WZR,
11973                     !cast<Instruction>(instr # "LB")>;
11974   def : BaseSTOPregister<asm # "lh", GPR32, WZR,
11975                     !cast<Instruction>(instr # "LH")>;
11976   def : BaseSTOPregister<asm # "l",  GPR32, WZR,
11977                     !cast<Instruction>(instr # "LW")>;
11978   def : BaseSTOPregister<asm # "l",  GPR64, XZR,
11979                     !cast<Instruction>(instr # "LX")>;
11980   def : BaseSTOPregister<asm # "b",  GPR32, WZR,
11981                     !cast<Instruction>(instr # "B")>;
11982   def : BaseSTOPregister<asm # "h",  GPR32, WZR,
11983                     !cast<Instruction>(instr # "H")>;
11984   def : BaseSTOPregister<asm,        GPR32, WZR,
11985                     !cast<Instruction>(instr # "W")>;
11986   def : BaseSTOPregister<asm,        GPR64, XZR,
11987                     !cast<Instruction>(instr # "X")>;
11990 class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops,
11991                         dag iops, dag oops, list<dag> pat>
11992     : I<oops, iops, asm_inst, asm_ops, "", pat>,
11993       Sched<[]> /* FIXME: fill in scheduling details once known */ {
11994   bits<5> Rt;
11995   bits<5> Rn;
11996   let Inst{31-21} = 0b11111000001;
11997   let Inst{15}    = 1;
11998   let Inst{14-12} = opc;
11999   let Inst{11-10} = 0b00;
12000   let Inst{9-5}   = Rn;
12001   let Inst{4-0}   = Rt;
12003   let Predicates = [HasV8_7a];
12006 class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops,
12007                       list<dag> pat = []>
12008     : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> {
12009   let Inst{20-16} = 0b11111;
12012 class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []>
12013     : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]",
12014                        (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> {
12015   bits<5> Rs;
12016   let Inst{20-16} = Rs;
12019 class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1,
12020                              bits<2> op2, string asm>
12021   : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb),
12022       (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn),
12023       asm, "\t[$Rd]!, [$Rs]!, $Rn!",
12024       "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>,
12025     Sched<[]> {
12026   bits<5> Rd;
12027   bits<5> Rs;
12028   bits<5> Rn;
12029   let Inst{31-27} = 0b00011;
12030   let Inst{26} = isMove;
12031   let Inst{25-24} = 0b01;
12032   let Inst{23-22} = opcode;
12033   let Inst{21} = 0b0;
12034   let Inst{20-16} = Rs;
12035   let Inst{15-14} = op2;
12036   let Inst{13-12} = op1;
12037   let Inst{11-10} = 0b01;
12038   let Inst{9-5} = Rn;
12039   let Inst{4-0} = Rd;
12041   let DecoderMethod = "DecodeCPYMemOpInstruction";
12042   let mayLoad = 1;
12043   let mayStore = 1;
12046 class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>
12047   : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>;
12049 class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>
12050   : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>;
12052 class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2,
12053                         string asm>
12054   : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb),
12055       (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm),
12056       asm, "\t[$Rd]!, $Rn!, $Rm",
12057       "$Rd = $Rd_wb,$Rn = $Rn_wb", []>,
12058     Sched<[]> {
12059   bits<5> Rd;
12060   bits<5> Rn;
12061   bits<5> Rm;
12062   let Inst{31-27} = 0b00011;
12063   let Inst{26} = isTagging;
12064   let Inst{25-21} = 0b01110;
12065   let Inst{20-16} = Rm;
12066   let Inst{15-14} = opcode;
12067   let Inst{13} = op2;
12068   let Inst{12} = op1;
12069   let Inst{11-10} = 0b01;
12070   let Inst{9-5} = Rn;
12071   let Inst{4-0} = Rd;
12073   let DecoderMethod = "DecodeSETMemOpInstruction";
12074   let mayLoad = 0;
12075   let mayStore = 1;
12078 class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm>
12079   : MOPSMemorySetBase<0, opcode, op1, op2, asm>;
12081 class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm>
12082   : MOPSMemorySetBase<1, opcode, op1, op2, asm>;
12084 multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> {
12085   def ""   : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>;
12086   def WN   : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">;
12087   def RN   : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">;
12088   def N    : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">;
12089   def WT   : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">;
12090   def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">;
12091   def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">;
12092   def WTN  : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">;
12093   def RT   : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">;
12094   def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">;
12095   def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">;
12096   def RTN  : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">;
12097   def T    : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">;
12098   def TWN  : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">;
12099   def TRN  : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">;
12100   def TN   : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">;
12103 multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> {
12104   def ""   : MOPSMemoryMove<opcode, 0b00, 0b00, asm>;
12105   def WN   : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">;
12106   def RN   : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">;
12107   def N    : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">;
12108   def WT   : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">;
12109   def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">;
12110   def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">;
12111   def WTN  : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">;
12112   def RT   : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">;
12113   def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">;
12114   def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">;
12115   def RTN  : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">;
12116   def T    : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">;
12117   def TWN  : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">;
12118   def TRN  : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">;
12119   def TN   : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">;
12122 multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> {
12123   def "" : MOPSMemorySet<opcode, 0, 0, asm>;
12124   def T  : MOPSMemorySet<opcode, 1, 0, asm # "t">;
12125   def N  : MOPSMemorySet<opcode, 0, 1, asm # "n">;
12126   def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">;
12129 multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> {
12130   def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>;
12131   def T  : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">;
12132   def N  : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">;
12133   def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">;
12136 //----------------------------------------------------------------------------
12137 // 2022 Armv8.9/Armv9.4 Extensions
12138 //----------------------------------------------------------------------------
12140 //---
12141 // 2022 Architecture Extensions: General Data Processing (FEAT_CSSC)
12142 //---
12144 class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc,
12145                            RegisterClass regtype, ImmLeaf immtype, string asm,
12146                            SDPatternOperator OpNode>
12147     : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm),
12148         asm, "\t$Rd, $Rn, $imm", "",
12149         [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> {
12150   bits<5> Rd;
12151   bits<5> Rn;
12152   bits<8> imm;
12154   let Inst{31}    = sf;
12155   let Inst{30}    = Op;
12156   let Inst{29}    = S;
12157   let Inst{28-22} = 0b1000111;
12158   let Inst{21-18} = opc;
12159   let Inst{17-10} = imm;
12160   let Inst{9-5}   = Rn;
12161   let Inst{4-0}   = Rd;
12164 class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin,
12165                           RegisterClass regtype, string asm,
12166                           SDPatternOperator OpNode>
12167     : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>,
12168       Sched<[WriteI]> {
12169   let Inst{11} = isMin;
12170   let Inst{10} = isUnsigned;
12171   let mayLoad  = 0;
12172   let mayStore = 0;
12173   let hasSideEffects = 0;
12176 class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin,
12177                           RegisterClass regtype, ImmLeaf immtype, string asm,
12178                           SDPatternOperator OpNode>
12179     : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm,
12180                            OpNode>,
12181       Sched<[]> {
12182   let Inst{19} = isMin;
12183   let Inst{18} = isUnsigned;
12184   let mayLoad  = 0;
12185   let mayStore = 0;
12186   let hasSideEffects = 0;
12189 multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm,
12190                         SDPatternOperator OpNode = null_frag> {
12191   def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>;
12193   def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32,
12194                                 !cond(isUnsigned : uimm8_32b,
12195                                       !not(isUnsigned) : simm8_32b), asm, OpNode>;
12197   def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>;
12199   def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64,
12200                                 !cond(isUnsigned : uimm8_64b,
12201                                       !not(isUnsigned) : simm8_64b), asm, OpNode>;
12204 //---
12205 // RCPC instructions (FEAT_LRCPC3)
12206 //---
12208 class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops,
12209                  string asm, string operands, string cstr = "">
12210       : I<oops, iops, asm, operands, cstr, []>,
12211         Sched<[WriteAtomic]> {
12212   bits<5> Rt;
12213   bits<5> Rn;
12214   let Inst{31-30}    = size;
12215   let Inst{29-24}    = {0,1,1,V,0,1};
12216   let Inst{23-22}    = opc;
12217   let Inst{21}       = 0b0;
12218   //  Inst{20-12}
12219   let Inst{11-10}    = 0b10;
12220   let Inst{9-5}      = Rn;
12221   let Inst{4-0}      = Rt;
12223   let mayLoad = Inst{22};
12224   let mayStore = !not(Inst{22});
12225   let hasSideEffects = 0;
12228 class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2,
12229                                      dag oops, dag iops, string asm,
12230                                      string operands, string cstr>
12231       : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> {
12232   bits<5> Rt2;
12233   let Inst{20-16} = Rt2;
12234   let Inst{15-12} = opc2;
12237 class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops,
12238                                  string asm, string operands, string cstr>
12239       : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> {
12240   let Inst{20-12} = 0b000000000; // imm9
12243 multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype,
12244                                              dag oops, dag iops, string asm> {
12245   def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> {
12246     bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4
12247     let Inst{20-12} = simm;
12248   }
12250   def a : InstAlias<asm # "\t$Rt, [$Rn]",
12251                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
12254 class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst>
12255       : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm,
12256                            "\t$Vt$Q, [$Rn]", cst, oops, iops, []>,
12257         Sched<[]> {
12258   bit Q;
12259   let Inst{31}       = 0;
12260   let Inst{30}       = Q;
12261   let Inst{23}       = 0;
12262   let Inst{20-16}    = 0b00001;
12263   let Inst{12}       = 0; // S
12264   let Inst{11-10}    = 0b01; // size
12266   let mayLoad = L;
12267   let mayStore = !not(L);
12268   let hasSideEffects = 1;
12271 //---
12272 // Instrumentation Extension (FEAT_ITE)
12273 //---
12275 let Predicates = [HasITE] in
12276 def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> {
12277   let Inst{20-19} = 0b01;
12278   let Inst{18-16} = 0b011;
12279   let Inst{15-12} = 0b0111;
12280   let Inst{11-8}  = 0b0010;
12281   let Inst{7-5}   = 0b111;
12284 // * RCWCAS family
12285 // * RCW<OP> family
12287 //--------------------------------------------------------------------
12288 // Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?)
12290 // Instruction encoding:
12292 //          31 30|29  24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 0
12293 // RCWCAS    0  0|011001| A| R| 1|   Rs| 0| 0  0| 0  1  0| Rn| Rt
12294 // RCWSCAS   0  1|011001| A| R| 1|   Rs| 0| 0  0| 0  1  0| Rn| Rt
12295 // RCWCASP   0  0|011001| A| R| 1|   Rs| 0| 0  0| 0  1  1| Rn| Rt
12296 // RCWSCASP  0  1|011001| A| R| 1|   Rs| 0| 0  0| 0  1  1| Rn| Rt
12298 // Instruction syntax:
12300 // RCW[S]CAS{<order>}   <Xs>,           <Xt>,          [<Xn|SP>]
12301 // RCW[S]CASP{<order>}  <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>]
12303 class BaseRCWCASEncoding<dag oops, dag iops, string asm>
12304       : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>,
12305         Sched<[]> {
12306   bit Acq;
12307   bit Rel;
12308   bit SC;
12309   bit Pair;
12310   bits<5> Rs;
12311   bits<5> Rn;
12312   bits<5> Rt;
12313   let Inst{31} = 0b0;
12314   let Inst{30} = SC;
12315   let Inst{29-24} = 0b011001;
12316   let Inst{23} = Acq;
12317   let Inst{22} = Rel;
12318   let Inst{21} = 0b1;
12319   let Inst{20-16} = Rs;
12320   let Inst{15-13} = 0b000;
12321   let Inst{12-11} = 0b01;
12322   let Inst{10} = Pair;
12323   let Inst{9-5} = Rn;
12324   let Inst{4-0} = Rt;
12325   let mayLoad = 1;
12326   let mayStore = 1;
12327   let hasSideEffects = 1;
12328   let Defs = [NZCV];
12331 multiclass BaseRCWCAS<dag oops, dag iops, string prefix> {
12332   let Acq = 0b0, Rel = 0b0 in
12333     def "" : BaseRCWCASEncoding<oops, iops, prefix # "">;
12334   let Acq = 0b1, Rel = 0b0 in
12335     def A  : BaseRCWCASEncoding<oops, iops, prefix # "a">;
12336   let Acq = 0b0, Rel = 0b1 in
12337     def L  : BaseRCWCASEncoding<oops, iops, prefix # "l">;
12338   let Acq = 0b1, Rel = 0b1 in
12339     def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">;
12342 multiclass ReadCheckWriteCompareAndSwap {
12343   let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in
12344     defm CAS  : BaseRCWCAS<(outs GPR64:$out),
12345                            (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >;
12346   let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in
12347     defm SCAS : BaseRCWCAS<(outs GPR64:$out),
12348                            (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">;
12349   let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in
12350     defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out),
12351                            (ins XSeqPairClassOperand:$Rs,
12352                                 XSeqPairClassOperand:$Rt, GPR64sp:$Rn),
12353                            "rcwcasp">;
12354   let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in
12355     defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out),
12356                            (ins XSeqPairClassOperand:$Rs,
12357                                 XSeqPairClassOperand:$Rt, GPR64sp:$Rn),
12358                            "rcwscasp">;
12361 //------------------------------------------------------------------
12362 // Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?)
12364 // Instruction encoding:
12366 //          31 30|29  24|23|22|21|20 16|15|14 12|11 10|9 5|4 0
12367 // RCWCLR    0  0|111000| A| R| 1|   Rs| 1|  001| 0  0| Rn| Rt
12368 // RCWSCLR   0  1|111000| A| R| 1|   Rs| 1|  001| 0  0| Rn| Rt
12369 // RCWSET    0  0|111000| A| R| 1|   Rs| 1|  011| 0  0| Rn| Rt
12370 // RCWSSET   0  1|111000| A| R| 1|   Rs| 1|  011| 0  0| Rn| Rt
12371 // RCWSWP    0  0|111000| A| R| 1|   Rs| 1|  010| 0  0| Rn| Rt
12372 // RCWSSWP   0  1|111000| A| R| 1|   Rs| 1|  010| 0  0| Rn| Rt
12374 //          31 30|29  24|23|22|21|20 16|15|14 12|11 10|9 5|4 0
12375 // RCWCLRP   0  0|011001| A| R| 1|  Rt2| 1|  001| 0  0| Rn| Rt
12376 // RCWSCLRP  0  1|011001| A| R| 1|  Rt2| 1|  001| 0  0| Rn| Rt
12377 // RCWSETP   0  0|011001| A| R| 1|  Rt2| 1|  011| 0  0| Rn| Rt
12378 // RCWSSETP  0  1|011001| A| R| 1|  Rt2| 1|  011| 0  0| Rn| Rt
12379 // RCWSWPP   0  0|011001| A| R| 1|  Rt2| 1|  010| 0  0| Rn| Rt
12380 // RCWSSWPP  0  1|011001| A| R| 1|  Rt2| 1|  010| 0  0| Rn| Rt
12382 // Instruction syntax:
12384 // RCW[S]<OP>{<order>}   <Xs>,  <Xt>, [<Xn|SP>]
12385 // RCW[S]<OP>P{<order>}  <Xt1>, <Xt2>, [<Xn|SP>]
12387 class BaseRCWOPEncoding<string asm>
12388       : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm,
12389           "\t$Rs, $Rt, [$Rn]", "", []>,
12390         Sched<[]> {
12391   bit Acq;
12392   bit Rel;
12393   bit SC;
12394   bits<3> opc;
12395   bits<5> Rs;
12396   bits<5> Rn;
12397   bits<5> Rt;
12398   let Inst{31} = 0b0;
12399   let Inst{30} = SC;
12400   let Inst{29-24} = 0b111000;
12401   let Inst{23} = Acq;
12402   let Inst{22} = Rel;
12403   let Inst{21} = 0b1;
12404   let Inst{20-16} = Rs;
12405   let Inst{15} = 0b1;
12406   let Inst{14-12} = opc;
12407   let Inst{11-10} = 0b00;
12408   let Inst{9-5} = Rn;
12409   let Inst{4-0} = Rt;
12410   let mayLoad = 1;
12411   let mayStore = 1;
12412   let hasSideEffects = 1;
12413   let Defs = [NZCV];
12414   let Predicates = [HasTHE];
12417 class BaseRCWOPPEncoding<string asm>
12418       : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb),
12419           (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm,
12420           "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>,
12421         Sched<[]> {
12422   bit Acq;
12423   bit Rel;
12424   bit SC;
12425   bits<3> opc;
12426   bits<5> Rt2;
12427   bits<5> Rn;
12428   bits<5> Rt;
12429   let Inst{31} = 0b0;
12430   let Inst{30} = SC;
12431   let Inst{29-24} = 0b011001;
12432   let Inst{23} = Acq;
12433   let Inst{22} = Rel;
12434   let Inst{21} = 0b1;
12435   let Inst{20-16} = Rt2;
12436   let Inst{15} = 0b1;
12437   let Inst{14-12} = opc;
12438   let Inst{11-10} = 0b00;
12439   let Inst{9-5} = Rn;
12440   let Inst{4-0} = Rt;
12441   let mayLoad = 1;
12442   let mayStore = 1;
12443   let hasSideEffects = 1;
12444   let Defs = [NZCV];
12445   let Predicates = [HasTHE, HasD128];
12448 multiclass BaseRCWOP<string prefix> {
12449   let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">;
12450   let Acq = 0b1, Rel = 0b0 in def A  : BaseRCWOPEncoding<prefix # "a">;
12451   let Acq = 0b0, Rel = 0b1 in def L  : BaseRCWOPEncoding<prefix # "l">;
12452   let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">;
12454   let Acq = 0b0, Rel = 0b0 in def P   : BaseRCWOPPEncoding<prefix # "p">;
12455   let Acq = 0b1, Rel = 0b0 in def PA  : BaseRCWOPPEncoding<prefix # "pa">;
12456   let Acq = 0b0, Rel = 0b1 in def PL  : BaseRCWOPPEncoding<prefix # "pl">;
12457   let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">;
12460 multiclass ReadCheckWriteOperation<bits<3> opc, string op> {
12461   let SC = 0b0, opc = opc in defm ""  : BaseRCWOP<"rcw" # ""  # op>;
12462   let SC = 0b1, opc = opc in defm S   : BaseRCWOP<"rcw" # "s" # op >;
12465 //---
12466 // 128-bit atomic instructions (FEAT_LSE128)
12467 //---
12469 let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in
12470 class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm>
12471 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb),
12472     (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn),
12473     asm, "\t$Rt, $Rt2, [$Rn]",
12474     "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>,
12475   Sched<[]> {
12476   bits<5> Rt;
12477   bits<5> Rt2;
12478   bits<5> Rn;
12479   let Inst{31-24} = 0b00011001;
12480   let Inst{23-22} = AR;
12481   let Inst{21} = 0b1;
12482   let Inst{20-16} = Rt2;
12483   let Inst{15} = o3;
12484   let Inst{14-12} = op0;
12485   let Inst{11-10} = 0b00;
12486   let Inst{9-5} = Rn;
12487   let Inst{4-0} = Rt;
12490 //---
12491 // 128-bit System Instructions (FEAT_SYSINSTR128)
12492 //---
12494 // Instruction encoding:
12496 //          31          19|18 16|15 12|11 8|7 5|4 0
12497 // SYSP      1101010101001|  op1|   Cn|  Cm|op2| Rt
12499 // Instruction syntax:
12501 // SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>}
12503 class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> :
12504   RtSystemI<L, oops, iops, asm, operands, pattern> {
12505   let Inst{22}    = 0b1; // override BaseSystemI
12508 class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs>
12509   : RtSystemI128<L, outputs, inputs, asm, operands> {
12510   bits<3> op1;
12511   bits<4> Cn;
12512   bits<4> Cm;
12513   bits<3> op2;
12514   let Inst{20-19} = 0b01;
12515   let Inst{18-16} = op1;
12516   let Inst{15-12} = Cn;
12517   let Inst{11-8}  = Cm;
12518   let Inst{7-5}   = op2;
12520 class SystemPXtI<bit L, string asm> :
12521   BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs),
12522   (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>;
12524 //----------------------------------------------------------------------------
12525 // 2023 Armv9.5 Extensions
12526 //----------------------------------------------------------------------------
12528 //---
12529 // Checked Pointer Arithmetic (FEAT_CPA)
12530 //---
12532 def LSLImm3ShiftOperand : AsmOperandClass {
12533   let SuperClasses = [ExtendOperandLSL64];
12534   let Name = "LSLImm3Shift";
12535   let RenderMethod = "addLSLImm3ShifterOperands";
12536   let DiagnosticType = "AddSubLSLImm3ShiftLarge";
12539 def lsl_imm3_shift_operand : Operand<i32> {
12540   let PrintMethod = "printShifter";
12541   let ParserMatchClass = LSLImm3ShiftOperand;
12544 // Base CPA scalar add/subtract with lsl #imm3 shift
12545 class BaseAddSubCPA<bit isSub, string asm> : I<(outs GPR64sp:$Rd),
12546     (ins GPR64sp:$Rn, GPR64:$Rm, lsl_imm3_shift_operand:$shift_imm),
12547     asm, "\t$Rd, $Rn, $Rm$shift_imm", "", []>, Sched<[]> {
12548   bits<5> Rd;
12549   bits<5> Rn;
12550   bits<5> Rm;
12551   bits<3> shift_imm;
12552   let Inst{31} = 0b1;
12553   let Inst{30} = isSub;
12554   let Inst{29-21} = 0b011010000;
12555   let Inst{20-16} = Rm;
12556   let Inst{15-13} = 0b001;
12557   let Inst{12-10} = shift_imm;
12558   let Inst{9-5} = Rn;
12559   let Inst{4-0} = Rd;
12562 // Alias for CPA scalar add/subtract with no shift
12563 class AddSubCPAAlias<string asm, Instruction inst>
12564     : InstAlias<asm#"\t$Rd, $Rn, $Rm",
12565                 (inst GPR64sp:$Rd, GPR64sp:$Rn, GPR64:$Rm, 0)>;
12567 multiclass AddSubCPA<bit isSub, string asm> {
12568   def _shift : BaseAddSubCPA<isSub, asm>;
12569   def _noshift : AddSubCPAAlias<asm, !cast<Instruction>(NAME#"_shift")>;
12572 class MulAccumCPA<bit isSub, string asm>
12573   : BaseMulAccum<isSub, 0b011, GPR64, GPR64, asm, []>, Sched<[]> {
12574   let Inst{31} = 0b1;
12577 //----------------------------------------------------------------------------
12578 // Allow the size specifier tokens to be upper case, not just lower.
12579 def : TokenAlias<".4B", ".4b">;  // Add dot product
12580 def : TokenAlias<".8B", ".8b">;
12581 def : TokenAlias<".4H", ".4h">;
12582 def : TokenAlias<".2S", ".2s">;
12583 def : TokenAlias<".1D", ".1d">;
12584 def : TokenAlias<".16B", ".16b">;
12585 def : TokenAlias<".8H", ".8h">;
12586 def : TokenAlias<".4S", ".4s">;
12587 def : TokenAlias<".2D", ".2d">;
12588 def : TokenAlias<".1Q", ".1q">;
12589 def : TokenAlias<".2H", ".2h">;
12590 def : TokenAlias<".2B", ".2b">;
12591 def : TokenAlias<".B", ".b">;
12592 def : TokenAlias<".H", ".h">;
12593 def : TokenAlias<".S", ".s">;
12594 def : TokenAlias<".D", ".d">;
12595 def : TokenAlias<".Q", ".q">;