1 //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
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
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
16 class Format<bits<2> 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> {
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> {
44 def FalseLanesNone : FalseLanesEnum<0>;
45 def FalseLanesZero : FalseLanesEnum<1>;
46 def FalseLanesUndef : FalseLanesEnum<2>;
48 class SMEMatrixTypeEnum<bits<3> 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";
72 bits<2> Form = F.Value;
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;
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;
106 // Real instructions (have encoding information)
107 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
108 let Pattern = pattern;
112 // Normal instructions
113 class I<dag oops, dag iops, string asm, string operands, string cstr,
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))>;
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))]>;
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))]>;
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))]>;
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 {
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 {
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";
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";
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 {
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);
477 def UImmS2XForm : SDNodeXForm<imm, [{
478 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);
480 def UImmS4XForm : SDNodeXForm<imm, [{
481 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);
483 def UImmS8XForm : SDNodeXForm<imm, [{
484 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
487 // uimm5sN predicate - True if the immediate is a multiple of N in the range
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); }],
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); }],
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); }],
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); }],
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); }],
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); }],
529 let ParserMatchClass = UImm5s8Operand;
530 let PrintMethod = "printImmScale<8>";
533 // uimm6sN predicate - True if the immediate is a multiple of N in the range
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);
568 def SImmS3XForm : SDNodeXForm<imm, [{
569 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64);
571 def SImmS4XForm : SDNodeXForm<imm, [{
572 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64);
574 def SImmS16XForm : SDNodeXForm<imm, [{
575 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64);
577 def SImmS32XForm : SDNodeXForm<imm, [{
578 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64);
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
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>
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>
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>
718 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<32>", [fpimm, ld]> {
719 let EncoderMethod = "getFixedPointScaleOpValue";
720 let DecoderMethod = "DecodeFixedPointScaleImm32";
723 class fixedpoint_recip_i64<ValueType 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);
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);
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);
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);
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);
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);
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);
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
790 def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
791 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
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);
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);
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);
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);
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);
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);
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);
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
861 def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{
862 return (((uint32_t)Imm) < 8);
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);
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);
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);
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);
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);
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>";
912 def LogicalImm64Operand : AsmOperandClass {
913 let Name = "LogicalImm64";
914 let PredicateMethod = "isLogicalImm<int64_t>";
915 let RenderMethod = "addLogicalImmOperands<int64_t>";
917 def LogicalImm32NotOperand : AsmOperandClass {
918 let Name = "LogicalImm32Not";
919 let PredicateMethod = "isLogicalImm<int32_t>";
920 let RenderMethod = "addLogicalImmNotOperands<int32_t>";
922 def LogicalImm64NotOperand : AsmOperandClass {
923 let Name = "LogicalImm64Not";
924 let PredicateMethod = "isLogicalImm<int64_t>";
925 let RenderMethod = "addLogicalImmNotOperands<int64_t>";
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;
958 def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{
959 return ((uint64_t)Imm) < 65536;
962 def imm64_0_65535 : Operand<i64>, ImmLeaf<i64, [{
963 return ((uint64_t)Imm) < 65536;
965 } // ParserMatchClass
967 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
968 return ((uint32_t)Imm) < 256;
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;
978 let ParserMatchClass = Imm0_127Operand;
979 let PrintMethod = "printImm";
982 def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{
983 return ((uint64_t)Imm) < 128;
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;
996 let ParserMatchClass = Imm0_63Operand;
999 def timm0_63 : Operand<i64>, TImmLeaf<i64, [{
1000 return ((uint64_t)Imm) < 64;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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
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>
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
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>
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>";
1233 def AddSubImmNegOperand : AsmOperandClass {
1234 let Name = "AddSubImmNeg";
1235 let ParserMethod = "tryParseImmWithOptionalShift";
1236 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
1239 // An ADD/SUB immediate shifter 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>
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
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);
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);
1351 def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{
1352 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF()
1355 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
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);
1364 def fpimm16 : Operand<f16>,
1366 return AArch64_AM::getFP16Imm(Imm) != -1;
1368 let ParserMatchClass = FPImmOperand;
1369 let PrintMethod = "printFPImmOperand";
1372 def fpimmbf16 : Operand<bf16>,
1374 return AArch64_AM::getFP16Imm(Imm) != -1;
1377 def fpimm32 : Operand<f32>,
1379 return AArch64_AM::getFP32Imm(Imm) != -1;
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>,
1393 return AArch64_AM::getFP64Imm(Imm) != -1;
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);
1408 def fpimm_minus0 : FPImmLeaf<fAny, [{
1409 return Imm.isExactlyValue(-0.0);
1412 def fpimm_half : FPImmLeaf<fAny, [{
1413 return Imm.isExactlyValue(+0.5);
1416 def fpimm_one : FPImmLeaf<fAny, [{
1417 return Imm.isExactlyValue(+1.0);
1420 def fpimm_two : FPImmLeaf<fAny, [{
1421 return Imm.isExactlyValue(+2.0);
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>
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; }]>;
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;
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;
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;
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;
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;
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>,
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()
1635 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1637 let ParserMatchClass = SIMDImmType10Operand;
1638 let PrintMethod = "printSIMDType10Operand";
1643 // System management
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;
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>,
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>,
1676 let Inst{20-12} = 0b000110011;
1677 let Inst{11-8} = CRm;
1678 let Inst{7-5} = op2;
1679 let DecoderMethod = "";
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> {
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>,
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]> {
1729 let Inst{20-12} = 0b000110010;
1730 let Inst{11-5} = imm;
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]> {
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]> {
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.
1809 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
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.
1824 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr;
1828 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
1829 "mrs", "\t$Rt, $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.
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"> {
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 = [{
1860 return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr;
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">,
1878 bits<6> pstatefield;
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 = [{
1900 return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr;
1904 class MSRpstateImm0_1
1905 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",
1906 "\t$pstatefield, $imm">,
1909 bits<9> pstatefield;
1911 let Inst{18-16} = pstatefield{5-3};
1912 let Inst{11-9} = pstatefield{8-6};
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 {
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"> {
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"> {
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);
1974 let PrintMethod = "printRPRFMOperand";
1975 let ParserMatchClass = RangePrefetchOperand;
1978 // Branch (register) instructions:
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> {
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;
2010 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
2011 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
2015 let Inst{31-30} = sz;
2016 let Inst{29-10} = 0b11100010111111110000;
2021 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
2023 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
2024 let isAuthenticated = 1;
2025 let Inst{31-25} = 0b1101011;
2026 let Inst{20-11} = 0b1111100001;
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", []> {
2035 let Inst{24-22} = 0b100;
2041 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
2042 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
2045 let Inst{23-21} = opc;
2049 let Uses = [LR,SP] in
2050 class AuthReturn<bits<3> op, bits<1> M, string asm>
2051 : AuthBase<M, (outs), (ins), asm, "", []> {
2053 let Inst{23-21} = op;
2054 let Inst{9-0} = 0b1111111111;
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<[]> {
2064 let isAuthenticated = 1;
2065 let Inst{31-24} = 0b11111000;
2067 let Inst{22} = offset{9};
2069 let Inst{20-12} = offset{8-0};
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>;
2095 // Conditional branch instruction.
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;
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]> {
2130 let isTerminator = 1;
2135 let Inst{31-24} = 0b01010100;
2136 let Inst{23-5} = target;
2138 let Inst{3-0} = cond;
2142 // Compare-and-branch instructions.
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)]>,
2150 let isTerminator = 1;
2154 let Inst{30-25} = 0b011010;
2156 let Inst{23-5} = target;
2160 multiclass CmpBranch<bit op, string asm, SDNode node> {
2161 def W : BaseCmpBranch<GPR32, op, asm, node> {
2164 def X : BaseCmpBranch<GPR64, op, asm, node> {
2170 // Test-bit-and-branch instructions.
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);
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);
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)]>,
2216 let isTerminator = 1;
2222 let Inst{30-25} = 0b011011;
2224 let Inst{23-19} = bit_off{4-0};
2225 let Inst{18-5} = target;
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> {
2236 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
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)>;
2250 // Unconditional branch (immediate) instructions.
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]> {
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>;
2281 // Basic one-operand data processing instructions.
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]> {
2297 let Inst{28-21} = 0b11010110;
2298 let Inst{20-16} = opc2;
2299 let Inst{15-10} = opc;
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]> {
2325 let Inst{31-15} = 0b11011010110000010;
2326 let Inst{14-12} = opcode_prefix;
2327 let Inst{11-10} = opcode;
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)))]>,
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;
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]> {
2354 let Inst{31-21} = 0b10011010110;
2355 let Inst{20-16} = Rm;
2356 let Inst{15-14} = 0b00;
2357 let Inst{13-10} = opc;
2362 class ClearAuth<bits<1> data, string asm>
2363 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> {
2365 let Inst{31-11} = 0b110110101100000101000;
2366 let Inst{10} = data;
2367 let Inst{9-5} = 0b11111;
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
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", "", []>,
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", "", []>,
2413 let Inst{31} = 0b1; // sf
2415 let Inst{29} = 0b0; // S
2416 let Inst{28-21} = 0b11010110;
2417 let Inst{20-16} = opcode2;
2418 let Inst{15-10} = opcode;
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]> {
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]> {
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]> {
2453 let Inst{30-15} = 0b0111010000000000;
2455 let Inst{13-10} = 0b0010;
2457 let Inst{4-0} = 0b01101;
2460 class FlagRotate<dag iops, string asm, string ops>
2461 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
2464 let Inst{20-15} = imm;
2465 let Inst{13-10} = 0b0001;
2467 let Inst{3-0} = mask;
2471 // Basic two-operand data processing instructions.
2473 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
2475 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2476 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2477 Sched<[WriteI, ReadI, ReadI]> {
2482 let Inst{30} = isSub;
2483 let Inst{28-21} = 0b11010000;
2484 let Inst{20-16} = Rm;
2485 let Inst{15-10} = 0;
2490 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
2492 : BaseBaseAddSubCarry<isSub, regtype, asm,
2493 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
2495 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
2497 : BaseBaseAddSubCarry<isSub, regtype, asm,
2498 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, 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> {
2509 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
2515 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
2520 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
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))]> {
2540 let Inst{28-21} = 0b11010110;
2541 let Inst{20-16} = Rm;
2542 let Inst{15-10} = opc;
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,
2602 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
2603 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
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;
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]> {
2624 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>,
2625 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
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]> {
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]> {
2647 let Inst{31-24} = 0b10011011;
2648 let Inst{23-21} = opc;
2649 let Inst{20-16} = Rm;
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]> {
2680 let Inst{30-21} = 0b0011010110;
2681 let Inst{20-16} = Rm;
2682 let Inst{15-13} = 0b010;
2684 let Inst{11-10} = sz;
2687 let Predicates = [HasCRC];
2691 // Address generation.
2694 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
2695 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $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};
2706 let DecoderMethod = "DecodeAdrInstruction";
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,
2730 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
2731 asm, "\t$Rd, $imm$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;
2742 let DecoderMethod = "DecodeMoveImmInstruction";
2745 multiclass MoveImmediate<bits<2> opc, string asm> {
2746 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
2750 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
2755 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2756 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
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]> {
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;
2771 let DecoderMethod = "DecodeMoveImmInstruction";
2774 multiclass InsertImmediate<bits<2> opc, string asm> {
2775 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
2779 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
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]> {
2795 let Inst{30} = isSub;
2796 let Inst{29} = setFlags;
2797 let Inst{28-24} = 0b10001;
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))> {
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]> {
2832 let Inst{30} = isSub;
2833 let Inst{29} = setFlags;
2834 let Inst{28-24} = 0b01011;
2835 let Inst{23-22} = shift{7-6};
2837 let Inst{20-16} = Rm;
2838 let Inst{15-10} = shift{5-0};
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]> {
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};
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]> {
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};
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,
2899 : InstAlias<asm#"\t$dst, $src1, $src2",
2900 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
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,
2916 let AddedComplexity = 6 in
2917 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
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,
2931 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
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> {
2943 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
2944 arith_extended_reg32to64_i64, mnemonic, OpNode> {
2949 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
2950 arith_extendlsl64, mnemonic> {
2951 // UXTX and SXTX only.
2952 let Inst{14-13} = 0b11;
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,
2992 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
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,
3006 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
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> {
3017 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
3018 arith_extended_reg32_i64, mnemonic, OpNode> {
3023 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
3024 arith_extendlsl64, mnemonic> {
3025 // UXTX and SXTX only.
3026 let Inst{14-13} = 0b11;
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>;
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
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>
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))> {
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,
3108 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
3110 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
3112 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
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]> {
3122 let Inst{30-23} = 0b00100111;
3124 let Inst{20-16} = Rm;
3125 let Inst{15-10} = imm;
3130 multiclass ExtractImm<string asm> {
3131 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
3133 (fshr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
3136 // imm<5> must be zero.
3139 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
3141 (fshr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
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]> {
3163 let Inst{30-29} = opc;
3164 let Inst{28-23} = 0b100110;
3165 let Inst{21-16} = immr;
3166 let Inst{15-10} = imms;
3171 multiclass BitfieldImm<bits<2> opc, string asm> {
3172 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
3175 // imms<5> and immr<5> must be zero, else ReservedValue().
3179 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
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,
3190 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
3191 Sched<[WriteIS, ReadI]> {
3197 let Inst{30-29} = opc;
3198 let Inst{28-23} = 0b100110;
3199 let Inst{21-16} = immr;
3200 let Inst{15-10} = imms;
3205 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
3206 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
3209 // imms<5> and immr<5> must be zero, else ReservedValue().
3213 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
3223 // Logical (immediate)
3224 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
3225 RegisterClass sregtype, Operand imm_type, string asm,
3227 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
3228 asm, "\t$Rd, $Rn, $imm", "", pattern>,
3229 Sched<[WriteI, ReadI]> {
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};
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,
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]> {
3255 let Inst{30-29} = opc;
3256 let Inst{28-24} = 0b01010;
3257 let Inst{23-22} = shift{7-6};
3259 let Inst{20-16} = Rm;
3260 let Inst{15-10} = shift{5-0};
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,
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))]> {
3279 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
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))]> {
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,
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))]> {
3302 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
3304 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
3305 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
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>;
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))]> {
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))]> {
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))]> {
3359 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
3360 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> {
3365 def : LogicalRegAlias<mnemonic,
3366 !cast<Instruction>(NAME#"Wrs"), GPR32>;
3367 def : LogicalRegAlias<mnemonic,
3368 !cast<Instruction>(NAME#"Xrs"), GPR64>;
3372 // Conditionally set flags
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]> {
3392 let Inst{29-21} = 0b111010010;
3393 let Inst{20-16} = imm;
3394 let Inst{15-12} = cond;
3395 let Inst{11-10} = 0b10;
3398 let Inst{3-0} = nzcv;
3401 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3402 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
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]> {
3418 let Inst{29-21} = 0b111010010;
3419 let Inst{20-16} = Rm;
3420 let Inst{15-12} = cond;
3421 let Inst{11-10} = 0b00;
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> {
3432 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
3435 // register operand variants
3436 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
3439 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
3445 // Conditional select
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", "",
3452 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
3453 Sched<[WriteI, ReadI, ReadI]> {
3462 let Inst{29-21} = 0b011010100;
3463 let Inst{20-16} = Rm;
3464 let Inst{15-12} = cond;
3465 let Inst{11-10} = op2;
3470 multiclass CondSelect<bit op, bits<2> op2, string asm> {
3471 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
3474 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
3479 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
3481 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3482 asm, "\t$Rd, $Rn, $Rm, $cond", "",
3484 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
3485 (i32 imm:$cond), NZCV))]>,
3486 Sched<[WriteI, ReadI, ReadI]> {
3495 let Inst{29-21} = 0b011010100;
3496 let Inst{20-16} = Rm;
3497 let Inst{15-12} = cond;
3498 let Inst{11-10} = op2;
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),
3509 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
3510 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
3513 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
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))>;
3527 // Special Mask Value
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; }]> {
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");
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> {
3607 let Inst{31-30} = sz;
3608 let Inst{29-27} = 0b111;
3610 let Inst{25-24} = 0b01;
3611 let Inst{23-22} = opc;
3612 let Inst{21-10} = offset;
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),
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),
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
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),
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),
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>,
3697 let Inst{31-30} = opc;
3698 let Inst{29-27} = 0b011;
3700 let Inst{25-24} = 0b00;
3701 let Inst{23-5} = label;
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>,
3712 let Inst{31-30} = opc;
3713 let Inst{29-27} = 0b011;
3715 let Inst{25-24} = 0b00;
3716 let Inst{23-5} = label;
3721 // Load/store register offset
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>
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,
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> {
3841 let Inst{31-30} = sz;
3842 let Inst{29-27} = 0b111;
3844 let Inst{25-24} = 0b00;
3845 let Inst{23-22} = opc;
3847 let Inst{20-16} = Rm;
3848 let Inst{15} = extend{1}; // sign extend Rm?
3850 let Inst{12} = extend{0}; // do shift?
3851 let Inst{11-10} = 0b10;
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,
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]> {
3873 let AddedComplexity = 10 in
3874 def roX : LoadStore8RO<sz, V, opc, asm,
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]> {
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]> {
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]> {
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> {
3919 let Inst{31-30} = sz;
3920 let Inst{29-27} = 0b111;
3922 let Inst{25-24} = 0b00;
3923 let Inst{23-22} = opc;
3925 let Inst{20-16} = Rm;
3926 let Inst{15} = extend{1}; // sign extend Rm?
3928 let Inst{12} = extend{0}; // do shift?
3929 let Inst{11-10} = 0b10;
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]> {
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]> {
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]> {
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]> {
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> {
3991 let Inst{31-30} = sz;
3992 let Inst{29-27} = 0b111;
3994 let Inst{25-24} = 0b00;
3995 let Inst{23-22} = opc;
3997 let Inst{20-16} = Rm;
3998 let Inst{15} = extend{1}; // sign extend Rm?
4000 let Inst{12} = extend{0}; // do shift?
4001 let Inst{11-10} = 0b10;
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]> {
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]> {
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]> {
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]> {
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> {
4063 let Inst{31-30} = sz;
4064 let Inst{29-27} = 0b111;
4066 let Inst{25-24} = 0b00;
4067 let Inst{23-22} = opc;
4069 let Inst{20-16} = Rm;
4070 let Inst{15} = extend{1}; // sign extend Rm?
4072 let Inst{12} = extend{0}; // do shift?
4073 let Inst{11-10} = 0b10;
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]> {
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]> {
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]> {
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]> {
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> {
4135 let Inst{31-30} = sz;
4136 let Inst{29-27} = 0b111;
4138 let Inst{25-24} = 0b00;
4139 let Inst{23-22} = opc;
4141 let Inst{20-16} = Rm;
4142 let Inst{15} = extend{1}; // sign extend Rm?
4144 let Inst{12} = extend{0}; // do shift?
4145 let Inst{11-10} = 0b10;
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]> {
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]> {
4172 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
4175 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
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),
4181 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
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),
4189 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
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>,
4205 let Inst{31-30} = sz;
4206 let Inst{29-27} = 0b111;
4208 let Inst{25-24} = 0b00;
4209 let Inst{23-22} = opc;
4211 let Inst{20-16} = Rm;
4212 let Inst{15} = extend{1}; // sign extend Rm?
4214 let Inst{12} = extend{0}; // do shift?
4215 let Inst{11-10} = 0b10;
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))]> {
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))]> {
4242 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
4243 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
4244 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
4248 // Load/store unscaled immediate
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> {
4280 let Inst{31-30} = sz;
4281 let Inst{29-27} = 0b111;
4283 let Inst{25-24} = 0b00;
4284 let Inst{23-22} = opc;
4286 let Inst{20-12} = offset;
4287 let Inst{11-10} = 0b00;
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, []>,
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),
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>,
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),
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,
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),
4351 def : InstAlias<asm # "\t$Rt, [$Rn]",
4352 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
4356 // Load/store unscaled immediate, unprivileged
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]", "", []> {
4365 let Inst{31-30} = sz;
4366 let Inst{29-27} = 0b111;
4368 let Inst{25-24} = 0b00;
4369 let Inst{23-22} = opc;
4371 let Inst{20-12} = offset;
4372 let Inst{11-10} = 0b10;
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>,
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),
4398 def : InstAlias<asm # "\t$Rt, [$Rn]",
4399 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
4403 // Load/store pre-indexed
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> {
4412 let Inst{31-30} = sz;
4413 let Inst{29-27} = 0b111;
4415 let Inst{25-24} = 0;
4416 let Inst{23-22} = opc;
4418 let Inst{20-12} = offset;
4419 let Inst{11-10} = 0b11;
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,
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
4449 // Load/store post-indexed
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> {
4458 let Inst{31-30} = sz;
4459 let Inst{29-27} = 0b111;
4461 let Inst{25-24} = 0b00;
4462 let Inst{23-22} = opc;
4464 let Inst{20-12} = offset;
4465 let Inst{11-10} = 0b01;
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,
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
4499 // (indexed, offset)
4501 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
4503 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4508 let Inst{31-30} = opc;
4509 let Inst{29-27} = 0b101;
4511 let Inst{25-23} = 0b010;
4513 let Inst{21-15} = offset;
4514 let Inst{14-10} = Rt2;
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,
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),
4544 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4545 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4550 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4552 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
4557 let Inst{31-30} = opc;
4558 let Inst{29-27} = 0b101;
4560 let Inst{25-23} = 0b011;
4562 let Inst{21-15} = offset;
4563 let Inst{14-10} = Rt2;
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),
4586 Sched<[WriteAdr, WriteSTP]>;
4587 } // hasSideEffects = 0
4591 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4593 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
4598 let Inst{31-30} = opc;
4599 let Inst{29-27} = 0b101;
4601 let Inst{25-23} = 0b001;
4603 let Inst{21-15} = offset;
4604 let Inst{14-10} = Rt2;
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),
4627 Sched<[WriteAdr, WriteSTP]>;
4628 } // hasSideEffects = 0
4632 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
4634 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4639 let Inst{31-30} = opc;
4640 let Inst{29-27} = 0b101;
4642 let Inst{25-23} = 0b000;
4644 let Inst{21-15} = offset;
4645 let Inst{14-10} = Rt2;
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,
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),
4675 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4676 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4681 // Load/store exclusive
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;
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> {
4719 let Inst{20-16} = 0b11111;
4720 let Unpredictable{20-16} = 0b11111;
4721 let Inst{14-10} = 0b11111;
4722 let Unpredictable{14-10} = 0b11111;
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]">,
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]">,
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]> {
4753 let Inst{14-10} = Rt2;
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]">,
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]">,
4779 let Inst{20-16} = Ws;
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,
4791 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
4792 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
4798 let Inst{20-16} = Ws;
4799 let Inst{14-10} = Rt2;
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, []>,
4813 let Inst{31-24} = 0b11011001;
4814 let Inst{23-22} = opc1;
4816 // Inst{20-12} defined by subclass
4817 let Inst{11-10} = opc2;
4819 // Inst{4-0} defined by subclass
4822 class MemTagVector<bit Load, string asm_insn, string asm_opnds,
4824 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,
4828 let Inst{20-12} = 0b000000000;
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)> {
4841 let Inst{20-12} = offset;
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> {
4853 let Inst{20-12} = offset;
4859 multiclass MemTagStore<bits<2> opc1, string insn> {
4861 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",
4862 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4864 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",
4866 (outs GPR64sp:$wback),
4867 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4869 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",
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)>;
4879 // Exception generation
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>,
4888 let Inst{31-24} = 0b11010100;
4889 let Inst{23-21} = op1;
4890 let Inst{20-5} = imm;
4891 let Inst{4-2} = 0b000;
4896 // UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm.
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", "", []>,
4904 let Inst{31-16} = opc;
4905 let Inst{15-0} = imm;
4908 let Predicates = [HasFPARMv8] in {
4911 // Floating point to integer conversion
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]> {
4923 let Inst{30-29} = 0b00;
4924 let Inst{28-24} = 0b11110;
4925 let Inst{23-22} = type;
4927 let Inst{20-19} = rmode;
4928 let Inst{18-16} = opcode;
4929 let Inst{15-10} = 0;
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]> {
4944 let Inst{30-29} = 0b00;
4945 let Inst{28-24} = 0b11110;
4946 let Inst{23-22} = type;
4948 let Inst{20-19} = rmode;
4949 let Inst{18-16} = opcode;
4950 let Inst{15-10} = scale;
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];
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];
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
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
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
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
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
5005 let Predicates = [HasFullFP16];
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];
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
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
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
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
5053 // Integer to floating point conversion
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]> {
5066 let Inst{30-24} = 0b0011110;
5067 let Inst{21-17} = 0b00001;
5068 let Inst{16} = isUnsigned;
5069 let Inst{15-10} = scale;
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]> {
5084 let Inst{30-24} = 0b0011110;
5085 let Inst{21-17} = 0b10001;
5086 let Inst{16} = isUnsigned;
5087 let Inst{15-10} = 0b000000;
5092 multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> {
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];
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
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
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];
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
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
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
5134 let Predicates = [HasFullFP16];
5137 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_recip_f32_i32, asm,
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
5146 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_recip_f64_i32, asm,
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
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];
5164 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_recip_f32_i64, asm,
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
5172 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_recip_f64_i64, asm,
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
5182 // Unscaled integer <-> floating point conversion (i.e. FMOV)
5185 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5186 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
5187 RegisterClass srcType, RegisterClass dstType,
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]> {
5199 let Inst{30-24} = 0b0011110;
5201 let Inst{20-19} = rmode;
5202 let Inst{18-16} = opcode;
5203 let Inst{15-10} = 0b000000;
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,
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]> {
5217 let Inst{30-23} = 0b00111101;
5219 let Inst{20-19} = rmode;
5220 let Inst{18-16} = opcode;
5221 let Inst{15-10} = 0b000000;
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,
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]> {
5237 let Inst{30-23} = 0b00111101;
5239 let Inst{20-19} = rmode;
5240 let Inst{18-16} = opcode;
5241 let Inst{15-10} = 0b000000;
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];
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];
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
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
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];
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];
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
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
5294 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
5300 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
5308 // Floating point conversion
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]> {
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;
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))]>;
5354 // Single operand floating point data processing
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)))]>,
5365 let Inst{31-24} = 0b00011110;
5367 let Inst{20-15} = opcode;
5368 let Inst{14-10} = 0b10000;
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];
5382 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {
5383 let Inst{23-22} = 0b00; // 32-bit size flag
5386 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {
5387 let Inst{23-22} = 0b01; // 64-bit size flag
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
5404 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
5405 let Inst{23-22} = 0b01; // 64-bit registers
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>;
5414 // Two operand floating point data processing
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>,
5426 let Inst{31-24} = 0b00011110;
5428 let Inst{20-16} = Rm;
5429 let Inst{15-12} = opcode;
5430 let Inst{11-10} = 0b10;
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];
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
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
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];
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
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
5478 // Three operand floating point data processing
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]> {
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;
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];
5509 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
5511 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
5512 let Inst{23-22} = 0b00; // 32-bit size flag
5515 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
5517 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
5518 let Inst{23-22} = 0b01; // 64-bit size flag
5521 let Predicates = [HasFullFP16] in {
5522 def : Pat<(f16 (node (f16 FPR16:$Rn),
5523 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))),
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))),
5531 (!cast<Instruction>(NAME # Hrrr)
5532 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), FPR16:$Rm, FPR16:$Ra)>;
5535 def : Pat<(f32 (node (f32 FPR32:$Rn),
5536 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))),
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))),
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))),
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))),
5556 (!cast<Instruction>(NAME # Drrr)
5557 (EXTRACT_SUBREG V128:$Rn, dsub), FPR64:$Rm, FPR64:$Ra)>;
5561 // Floating point data comparisons
5564 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
5565 class BaseOneOperandFPComparison<bit signalAllNans,
5566 RegisterClass regtype, string asm,
5568 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
5569 Sched<[WriteFCmp]> {
5571 let Inst{31-24} = 0b00011110;
5574 let Inst{15-10} = 0b001000;
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]> {
5590 let Inst{31-24} = 0b00011110;
5592 let Inst{20-16} = Rm;
5593 let Inst{15-10} = 0b001000;
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];
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];
5614 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
5615 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
5616 let Inst{23-22} = 0b00;
5619 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
5620 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
5621 let Inst{23-22} = 0b00;
5624 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
5625 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
5626 let Inst{23-22} = 0b01;
5629 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
5630 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
5631 let Inst{23-22} = 0b01;
5637 // Floating point conditional comparisons
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]> {
5654 let Inst{31-24} = 0b00011110;
5656 let Inst{20-16} = Rm;
5657 let Inst{15-12} = cond;
5658 let Inst{11-10} = 0b01;
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];
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;
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;
5687 // Floating point conditional select
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", "",
5694 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
5695 (i32 imm:$cond), NZCV))]>,
5702 let Inst{31-24} = 0b00011110;
5704 let Inst{20-16} = Rm;
5705 let Inst{15-12} = cond;
5706 let Inst{11-10} = 0b11;
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];
5718 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
5719 let Inst{23-22} = 0b00;
5722 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
5723 let Inst{23-22} = 0b01;
5729 // Floating move immediate
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]> {
5738 let Inst{31-24} = 0b00011110;
5740 let Inst{20-13} = imm;
5741 let Inst{12-5} = 0b10000000;
5745 multiclass FPMoveImmediate<string asm> {
5746 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
5747 let Inst{23-22} = 0b11;
5748 let Predicates = [HasFullFP16];
5751 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
5752 let Inst{23-22} = 0b00;
5755 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
5756 let Inst{23-22} = 0b01;
5759 } // end of 'let Predicates = [HasFPARMv8]'
5761 //----------------------------------------------------------------------------
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,
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)]> {
5785 let Inst{28-24} = 0b01110;
5786 let Inst{23-21} = size;
5787 let Inst{20-16} = Rm;
5788 let Inst{15-11} = opcode;
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,
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)]> {
5808 let Inst{28-24} = 0b01110;
5809 let Inst{23-21} = size;
5810 let Inst{20-16} = Rm;
5811 let Inst{15-11} = opcode;
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),
5833 (!cast<Instruction>(NAME#"v8i8")
5834 V64:$LHS, V64:$MHS, V64:$RHS)>;
5835 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5837 (!cast<Instruction>(NAME#"v8i8")
5838 V64:$LHS, V64:$MHS, V64:$RHS)>;
5839 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
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,
5863 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5864 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5866 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5867 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5869 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5870 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5872 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5873 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5875 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5876 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5878 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5879 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
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,
5907 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
5908 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5910 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
5911 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5913 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
5914 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5916 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
5917 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5919 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
5920 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
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,
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,
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,
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,
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,
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,
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,
5958 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5959 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
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,
5972 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5973 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
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,
5979 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5980 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5982 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5983 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
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,
5991 SDPatternOperator OpNode> {
5992 let Predicates = [HasNEON, HasFullFP16] in {
5993 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5995 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5996 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
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,
6002 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
6003 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
6005 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
6006 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
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,
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,
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,
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,
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,
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,
6044 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6045 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
6047 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
6048 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
6050 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6051 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
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,
6061 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
6062 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
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,
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,
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),
6095 (!cast<Instruction>(NAME#"v8i8")
6096 V64:$LHS, V64:$MHS, V64:$RHS)>;
6097 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
6099 (!cast<Instruction>(NAME#"v8i8")
6100 V64:$LHS, V64:$MHS, V64:$RHS)>;
6101 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
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 # "}");
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<[]> {
6193 let Inst{28-24} = 0b01110;
6194 let Inst{23-22} = size;
6196 let Inst{20-16} = Rm;
6198 let Inst{14-11} = op;
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)]> {
6251 let Inst{28-24} = 0b01110;
6252 let Inst{23-22} = size;
6254 let Inst{20-19} = size2;
6255 let Inst{18-17} = 0b00;
6256 let Inst{16-12} = opcode;
6257 let Inst{11-10} = 0b10;
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,
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)]> {
6276 let Inst{28-24} = 0b01110;
6277 let Inst{23-22} = size;
6279 let Inst{20-19} = size2;
6280 let Inst{18-17} = 0b00;
6281 let Inst{16-12} = opcode;
6282 let Inst{11-10} = 0b10;
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,
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,
6298 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6299 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
6301 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6302 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
6304 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6305 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
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 # "}", "", []>,
6321 let Inst{29-24} = 0b101110;
6322 let Inst{23-22} = size;
6323 let Inst{21-10} = 0b100001001110;
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">;
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,
6350 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
6351 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
6353 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
6354 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
6356 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6357 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
6359 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6360 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
6362 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6363 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
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,
6372 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
6374 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
6376 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
6377 (v16i8 V128:$Rn)))]>;
6378 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
6380 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
6381 (v4i16 V64:$Rn)))]>;
6382 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
6384 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
6385 (v8i16 V128:$Rn)))]>;
6386 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
6388 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
6389 (v2i32 V64:$Rn)))]>;
6390 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
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,
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,
6407 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
6408 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
6410 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
6411 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
6413 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
6414 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
6416 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
6417 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
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,
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,
6432 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6433 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
6435 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6436 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
6438 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6439 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
6441 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6442 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
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,
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,
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,
6471 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
6472 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
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,
6486 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
6487 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6489 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
6490 } // Predicates = [HasNEON, HasFullFP16]
6491 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6493 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
6494 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6496 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
6497 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
6499 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
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,
6514 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
6515 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,
6517 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
6518 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,
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,
6532 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6533 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
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,
6544 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
6545 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6547 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
6548 } // Predicates = [HasNEON, HasFullFP16]
6549 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6551 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
6552 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6554 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
6555 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
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,
6566 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6567 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6569 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6570 } // Predicates = [HasNEON, HasFullFP16]
6571 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6573 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6574 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6576 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6577 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
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,
6587 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
6588 "{\t$Rd" # outkind # ", $Rn" # inkind #
6589 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
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;
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,
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>,
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;
6628 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
6629 SDPatternOperator OpNode> {
6630 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
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,
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,
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)]> {
6681 let Inst{28-24} = 0b01110;
6682 let Inst{23-22} = size;
6684 let Inst{20-19} = size2;
6685 let Inst{18-17} = 0b00;
6686 let Inst{16-12} = opcode;
6687 let Inst{11-10} = 0b10;
6692 // Comparisons support all element sizes, except 1xD.
6693 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
6695 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
6697 v8i8, v8i8, OpNode>;
6698 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
6700 v16i8, v16i8, OpNode>;
6701 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
6703 v4i16, v4i16, OpNode>;
6704 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
6706 v8i16, v8i16, OpNode>;
6707 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
6709 v2i32, v2i32, OpNode>;
6710 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
6712 v4i32, v4i32, OpNode>;
6713 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
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,
6726 v4i16, v4f16, OpNode>;
6727 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
6729 v8i16, v8f16, OpNode>;
6730 } // Predicates = [HasNEON, HasFullFP16]
6731 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
6733 v2i32, v2f32, OpNode>;
6734 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
6736 v4i32, v4f32, OpNode>;
6737 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
6739 v2i64, v2f64, OpNode>;
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>;
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>;
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,
6773 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
6774 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
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;
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,
6795 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
6796 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
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;
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,
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,
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>,
6865 let Inst{30} = size{0};
6867 let Inst{28-24} = 0b01110;
6868 let Inst{23-22} = size{2-1};
6870 let Inst{20-16} = Rm;
6871 let Inst{15-12} = opcode;
6872 let Inst{11-10} = 0b00;
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,
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>,
6891 let Inst{30} = size{0};
6893 let Inst{28-24} = 0b01110;
6894 let Inst{23-22} = size{2-1};
6896 let Inst{20-16} = Rm;
6897 let Inst{15-12} = opcode;
6898 let Inst{11-10} = 0b00;
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,
6909 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
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,
6915 asm#"2", ".16b", ".8h", ".8h",
6917 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
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,
6923 asm#"2", ".8h", ".4s", ".4s",
6925 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
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,
6931 asm#"2", ".4s", ".2d", ".2d",
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),
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),
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),
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,
6958 asm, ".8h", ".8b", ".8b",
6959 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6960 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6962 asm#"2", ".8h", ".16b", ".16b", []>;
6963 let Predicates = [HasAES] in {
6964 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
6966 asm, ".1q", ".1d", ".1d",
6967 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>;
6968 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
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))))]>;
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
7041 SDPatternOperator OpNode> {
7042 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
7116 SDPatternOperator OpNode> {
7117 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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)]> {
7235 let Inst{30} = size;
7236 let Inst{29-21} = 0b101110000;
7237 let Inst{20-16} = Rm;
7239 let Inst{14-11} = imm;
7246 multiclass SIMDBitwiseExtract<string asm> {
7247 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
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)]> {
7268 let Inst{30} = size{0};
7269 let Inst{29-24} = 0b001110;
7270 let Inst{23-22} = size{2-1};
7272 let Inst{20-16} = Rm;
7274 let Inst{14-12} = opc;
7275 let Inst{11-10} = 0b10;
7280 multiclass SIMDZipVector<bits<3>opc, string asm,
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,
7321 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
7322 "\t$Rd, $Rn, $Rm", "", pattern>,
7327 let Inst{31-30} = 0b01;
7329 let Inst{28-24} = 0b11110;
7330 let Inst{23-21} = size;
7331 let Inst{20-16} = Rm;
7332 let Inst{15-11} = opcode;
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,
7342 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
7347 let Inst{31-30} = 0b01;
7349 let Inst{28-24} = 0b11110;
7350 let Inst{23-22} = size;
7352 let Inst{20-16} = Rm;
7353 let Inst{15-11} = opcode;
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),
7390 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
7391 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
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))]>;
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)))]>;
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,
7425 } // Predicates = [HasNEON, HasFullFP16]
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>,
7440 let Inst{31-30} = 0b01;
7442 let Inst{28-24} = 0b11110;
7443 let Inst{23-22} = size;
7445 let Inst{20-16} = Rm;
7446 let Inst{15-11} = opcode;
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,
7457 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
7458 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
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,
7469 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
7470 asm, "$Rd = $dst", []>;
7471 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
7473 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
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>,
7492 let Inst{31-30} = 0b01;
7494 let Inst{28-24} = 0b11110;
7495 let Inst{23-22} = size;
7497 let Inst{20-19} = size2;
7498 let Inst{18-17} = 0b00;
7499 let Inst{16-12} = opcode;
7500 let Inst{11-10} = 0b10;
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>,
7514 let Inst{31-30} = 0b01;
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;
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, "", []>,
7534 let Inst{31-30} = 0b01;
7536 let Inst{28-24} = 0b11110;
7537 let Inst{23-22} = size;
7539 let Inst{20-19} = size2;
7540 let Inst{18-17} = 0b00;
7541 let Inst{16-12} = opcode;
7542 let Inst{11-10} = 0b10;
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)))]>,
7554 let Inst{31-17} = 0b011111100110000;
7555 let Inst{16-12} = opcode;
7556 let Inst{11-10} = 0b10;
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">;
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>;
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)>;
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,[]>;
7611 let Predicates = [pred, HasFullFP16] in {
7612 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
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)))]>;
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, []>;
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,
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, []>;
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}", "", []>,
7683 let Inst{31-30} = 0b01;
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;
7694 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
7695 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
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,
7705 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
7707 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
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)]> {
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;
7736 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
7738 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
7740 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
7742 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
7744 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
7746 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
7750 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
7751 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
7753 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
7755 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
7757 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
7759 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
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,
7769 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>;
7770 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
7772 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>;
7773 } // Predicates = [HasNEON, HasFullFP16]
7774 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
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)]> {
7794 let Inst{28-21} = 0b01110000;
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,
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> {
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> {
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> {
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> {
7854 let Inst{20-17} = idx;
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,
7868 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
7869 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
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)>;
7881 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)
7883 let Predicates = [HasNEONorSME] in {
7884 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> {
7885 let Inst{20-16} = 0b00001;
7887 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> {
7888 let Inst{20-16} = 0b00001;
7890 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> {
7891 let Inst{20-16} = 0b00010;
7893 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> {
7894 let Inst{20-16} = 0b00010;
7896 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> {
7897 let Inst{20-16} = 0b00100;
7900 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
7902 let Inst{20-17} = idx;
7905 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
7907 let Inst{20-17} = idx;
7910 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
7912 let Inst{20-18} = idx;
7913 let Inst{17-16} = 0b10;
7915 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
7917 let Inst{20-18} = idx;
7918 let Inst{17-16} = 0b10;
7920 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
7922 let Inst{20-19} = idx;
7923 let Inst{18-16} = 0b100;
7928 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)
7930 let Predicates = [HasNEONorSME] in {
7931 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> {
7932 let Inst{20-16} = 0b00001;
7934 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> {
7935 let Inst{20-16} = 0b00010;
7937 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> {
7938 let Inst{20-16} = 0b00100;
7940 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> {
7941 let Inst{20-16} = 0b01000;
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>;
7950 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
7952 let Inst{20-17} = idx;
7955 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
7957 let Inst{20-18} = idx;
7958 let Inst{17-16} = 0b10;
7960 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
7962 let Inst{20-19} = idx;
7963 let Inst{18-16} = 0b100;
7965 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
7968 let Inst{19-16} = 0b1000;
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}",
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}",
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,
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> {
8018 let Inst{20-17} = idx;
8021 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
8023 let Inst{20-18} = idx;
8024 let Inst{17-16} = 0b10;
8026 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
8028 let Inst{20-19} = idx;
8029 let Inst{18-16} = 0b100;
8031 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
8034 let Inst{19-16} = 0b1000;
8037 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
8040 let Inst{20-17} = idx;
8042 let Inst{14-11} = idx2;
8044 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
8047 let Inst{20-18} = idx;
8048 let Inst{17-16} = 0b10;
8049 let Inst{14-12} = idx2;
8052 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
8055 let Inst{20-19} = idx;
8056 let Inst{18-16} = 0b100;
8057 let Inst{14-13} = idx2;
8058 let Inst{12-11} = {?,?};
8060 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
8064 let Inst{19-16} = 0b1000;
8065 let Inst{14} = idx2;
8066 let Inst{13-11} = {?,?,?};
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"),
8083 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
8085 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
8087 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
8091 //----------------------------------------------------------------------------
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)]> {
8106 let Inst{29-21} = 0b001110000;
8107 let Inst{20-16} = Vm;
8109 let Inst{14-13} = len;
8111 let Inst{11-10} = 0b00;
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)]> {
8127 let Inst{29-21} = 0b001110000;
8128 let Inst{20-16} = Vm;
8130 let Inst{14-13} = len;
8132 let Inst{11-10} = 0b00;
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,
8145 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
8147 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
8149 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
8151 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
8153 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
8155 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
8157 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
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,
8189 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
8191 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
8193 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
8195 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
8197 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
8199 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
8201 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
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 //----------------------------------------------------------------------------
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", "", []>,
8246 let Inst{29-24} = 0b001110;
8247 let Inst{23-22} = opc{4-3};
8249 let Inst{20-16} = Rm;
8251 let Inst{14-12} = opc{2-0};
8252 let Inst{11-10} = 0b00;
8257 multiclass BaseSIMDTableLookupIndexed2<string asm> {
8258 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b10,?,?,0b1}, V128, VecListOne16b, VectorIndexS, asm, ".16b"> {
8260 let Inst{14-13} = idx;
8262 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b11,?,?,?}, V128, VecListOne8h, VectorIndexH, asm, ".8h" > {
8264 let Inst{14-12} = idx;
8268 multiclass BaseSIMDTableLookupIndexed4<string asm> {
8269 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,0b10}, V128, VecListOne16b, VectorIndexD, asm, ".16b"> {
8273 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,?,0b1}, V128, VecListTwo8h, VectorIndexS, asm, ".8h" > {
8275 let Inst{14-13} = idx;
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}", "", []>,
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> {
8307 let Inst{20-17} = idx;
8310 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> {
8312 let Inst{20-18} = idx;
8313 let Inst{17-16} = 0b10;
8315 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> {
8317 let Inst{20-19} = idx;
8318 let Inst{18-16} = 0b100;
8320 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> {
8323 let Inst{19-16} = 0b1000;
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)]> {
8359 let Inst{28-19} = 0b0111100000;
8360 let Inst{18-16} = imm8{7-5};
8363 let Inst{9-5} = imm8{4-0};
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,
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 # "}",
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,
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> {
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> {
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> {
8423 let Inst{15} = b15_b12{1};
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> {
8436 let Inst{15} = b15_b12{1};
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,
8444 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
8446 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
8449 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
8451 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
8455 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
8456 bits<2> w_cmode, string asm,
8458 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
8460 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
8462 (i32 imm:$shift)))]>;
8463 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
8465 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
8467 (i32 imm:$shift)))]>;
8469 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
8471 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
8473 (i32 imm:$shift)))]>;
8474 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
8476 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
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> {
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,
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),
8521 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
8522 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
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.
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>,
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.
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,
8594 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,
8598 class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
8599 string dst_kind, string lhs_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)))))))]> {
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),
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),
8646 (AArch64duplane16 (v8bf16 V128_lo:$Rm),
8647 VectorIndexH:$idx)))))]>,
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
8666 class SIMDThreeSameVectorBF16MatrixMul<string asm>
8667 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101,
8669 [(set (v4f32 V128:$dst),
8670 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd),
8672 (v8bf16 V128:$Rm)))]> {
8673 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h",
8674 ", $Rm", ".8h", "}");
8677 let mayRaiseFPException = 1, Uses = [FPCR] in
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
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]> {
8698 let Inst{31-10} = 0b0001111001100011010000;
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", []> {
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",
8724 multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm> {
8725 def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s",
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),
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)))))))]> {
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)))))]> {
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,
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)))]> {
8828 let Inst{11} = idx{2};
8829 let Inst{21} = idx{1};
8830 let Inst{20} = idx{0};
8833 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
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))))]> {
8841 let Inst{11} = idx{2};
8842 let Inst{21} = idx{1};
8843 let Inst{20} = idx{0};
8845 } // Predicates = [HasNEON, HasFullFP16]
8847 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8850 asm, ".2s", ".2s", ".2s", ".s",
8851 [(set (v2f32 V64:$Rd),
8852 (OpNode (v2f32 V64:$Rn),
8853 (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> {
8855 let Inst{11} = idx{1};
8856 let Inst{21} = idx{0};
8859 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8862 asm, ".4s", ".4s", ".4s", ".s",
8863 [(set (v4f32 V128:$Rd),
8864 (OpNode (v4f32 V128:$Rn),
8865 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8867 let Inst{11} = idx{1};
8868 let Inst{21} = idx{0};
8871 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
8874 asm, ".2d", ".2d", ".2d", ".d",
8875 [(set (v2f64 V128:$Rd),
8876 (OpNode (v2f64 V128:$Rn),
8877 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
8879 let Inst{11} = idx{0};
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))))]> {
8892 let Inst{11} = idx{2};
8893 let Inst{21} = idx{1};
8894 let Inst{20} = idx{0};
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))))]> {
8906 let Inst{11} = idx{1};
8907 let Inst{21} = idx{0};
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))))]> {
8918 let Inst{11} = idx{0};
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)>;
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)>;
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", []> {
9029 let Inst{11} = idx{2};
9030 let Inst{21} = idx{1};
9031 let Inst{20} = idx{0};
9034 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
9036 V128_lo, VectorIndexH,
9037 asm, ".8h", ".8h", ".8h", ".h", []> {
9039 let Inst{11} = idx{2};
9040 let Inst{21} = idx{1};
9041 let Inst{20} = idx{0};
9043 } // Predicates = [HasNEON, HasFullFP16]
9045 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
9047 asm, ".2s", ".2s", ".2s", ".s", []> {
9049 let Inst{11} = idx{1};
9050 let Inst{21} = idx{0};
9053 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9056 asm, ".4s", ".4s", ".4s", ".s", []> {
9058 let Inst{11} = idx{1};
9059 let Inst{21} = idx{0};
9062 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
9065 asm, ".2d", ".2d", ".2d", ".d", []> {
9067 let Inst{11} = idx{0};
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", []> {
9076 let Inst{11} = idx{2};
9077 let Inst{21} = idx{1};
9078 let Inst{20} = idx{0};
9080 } // Predicates = [HasNEON, HasFullFP16]
9082 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9083 FPR32Op, FPR32Op, V128, VectorIndexS,
9084 asm, ".s", "", "", ".s", []> {
9086 let Inst{11} = idx{1};
9087 let Inst{21} = idx{0};
9090 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
9091 FPR64Op, FPR64Op, V128, VectorIndexD,
9092 asm, ".d", "", "", ".d", []> {
9094 let Inst{11} = idx{0};
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
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)))]> {
9166 let Inst{11} = idx{2};
9167 let Inst{21} = idx{1};
9168 let Inst{20} = idx{0};
9171 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
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))))]> {
9179 let Inst{11} = idx{2};
9180 let Inst{21} = idx{1};
9181 let Inst{20} = idx{0};
9184 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9187 asm, ".2s", ".2s", ".2s", ".s",
9188 [(set (v2i32 V64:$Rd),
9189 (OpNode (v2i32 V64:$Rn),
9190 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9192 let Inst{11} = idx{1};
9193 let Inst{21} = idx{0};
9196 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
9199 asm, ".4s", ".4s", ".4s", ".s",
9200 [(set (v4i32 V128:$Rd),
9201 (OpNode (v4i32 V128:$Rn),
9202 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
9204 let Inst{11} = idx{1};
9205 let Inst{21} = idx{0};
9208 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
9209 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
9210 asm, ".h", "", "", ".h", []> {
9212 let Inst{11} = idx{2};
9213 let Inst{21} = idx{1};
9214 let Inst{20} = idx{0};
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))))]> {
9225 let Inst{11} = idx{1};
9226 let Inst{21} = idx{0};
9230 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
9231 SDPatternOperator OpNode> {
9232 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
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)))]> {
9240 let Inst{11} = idx{2};
9241 let Inst{21} = idx{1};
9242 let Inst{20} = idx{0};
9245 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
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))))]> {
9253 let Inst{11} = idx{2};
9254 let Inst{21} = idx{1};
9255 let Inst{20} = idx{0};
9258 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9261 asm, ".2s", ".2s", ".2s", ".s",
9262 [(set (v2i32 V64:$Rd),
9263 (OpNode (v2i32 V64:$Rn),
9264 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9266 let Inst{11} = idx{1};
9267 let Inst{21} = idx{0};
9270 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
9273 asm, ".4s", ".4s", ".4s", ".s",
9274 [(set (v4i32 V128:$Rd),
9275 (OpNode (v4i32 V128:$Rn),
9276 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
9278 let Inst{11} = idx{1};
9279 let Inst{21} = idx{0};
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)))]> {
9292 let Inst{11} = idx{2};
9293 let Inst{21} = idx{1};
9294 let Inst{20} = idx{0};
9297 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
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))))]> {
9305 let Inst{11} = idx{2};
9306 let Inst{21} = idx{1};
9307 let Inst{20} = idx{0};
9310 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
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)))]> {
9318 let Inst{11} = idx{1};
9319 let Inst{21} = idx{0};
9322 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
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))))]> {
9330 let Inst{11} = idx{1};
9331 let Inst{21} = idx{0};
9335 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
9336 SDPatternOperator OpNode> {
9337 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
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)))]> {
9345 let Inst{11} = idx{2};
9346 let Inst{21} = idx{1};
9347 let Inst{20} = idx{0};
9350 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
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)))]> {
9359 let Inst{11} = idx{2};
9360 let Inst{21} = idx{1};
9361 let Inst{20} = idx{0};
9364 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9367 asm, ".2d", ".2d", ".2s", ".s",
9368 [(set (v2i64 V128:$Rd),
9369 (OpNode (v2i32 V64:$Rn),
9370 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9372 let Inst{11} = idx{1};
9373 let Inst{21} = idx{0};
9376 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
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)))]> {
9384 let Inst{11} = idx{1};
9385 let Inst{21} = idx{0};
9388 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
9389 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
9390 asm, ".h", "", "", ".h", []> {
9392 let Inst{11} = idx{2};
9393 let Inst{21} = idx{1};
9394 let Inst{20} = idx{0};
9397 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
9398 FPR64Op, FPR32Op, V128, VectorIndexS,
9399 asm, ".s", "", "", ".s", []> {
9401 let Inst{11} = idx{1};
9402 let Inst{21} = idx{0};
9406 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
9407 SDPatternOperator Accum> {
9408 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
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
9416 (dup_v8i16 (v8i16 V128_lo:$Rm),
9417 VectorIndexH:$idx)))))]> {
9419 let Inst{11} = idx{2};
9420 let Inst{21} = idx{1};
9421 let Inst{20} = idx{0};
9424 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
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)))))]> {
9434 let Inst{11} = idx{2};
9435 let Inst{21} = idx{1};
9436 let Inst{20} = idx{0};
9439 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9442 asm, ".2d", ".2d", ".2s", ".s",
9443 [(set (v2i64 V128:$dst),
9444 (Accum (v2i64 V128:$Rd),
9445 (v2i64 (int_aarch64_neon_sqdmull
9447 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> {
9449 let Inst{11} = idx{1};
9450 let Inst{21} = idx{0};
9453 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
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)))))]> {
9463 let Inst{11} = idx{1};
9464 let Inst{21} = idx{0};
9467 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9468 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
9469 asm, ".h", "", "", ".h", []> {
9471 let Inst{11} = idx{2};
9472 let Inst{21} = idx{1};
9473 let Inst{20} = idx{0};
9476 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9477 (i32 (vector_extract
9478 (v4i32 (int_aarch64_neon_sqdmull
9482 (!cast<Instruction>(NAME # v1i32_indexed)
9484 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)),
9485 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub),
9488 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9489 (i32 (vector_extract
9490 (v4i32 (int_aarch64_neon_sqdmull
9492 (dup_v8i16 (v8i16 V128_lo:$Rm),
9493 VectorIndexH:$idx))),
9495 (!cast<Instruction>(NAME # v1i32_indexed)
9497 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)),
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
9508 (i32 (vector_extract (v4i32 V128:$Rm),
9509 VectorIndexS:$idx))))))]> {
9512 let Inst{11} = idx{1};
9513 let Inst{21} = idx{0};
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,
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)))]> {
9528 let Inst{11} = idx{2};
9529 let Inst{21} = idx{1};
9530 let Inst{20} = idx{0};
9533 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
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)))]> {
9542 let Inst{11} = idx{2};
9543 let Inst{21} = idx{1};
9544 let Inst{20} = idx{0};
9547 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
9550 asm, ".2d", ".2d", ".2s", ".s",
9551 [(set (v2i64 V128:$Rd),
9552 (OpNode (v2i32 V64:$Rn),
9553 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {
9555 let Inst{11} = idx{1};
9556 let Inst{21} = idx{0};
9559 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
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)))]> {
9567 let Inst{11} = idx{1};
9568 let Inst{21} = idx{0};
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,
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)))]> {
9584 let Inst{11} = idx{2};
9585 let Inst{21} = idx{1};
9586 let Inst{20} = idx{0};
9589 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
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)))]> {
9598 let Inst{11} = idx{2};
9599 let Inst{21} = idx{1};
9600 let Inst{20} = idx{0};
9603 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
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)))]> {
9611 let Inst{11} = idx{1};
9612 let Inst{21} = idx{0};
9615 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
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)))]> {
9624 let Inst{11} = idx{1};
9625 let Inst{21} = idx{0};
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>,
9644 let Inst{31-30} = 0b01;
9646 let Inst{28-23} = 0b111110;
9647 let Inst{22-16} = fixed_imm;
9648 let Inst{15-11} = opc;
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>,
9664 let Inst{31-30} = 0b01;
9666 let Inst{28-23} = 0b111110;
9667 let Inst{22-16} = fixed_imm;
9668 let Inst{15-11} = opc;
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};
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};
9686 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9687 FPR64, FPR64, vecshiftR64, asm, []> {
9688 let Inst{21-16} = imm{5-0};
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};
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};
9714 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
9715 (i32 vecshiftR64:$imm))),
9716 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
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};
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};
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};
9749 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9750 FPR16, FPR32, vecshiftR16, asm, []> {
9751 let Inst{19-16} = imm{3-0};
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};
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};
9768 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9769 FPR16, FPR16, vecshiftL16, asm, []> {
9770 let Inst{19-16} = imm{3-0};
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};
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};
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};
9795 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9796 FPR16, FPR16, vecshiftR16, asm, []> {
9797 let Inst{19-16} = imm{3-0};
9800 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9801 FPR32, FPR32, vecshiftR32, asm, []> {
9802 let Inst{20-16} = imm{4-0};
9805 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9806 FPR64, FPR64, vecshiftR64, asm, []> {
9807 let Inst{21-16} = imm{5-0};
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,
9819 string asm, string dst_kind, string src_kind,
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)]> {
9830 let Inst{28-23} = 0b011110;
9831 let Inst{22-16} = fixed_imm;
9832 let Inst{15-11} = opc;
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,
9842 string asm, string dst_kind, string src_kind,
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)]> {
9853 let Inst{28-23} = 0b011110;
9854 let Inst{22-16} = fixed_imm;
9855 let Inst{15-11} = opc;
9861 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
9863 let Predicates = [HasNEON, HasFullFP16] in {
9864 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9865 V64, V64, vecshiftR16,
9867 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
9869 let Inst{19-16} = imm;
9872 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9873 V128, V128, vecshiftR16,
9875 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
9877 let Inst{19-16} = imm;
9879 } // Predicates = [HasNEON, HasFullFP16]
9880 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9881 V64, V64, vecshiftR32,
9883 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
9885 let Inst{20-16} = imm;
9888 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9889 V128, V128, vecshiftR32,
9891 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
9893 let Inst{20-16} = imm;
9896 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9897 V128, V128, vecshiftR64,
9899 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
9901 let Inst{21-16} = imm;
9905 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
9907 let Predicates = [HasNEON, HasFullFP16] in {
9908 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9909 V64, V64, vecshiftR16,
9911 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
9913 let Inst{19-16} = imm;
9916 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9917 V128, V128, vecshiftR16,
9919 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
9921 let Inst{19-16} = imm;
9923 } // Predicates = [HasNEON, HasFullFP16]
9925 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9926 V64, V64, vecshiftR32,
9928 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
9930 let Inst{20-16} = imm;
9933 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9934 V128, V128, vecshiftR32,
9936 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
9938 let Inst{20-16} = imm;
9941 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9942 V128, V128, vecshiftR64,
9944 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
9946 let Inst{21-16} = imm;
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,
9955 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
9957 let Inst{18-16} = imm;
9960 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9961 V128, V128, vecshiftR16Narrow,
9962 asm#"2", ".16b", ".8h", []> {
9964 let Inst{18-16} = imm;
9965 let hasSideEffects = 0;
9968 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9969 V64, V128, vecshiftR32Narrow,
9971 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
9973 let Inst{19-16} = imm;
9976 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9977 V128, V128, vecshiftR32Narrow,
9978 asm#"2", ".8h", ".4s", []> {
9980 let Inst{19-16} = imm;
9981 let hasSideEffects = 0;
9984 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9985 V64, V128, vecshiftR64Narrow,
9987 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
9989 let Inst{20-16} = imm;
9992 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9993 V128, V128, vecshiftR64Narrow,
9994 asm#"2", ".4s", ".2d", []> {
9996 let Inst{20-16} = imm;
9997 let hasSideEffects = 0;
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,
10027 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
10028 (i32 vecshiftL8:$imm)))]> {
10030 let Inst{18-16} = imm;
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)))]> {
10039 let Inst{18-16} = imm;
10042 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
10043 V64, V64, vecshiftL16,
10045 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
10046 (i32 vecshiftL16:$imm)))]> {
10048 let Inst{19-16} = imm;
10051 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
10052 V128, V128, vecshiftL16,
10054 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
10055 (i32 vecshiftL16:$imm)))]> {
10057 let Inst{19-16} = imm;
10060 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
10061 V64, V64, vecshiftL32,
10063 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
10064 (i32 vecshiftL32:$imm)))]> {
10066 let Inst{20-16} = imm;
10069 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
10070 V128, V128, vecshiftL32,
10072 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
10073 (i32 vecshiftL32:$imm)))]> {
10075 let Inst{20-16} = imm;
10078 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
10079 V128, V128, vecshiftL64,
10081 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
10082 (i32 vecshiftL64:$imm)))]> {
10084 let Inst{21-16} = imm;
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,
10093 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
10094 (i32 vecshiftR8:$imm)))]> {
10096 let Inst{18-16} = imm;
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)))]> {
10105 let Inst{18-16} = imm;
10108 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
10109 V64, V64, vecshiftR16,
10111 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
10112 (i32 vecshiftR16:$imm)))]> {
10114 let Inst{19-16} = imm;
10117 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
10118 V128, V128, vecshiftR16,
10120 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
10121 (i32 vecshiftR16:$imm)))]> {
10123 let Inst{19-16} = imm;
10126 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
10127 V64, V64, vecshiftR32,
10129 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
10130 (i32 vecshiftR32:$imm)))]> {
10132 let Inst{20-16} = imm;
10135 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
10136 V128, V128, vecshiftR32,
10138 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
10139 (i32 vecshiftR32:$imm)))]> {
10141 let Inst{20-16} = imm;
10144 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
10145 V128, V128, vecshiftR64,
10147 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
10148 (i32 vecshiftR64:$imm)))]> {
10150 let Inst{21-16} = imm;
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)))]> {
10163 let Inst{18-16} = imm;
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)))]> {
10172 let Inst{18-16} = imm;
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)))]> {
10181 let Inst{19-16} = imm;
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)))]> {
10190 let Inst{19-16} = imm;
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)))]> {
10199 let Inst{20-16} = imm;
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)))]> {
10208 let Inst{20-16} = imm;
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)))]> {
10217 let Inst{21-16} = imm;
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,
10226 [(set (v8i8 V64:$dst),
10227 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
10228 (i32 vecshiftL8:$imm)))]> {
10230 let Inst{18-16} = imm;
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)))]> {
10240 let Inst{18-16} = imm;
10243 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
10244 V64, V64, vecshiftL16,
10246 [(set (v4i16 V64:$dst),
10247 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
10248 (i32 vecshiftL16:$imm)))]> {
10250 let Inst{19-16} = imm;
10253 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
10254 V128, V128, vecshiftL16,
10256 [(set (v8i16 V128:$dst),
10257 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
10258 (i32 vecshiftL16:$imm)))]> {
10260 let Inst{19-16} = imm;
10263 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
10264 V64, V64, vecshiftL32,
10266 [(set (v2i32 V64:$dst),
10267 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
10268 (i32 vecshiftL32:$imm)))]> {
10270 let Inst{20-16} = imm;
10273 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
10274 V128, V128, vecshiftL32,
10276 [(set (v4i32 V128:$dst),
10277 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
10278 (i32 vecshiftL32:$imm)))]> {
10280 let Inst{20-16} = imm;
10283 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
10284 V128, V128, vecshiftL64,
10286 [(set (v2i64 V128:$dst),
10287 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
10288 (i32 vecshiftL64:$imm)))]> {
10290 let Inst{21-16} = imm;
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))]> {
10300 let Inst{18-16} = imm;
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))]> {
10309 let Inst{18-16} = imm;
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))]> {
10316 let Inst{19-16} = imm;
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))]> {
10326 let Inst{19-16} = imm;
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))]> {
10333 let Inst{20-16} = imm;
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))]> {
10342 let Inst{20-16} = imm;
10348 // Vector load/store
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> {
10362 let Inst{29-23} = 0b0011000;
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", []> {
10379 let Inst{29-23} = 0b0011001;
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")
10400 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
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")
10410 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
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,
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")
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),
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),
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),
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),
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),
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),
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),
10493 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
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,
10512 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
10513 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
10515 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
10516 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
10518 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
10519 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
10521 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
10522 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
10524 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
10525 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
10527 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
10528 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
10531 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
10532 (outs GPR64sp:$wback),
10533 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
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,
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,
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,
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,
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,
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,
10565 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
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),
10591 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
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,
10607 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
10608 (outs GPR64sp:$wback),
10609 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
10611 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
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>;
10656 // AdvSIMD Load/store single-element
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> {
10666 let Inst{29-24} = 0b001101;
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> {
10681 let Inst{29-24} = 0b001101;
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),
10698 let Inst{20-16} = 0b00000;
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",
10707 (outs GPR64sp:$wback, listtype:$Vt),
10708 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
10712 let Inst{20-16} = Xm;
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")
10726 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
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")
10736 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
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,
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")
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,
10817 // idx encoded in Q:S:size fields.
10819 let Inst{30} = idx{3};
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.
10831 let Inst{30} = idx{3};
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.
10844 let Inst{30} = idx{3};
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.
10857 let Inst{30} = idx{3};
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,
10868 // idx encoded in Q:S:size<1> fields.
10870 let Inst{30} = idx{2};
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.
10883 let Inst{30} = idx{2};
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.
10898 let Inst{30} = idx{2};
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.
10912 let Inst{30} = idx{2};
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,
10923 // idx encoded in Q:S fields.
10925 let Inst{30} = idx{1};
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.
10937 let Inst{30} = idx{1};
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.
10950 let Inst{30} = idx{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.
10963 let Inst{30} = idx{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,
10973 // idx encoded in Q field.
10975 let Inst{30} = idx;
10977 let Inst{20-16} = 0b00000;
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.
10987 let Inst{30} = idx;
10989 let Inst{20-16} = 0b00000;
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.
11000 let Inst{30} = idx;
11002 let Inst{20-16} = Xm;
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.
11013 let Inst{30} = idx;
11015 let Inst{20-16} = Xm;
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,
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,
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,
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,
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,
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,
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,
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,
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")
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")
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")
11162 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
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,
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))))]> {
11234 let Inst{11} = idx{2};
11235 let Inst{21} = idx{1};
11236 let Inst{20} = idx{0};
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)))))]> {
11247 let Inst{11} = idx{2};
11248 let Inst{21} = idx{1};
11249 let Inst{20} = idx{0};
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))))]> {
11259 let Inst{11} = idx{1};
11260 let Inst{21} = idx{0};
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)))))]> {
11271 let Inst{11} = idx{1};
11272 let Inst{21} = idx{0};
11275 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
11276 FPR16Op, FPR16Op, V128_lo,
11277 VectorIndexH, asm, ".h", "", "", ".h",
11280 let Inst{11} = idx{2};
11281 let Inst{21} = idx{1};
11282 let Inst{20} = idx{0};
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)))))]> {
11293 let Inst{11} = idx{1};
11294 let Inst{21} = idx{0};
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);
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);
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)]> {
11338 let Inst{28-24} = 0b01110;
11339 let Inst{23-22} = size;
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;
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,
11357 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
11360 (i32 rottype:$rot)))]>;
11362 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
11364 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
11367 (i32 rottype:$rot)))]>;
11370 let Predicates = [HasComplxNum, HasNEON] in {
11371 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
11373 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
11376 (i32 rottype:$rot)))]>;
11378 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
11380 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
11383 (i32 rottype:$rot)))]>;
11385 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
11387 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
11390 (i32 rottype:$rot)))]>;
11394 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
11395 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
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)]> {
11412 let Inst{28-24} = 0b01110;
11413 let Inst{23-22} = size;
11415 let Inst{20-16} = Rm;
11416 let Inst{15-13} = opcode;
11417 let Inst{12-11} = rot;
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),
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),
11439 (i32 rottype:$rot)))]>;
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),
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),
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),
11462 (i32 rottype:$rot)))]>;
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),
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)]> {
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.
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
11506 multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype,
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",
11514 let Inst{21} = idx{0};
11517 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
11518 V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
11519 ".8h", ".8h", ".h", []> {
11521 let Inst{11} = idx{1};
11522 let Inst{21} = idx{0};
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", []> {
11531 let Inst{11} = idx{0};
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,
11544 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
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),
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>,
11575 let Inst{31-21} = 0b01011110000;
11576 let Inst{20-16} = Rm;
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,
11609 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
11610 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
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,
11634 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> {
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, []> {
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,
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}", "", []> {
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", []> {
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:
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> {
11772 let Inst{31-30} = Sz;
11773 let Inst{29-24} = 0b001000;
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]",
11789 Sched<[WriteAtomic]> {
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]",
11804 Sched<[WriteAtomic]> {
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]> {
11824 bits<3> opc = 0b000;
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]> {
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,
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",
11923 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
11924 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
11926 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11927 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
11929 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11930 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
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 */ {
11996 let Inst{31-21} = 0b11111000001;
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> {
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", []>,
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";
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,
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", []>,
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";
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 //----------------------------------------------------------------------------
12141 // 2022 Architecture Extensions: General Data Processing (FEAT_CSSC)
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))]> {
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>,
12169 let Inst{11} = isMin;
12170 let Inst{10} = isUnsigned;
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,
12182 let Inst{19} = isMin;
12183 let Inst{18} = isUnsigned;
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>;
12205 // RCPC instructions (FEAT_LRCPC3)
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]> {
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;
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> {
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;
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, []>,
12262 let Inst{20-16} = 0b00001;
12263 let Inst{12} = 0; // S
12264 let Inst{11-10} = 0b01; // size
12267 let mayStore = !not(L);
12268 let hasSideEffects = 1;
12272 // Instrumentation Extension (FEAT_ITE)
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;
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", []>,
12313 let Inst{31} = 0b0;
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;
12327 let hasSideEffects = 1;
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),
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),
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]", "", []>,
12398 let Inst{31} = 0b0;
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;
12412 let hasSideEffects = 1;
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", []>,
12429 let Inst{31} = 0b0;
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;
12443 let hasSideEffects = 1;
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 >;
12466 // 128-bit atomic instructions (FEAT_LSE128)
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", []>,
12479 let Inst{31-24} = 0b00011001;
12480 let Inst{23-22} = AR;
12481 let Inst{21} = 0b1;
12482 let Inst{20-16} = Rt2;
12484 let Inst{14-12} = op0;
12485 let Inst{11-10} = 0b00;
12486 let Inst{9-5} = Rn;
12487 let Inst{4-0} = Rt;
12491 // 128-bit System Instructions (FEAT_SYSINSTR128)
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> {
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 //----------------------------------------------------------------------------
12529 // Checked Pointer Arithmetic (FEAT_CPA)
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<[]> {
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">;