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>;
40 class FalseLanesEnum<bits<2> val> {
43 def FalseLanesNone : FalseLanesEnum<0>;
44 def FalseLanesZero : FalseLanesEnum<1>;
45 def FalseLanesUndef : FalseLanesEnum<2>;
47 // AArch64 Instruction Format
48 class AArch64Inst<Format f, string cstr> : Instruction {
49 field bits<32> Inst; // Instruction encoding.
50 // Mask of bits that cause an encoding to be UNPREDICTABLE.
51 // If a bit is set, then if the corresponding bit in the
52 // target encoding differs from its value in the "Inst" field,
53 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
54 field bits<32> Unpredictable = 0;
55 // SoftFail is the generic name for this field, but we alias it so
56 // as to make it more obvious what it means in ARM-land.
57 field bits<32> SoftFail = Unpredictable;
58 let Namespace = "AArch64";
60 bits<2> Form = F.Value;
63 FalseLanesEnum FalseLanes = FalseLanesNone;
64 DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
65 ElementSizeEnum ElementSize = ElementSizeNone;
67 let TSFlags{8-7} = FalseLanes.Value;
68 let TSFlags{6-3} = DestructiveInstType.Value;
69 let TSFlags{2-0} = ElementSize.Value;
72 let Constraints = cstr;
75 class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
76 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
78 // Pseudo instructions (don't have encoding information)
79 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
80 : AArch64Inst<PseudoFrm, cstr> {
81 dag OutOperandList = oops;
82 dag InOperandList = iops;
83 let Pattern = pattern;
84 let isCodeGenOnly = 1;
88 // Real instructions (have encoding information)
89 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
90 let Pattern = pattern;
94 // Normal instructions
95 class I<dag oops, dag iops, string asm, string operands, string cstr,
97 : EncodedI<cstr, pattern> {
98 dag OutOperandList = oops;
99 dag InOperandList = iops;
100 let AsmString = !strconcat(asm, operands);
103 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
104 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
105 class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;
107 // Helper fragment for an extract of the high portion of a 128-bit vector.
108 def extract_high_v16i8 :
109 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
110 def extract_high_v8i16 :
111 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
112 def extract_high_v4i32 :
113 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
114 def extract_high_v2i64 :
115 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
117 //===----------------------------------------------------------------------===//
118 // Asm Operand Classes.
121 // Shifter operand for arithmetic shifted encodings.
122 def ShifterOperand : AsmOperandClass {
123 let Name = "Shifter";
126 // Shifter operand for mov immediate encodings.
127 def MovImm32ShifterOperand : AsmOperandClass {
128 let SuperClasses = [ShifterOperand];
129 let Name = "MovImm32Shifter";
130 let RenderMethod = "addShifterOperands";
131 let DiagnosticType = "InvalidMovImm32Shift";
133 def MovImm64ShifterOperand : AsmOperandClass {
134 let SuperClasses = [ShifterOperand];
135 let Name = "MovImm64Shifter";
136 let RenderMethod = "addShifterOperands";
137 let DiagnosticType = "InvalidMovImm64Shift";
140 // Shifter operand for arithmetic register shifted encodings.
141 class ArithmeticShifterOperand<int width> : AsmOperandClass {
142 let SuperClasses = [ShifterOperand];
143 let Name = "ArithmeticShifter" # width;
144 let PredicateMethod = "isArithmeticShifter<" # width # ">";
145 let RenderMethod = "addShifterOperands";
146 let DiagnosticType = "AddSubRegShift" # width;
149 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
150 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
152 // Shifter operand for logical register shifted encodings.
153 class LogicalShifterOperand<int width> : AsmOperandClass {
154 let SuperClasses = [ShifterOperand];
155 let Name = "LogicalShifter" # width;
156 let PredicateMethod = "isLogicalShifter<" # width # ">";
157 let RenderMethod = "addShifterOperands";
158 let DiagnosticType = "AddSubRegShift" # width;
161 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
162 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
164 // Shifter operand for logical vector 128/64-bit shifted encodings.
165 def LogicalVecShifterOperand : AsmOperandClass {
166 let SuperClasses = [ShifterOperand];
167 let Name = "LogicalVecShifter";
168 let RenderMethod = "addShifterOperands";
170 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
171 let SuperClasses = [LogicalVecShifterOperand];
172 let Name = "LogicalVecHalfWordShifter";
173 let RenderMethod = "addShifterOperands";
176 // The "MSL" shifter on the vector MOVI instruction.
177 def MoveVecShifterOperand : AsmOperandClass {
178 let SuperClasses = [ShifterOperand];
179 let Name = "MoveVecShifter";
180 let RenderMethod = "addShifterOperands";
183 // Extend operand for arithmetic encodings.
184 def ExtendOperand : AsmOperandClass {
186 let DiagnosticType = "AddSubRegExtendLarge";
188 def ExtendOperand64 : AsmOperandClass {
189 let SuperClasses = [ExtendOperand];
190 let Name = "Extend64";
191 let DiagnosticType = "AddSubRegExtendSmall";
193 // 'extend' that's a lsl of a 64-bit register.
194 def ExtendOperandLSL64 : AsmOperandClass {
195 let SuperClasses = [ExtendOperand];
196 let Name = "ExtendLSL64";
197 let RenderMethod = "addExtend64Operands";
198 let DiagnosticType = "AddSubRegExtendLarge";
201 // 8-bit floating-point immediate encodings.
202 def FPImmOperand : AsmOperandClass {
204 let ParserMethod = "tryParseFPImm<true>";
205 let DiagnosticType = "InvalidFPImm";
208 def CondCode : AsmOperandClass {
209 let Name = "CondCode";
210 let DiagnosticType = "InvalidCondCode";
213 // A 32-bit register pasrsed as 64-bit
214 def GPR32as64Operand : AsmOperandClass {
215 let Name = "GPR32as64";
217 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";
219 def GPR32as64 : RegisterOperand<GPR32> {
220 let ParserMatchClass = GPR32as64Operand;
223 // A 64-bit register pasrsed as 32-bit
224 def GPR64as32Operand : AsmOperandClass {
225 let Name = "GPR64as32";
227 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";
229 def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {
230 let ParserMatchClass = GPR64as32Operand;
233 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
234 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
235 // are encoded as the eight bit value 'abcdefgh'.
236 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
238 class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
239 let Name = "UImm" # Width # "s" # Scale;
240 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;
241 let RenderMethod = "addImmScaledOperands<" # Scale # ">";
242 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";
245 class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
246 let Name = "SImm" # Width # "s" # Scale;
247 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;
248 let RenderMethod = "addImmScaledOperands<" # Scale # ">";
249 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";
252 //===----------------------------------------------------------------------===//
253 // Operand Definitions.
256 // ADR[P] instruction labels.
257 def AdrpOperand : AsmOperandClass {
258 let Name = "AdrpLabel";
259 let ParserMethod = "tryParseAdrpLabel";
260 let DiagnosticType = "InvalidLabel";
262 def adrplabel : Operand<i64> {
263 let EncoderMethod = "getAdrLabelOpValue";
264 let PrintMethod = "printAdrpLabel";
265 let ParserMatchClass = AdrpOperand;
268 def AdrOperand : AsmOperandClass {
269 let Name = "AdrLabel";
270 let ParserMethod = "tryParseAdrLabel";
271 let DiagnosticType = "InvalidLabel";
273 def adrlabel : Operand<i64> {
274 let EncoderMethod = "getAdrLabelOpValue";
275 let ParserMatchClass = AdrOperand;
278 class SImmOperand<int width> : AsmOperandClass {
279 let Name = "SImm" # width;
280 let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
281 let RenderMethod = "addImmOperands";
282 let PredicateMethod = "isSImm<" # width # ">";
286 class AsmImmRange<int Low, int High> : AsmOperandClass {
287 let Name = "Imm" # Low # "_" # High;
288 let DiagnosticType = "InvalidImm" # Low # "_" # High;
289 let RenderMethod = "addImmOperands";
290 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
293 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
294 def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;
295 def simm10Scaled : Operand<i64> {
296 let ParserMatchClass = SImm10s8Operand;
297 let DecoderMethod = "DecodeSImm<10>";
298 let PrintMethod = "printImmScale<8>";
301 def simm9s16 : Operand<i64> {
302 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;
303 let DecoderMethod = "DecodeSImm<9>";
304 let PrintMethod = "printImmScale<16>";
307 // uimm6 predicate - True if the immediate is in the range [0, 63].
308 def UImm6Operand : AsmOperandClass {
310 let DiagnosticType = "InvalidImm0_63";
313 def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
314 let ParserMatchClass = UImm6Operand;
317 def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
318 let ParserMatchClass = AsmImmRange<0, 65535>;
321 def SImm9Operand : SImmOperand<9>;
322 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
323 let ParserMatchClass = SImm9Operand;
324 let DecoderMethod = "DecodeSImm<9>";
327 def SImm8Operand : SImmOperand<8>;
328 def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 127; }]> {
329 let ParserMatchClass = SImm8Operand;
330 let DecoderMethod = "DecodeSImm<8>";
333 def SImm6Operand : SImmOperand<6>;
334 def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
335 let ParserMatchClass = SImm6Operand;
336 let DecoderMethod = "DecodeSImm<6>";
339 def SImm5Operand : SImmOperand<5>;
340 def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
341 let ParserMatchClass = SImm5Operand;
342 let DecoderMethod = "DecodeSImm<5>";
345 def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
346 let ParserMatchClass = SImm5Operand;
347 let DecoderMethod = "DecodeSImm<5>";
350 def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {
351 let ParserMatchClass = SImm5Operand;
352 let DecoderMethod = "DecodeSImm<5>";
353 let PrintMethod = "printSImm<8>";
356 def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {
357 let ParserMatchClass = SImm5Operand;
358 let DecoderMethod = "DecodeSImm<5>";
359 let PrintMethod = "printSImm<16>";
362 // simm7sN predicate - True if the immediate is a multiple of N in the range
363 // [-64 * N, 63 * N].
365 def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;
366 def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;
367 def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
369 def simm7s4 : Operand<i32> {
370 let ParserMatchClass = SImm7s4Operand;
371 let PrintMethod = "printImmScale<4>";
374 def simm7s8 : Operand<i32> {
375 let ParserMatchClass = SImm7s8Operand;
376 let PrintMethod = "printImmScale<8>";
379 def simm7s16 : Operand<i32> {
380 let ParserMatchClass = SImm7s16Operand;
381 let PrintMethod = "printImmScale<16>";
384 def am_sve_fi : ComplexPattern<i64, 2, "SelectAddrModeFrameIndexSVE", []>;
386 def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
387 def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
388 def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
389 def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
390 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
392 def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>;
393 def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>;
395 def UImmS1XForm : SDNodeXForm<imm, [{
396 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64);
398 def UImmS2XForm : SDNodeXForm<imm, [{
399 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);
401 def UImmS4XForm : SDNodeXForm<imm, [{
402 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);
404 def UImmS8XForm : SDNodeXForm<imm, [{
405 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
408 // uimm5sN predicate - True if the immediate is a multiple of N in the range
410 def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
411 def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;
412 def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;
414 def uimm5s2 : Operand<i64>, ImmLeaf<i64,
415 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
417 let ParserMatchClass = UImm5s2Operand;
418 let PrintMethod = "printImmScale<2>";
420 def uimm5s4 : Operand<i64>, ImmLeaf<i64,
421 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
423 let ParserMatchClass = UImm5s4Operand;
424 let PrintMethod = "printImmScale<4>";
426 def uimm5s8 : Operand<i64>, ImmLeaf<i64,
427 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
429 let ParserMatchClass = UImm5s8Operand;
430 let PrintMethod = "printImmScale<8>";
433 // tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant)
434 // instead of ImmLeaf (Constant)
435 def tuimm5s2 : Operand<i64>, TImmLeaf<i64,
436 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
438 let ParserMatchClass = UImm5s2Operand;
439 let PrintMethod = "printImmScale<2>";
441 def tuimm5s4 : Operand<i64>, TImmLeaf<i64,
442 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
444 let ParserMatchClass = UImm5s4Operand;
445 let PrintMethod = "printImmScale<4>";
447 def tuimm5s8 : Operand<i64>, TImmLeaf<i64,
448 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
450 let ParserMatchClass = UImm5s8Operand;
451 let PrintMethod = "printImmScale<8>";
454 // uimm6sN predicate - True if the immediate is a multiple of N in the range
456 def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;
457 def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;
458 def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;
459 def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;
460 def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;
462 def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
463 let ParserMatchClass = UImm6s1Operand;
465 def uimm6s2 : Operand<i64>, ImmLeaf<i64,
466 [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
467 let PrintMethod = "printImmScale<2>";
468 let ParserMatchClass = UImm6s2Operand;
470 def uimm6s4 : Operand<i64>, ImmLeaf<i64,
471 [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
472 let PrintMethod = "printImmScale<4>";
473 let ParserMatchClass = UImm6s4Operand;
475 def uimm6s8 : Operand<i64>, ImmLeaf<i64,
476 [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
477 let PrintMethod = "printImmScale<8>";
478 let ParserMatchClass = UImm6s8Operand;
480 def uimm6s16 : Operand<i64>, ImmLeaf<i64,
481 [{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {
482 let PrintMethod = "printImmScale<16>";
483 let ParserMatchClass = UImm6s16Operand;
486 def SImmS2XForm : SDNodeXForm<imm, [{
487 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64);
489 def SImmS3XForm : SDNodeXForm<imm, [{
490 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64);
492 def SImmS4XForm : SDNodeXForm<imm, [{
493 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64);
495 def SImmS16XForm : SDNodeXForm<imm, [{
496 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64);
498 def SImmS32XForm : SDNodeXForm<imm, [{
499 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64);
502 // simm6sN predicate - True if the immediate is a multiple of N in the range
503 // [-32 * N, 31 * N].
504 def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
505 def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
506 let ParserMatchClass = SImm6s1Operand;
507 let DecoderMethod = "DecodeSImm<6>";
510 // simm4sN predicate - True if the immediate is a multiple of N in the range
512 def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>;
513 def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>;
514 def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>;
515 def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>;
516 def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
517 def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>;
519 def simm4s1 : Operand<i64>, ImmLeaf<i64,
520 [{ return Imm >=-8 && Imm <= 7; }]> {
521 let ParserMatchClass = SImm4s1Operand;
522 let DecoderMethod = "DecodeSImm<4>";
525 def simm4s2 : Operand<i64>, ImmLeaf<i64,
526 [{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> {
527 let PrintMethod = "printImmScale<2>";
528 let ParserMatchClass = SImm4s2Operand;
529 let DecoderMethod = "DecodeSImm<4>";
532 def simm4s3 : Operand<i64>, ImmLeaf<i64,
533 [{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> {
534 let PrintMethod = "printImmScale<3>";
535 let ParserMatchClass = SImm4s3Operand;
536 let DecoderMethod = "DecodeSImm<4>";
539 def simm4s4 : Operand<i64>, ImmLeaf<i64,
540 [{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> {
541 let PrintMethod = "printImmScale<4>";
542 let ParserMatchClass = SImm4s4Operand;
543 let DecoderMethod = "DecodeSImm<4>";
545 def simm4s16 : Operand<i64>, ImmLeaf<i64,
546 [{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> {
547 let PrintMethod = "printImmScale<16>";
548 let ParserMatchClass = SImm4s16Operand;
549 let DecoderMethod = "DecodeSImm<4>";
551 def simm4s32 : Operand<i64>, ImmLeaf<i64,
552 [{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> {
553 let PrintMethod = "printImmScale<32>";
554 let ParserMatchClass = SImm4s32Operand;
555 let DecoderMethod = "DecodeSImm<4>";
558 def Imm1_8Operand : AsmImmRange<1, 8>;
559 def Imm1_16Operand : AsmImmRange<1, 16>;
560 def Imm1_32Operand : AsmImmRange<1, 32>;
561 def Imm1_64Operand : AsmImmRange<1, 64>;
563 class BranchTarget<int N> : AsmOperandClass {
564 let Name = "BranchTarget" # N;
565 let DiagnosticType = "InvalidLabel";
566 let PredicateMethod = "isBranchTarget<" # N # ">";
569 class PCRelLabel<int N> : BranchTarget<N> {
570 let Name = "PCRelLabel" # N;
573 def BranchTarget14Operand : BranchTarget<14>;
574 def BranchTarget26Operand : BranchTarget<26>;
575 def PCRelLabel19Operand : PCRelLabel<19>;
577 def MovWSymbolG3AsmOperand : AsmOperandClass {
578 let Name = "MovWSymbolG3";
579 let RenderMethod = "addImmOperands";
582 def movw_symbol_g3 : Operand<i32> {
583 let ParserMatchClass = MovWSymbolG3AsmOperand;
586 def MovWSymbolG2AsmOperand : AsmOperandClass {
587 let Name = "MovWSymbolG2";
588 let RenderMethod = "addImmOperands";
591 def movw_symbol_g2 : Operand<i32> {
592 let ParserMatchClass = MovWSymbolG2AsmOperand;
595 def MovWSymbolG1AsmOperand : AsmOperandClass {
596 let Name = "MovWSymbolG1";
597 let RenderMethod = "addImmOperands";
600 def movw_symbol_g1 : Operand<i32> {
601 let ParserMatchClass = MovWSymbolG1AsmOperand;
604 def MovWSymbolG0AsmOperand : AsmOperandClass {
605 let Name = "MovWSymbolG0";
606 let RenderMethod = "addImmOperands";
609 def movw_symbol_g0 : Operand<i32> {
610 let ParserMatchClass = MovWSymbolG0AsmOperand;
613 class fixedpoint_i32<ValueType FloatVT>
615 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
616 let EncoderMethod = "getFixedPointScaleOpValue";
617 let DecoderMethod = "DecodeFixedPointScaleImm32";
618 let ParserMatchClass = Imm1_32Operand;
621 class fixedpoint_i64<ValueType FloatVT>
623 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
624 let EncoderMethod = "getFixedPointScaleOpValue";
625 let DecoderMethod = "DecodeFixedPointScaleImm64";
626 let ParserMatchClass = Imm1_64Operand;
629 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
630 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
631 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
633 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
634 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
635 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
637 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
638 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
640 let EncoderMethod = "getVecShiftR8OpValue";
641 let DecoderMethod = "DecodeVecShiftR8Imm";
642 let ParserMatchClass = Imm1_8Operand;
644 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
645 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
647 let EncoderMethod = "getVecShiftR16OpValue";
648 let DecoderMethod = "DecodeVecShiftR16Imm";
649 let ParserMatchClass = Imm1_16Operand;
651 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
652 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
654 let EncoderMethod = "getVecShiftR16OpValue";
655 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
656 let ParserMatchClass = Imm1_8Operand;
658 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
659 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
661 let EncoderMethod = "getVecShiftR32OpValue";
662 let DecoderMethod = "DecodeVecShiftR32Imm";
663 let ParserMatchClass = Imm1_32Operand;
665 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
666 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
668 let EncoderMethod = "getVecShiftR32OpValue";
669 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
670 let ParserMatchClass = Imm1_16Operand;
672 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
673 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
675 let EncoderMethod = "getVecShiftR64OpValue";
676 let DecoderMethod = "DecodeVecShiftR64Imm";
677 let ParserMatchClass = Imm1_64Operand;
679 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
680 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
682 let EncoderMethod = "getVecShiftR64OpValue";
683 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
684 let ParserMatchClass = Imm1_32Operand;
687 // Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant
689 def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
690 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
692 let EncoderMethod = "getVecShiftR8OpValue";
693 let DecoderMethod = "DecodeVecShiftR8Imm";
694 let ParserMatchClass = Imm1_8Operand;
696 def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
697 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
699 let EncoderMethod = "getVecShiftR16OpValue";
700 let DecoderMethod = "DecodeVecShiftR16Imm";
701 let ParserMatchClass = Imm1_16Operand;
703 def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
704 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
706 let EncoderMethod = "getVecShiftR32OpValue";
707 let DecoderMethod = "DecodeVecShiftR32Imm";
708 let ParserMatchClass = Imm1_32Operand;
710 def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{
711 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
713 let EncoderMethod = "getVecShiftR64OpValue";
714 let DecoderMethod = "DecodeVecShiftR64Imm";
715 let ParserMatchClass = Imm1_64Operand;
718 def Imm0_1Operand : AsmImmRange<0, 1>;
719 def Imm0_7Operand : AsmImmRange<0, 7>;
720 def Imm0_15Operand : AsmImmRange<0, 15>;
721 def Imm0_31Operand : AsmImmRange<0, 31>;
722 def Imm0_63Operand : AsmImmRange<0, 63>;
724 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
725 return (((uint32_t)Imm) < 8);
727 let EncoderMethod = "getVecShiftL8OpValue";
728 let DecoderMethod = "DecodeVecShiftL8Imm";
729 let ParserMatchClass = Imm0_7Operand;
731 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
732 return (((uint32_t)Imm) < 16);
734 let EncoderMethod = "getVecShiftL16OpValue";
735 let DecoderMethod = "DecodeVecShiftL16Imm";
736 let ParserMatchClass = Imm0_15Operand;
738 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
739 return (((uint32_t)Imm) < 32);
741 let EncoderMethod = "getVecShiftL32OpValue";
742 let DecoderMethod = "DecodeVecShiftL32Imm";
743 let ParserMatchClass = Imm0_31Operand;
745 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
746 return (((uint32_t)Imm) < 64);
748 let EncoderMethod = "getVecShiftL64OpValue";
749 let DecoderMethod = "DecodeVecShiftL64Imm";
750 let ParserMatchClass = Imm0_63Operand;
753 // Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant
755 def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{
756 return (((uint32_t)Imm) < 8);
758 let EncoderMethod = "getVecShiftL8OpValue";
759 let DecoderMethod = "DecodeVecShiftL8Imm";
760 let ParserMatchClass = Imm0_7Operand;
762 def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{
763 return (((uint32_t)Imm) < 16);
765 let EncoderMethod = "getVecShiftL16OpValue";
766 let DecoderMethod = "DecodeVecShiftL16Imm";
767 let ParserMatchClass = Imm0_15Operand;
769 def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{
770 return (((uint32_t)Imm) < 32);
772 let EncoderMethod = "getVecShiftL32OpValue";
773 let DecoderMethod = "DecodeVecShiftL32Imm";
774 let ParserMatchClass = Imm0_31Operand;
776 def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{
777 return (((uint32_t)Imm) < 64);
779 let EncoderMethod = "getVecShiftL64OpValue";
780 let DecoderMethod = "DecodeVecShiftL64Imm";
781 let ParserMatchClass = Imm0_63Operand;
784 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
785 // instructions for splatting repeating bit patterns across the immediate.
786 def logical_imm32_XFORM : SDNodeXForm<imm, [{
787 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
788 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
790 def logical_imm64_XFORM : SDNodeXForm<imm, [{
791 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
792 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
795 def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">,
796 GISDNodeXFormEquiv<logical_imm32_XFORM>;
797 def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">,
798 GISDNodeXFormEquiv<logical_imm64_XFORM>;
800 let DiagnosticType = "LogicalSecondSource" in {
801 def LogicalImm32Operand : AsmOperandClass {
802 let Name = "LogicalImm32";
803 let PredicateMethod = "isLogicalImm<int32_t>";
804 let RenderMethod = "addLogicalImmOperands<int32_t>";
806 def LogicalImm64Operand : AsmOperandClass {
807 let Name = "LogicalImm64";
808 let PredicateMethod = "isLogicalImm<int64_t>";
809 let RenderMethod = "addLogicalImmOperands<int64_t>";
811 def LogicalImm32NotOperand : AsmOperandClass {
812 let Name = "LogicalImm32Not";
813 let PredicateMethod = "isLogicalImm<int32_t>";
814 let RenderMethod = "addLogicalImmNotOperands<int32_t>";
816 def LogicalImm64NotOperand : AsmOperandClass {
817 let Name = "LogicalImm64Not";
818 let PredicateMethod = "isLogicalImm<int64_t>";
819 let RenderMethod = "addLogicalImmNotOperands<int64_t>";
822 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
823 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
824 }], logical_imm32_XFORM> {
825 let PrintMethod = "printLogicalImm<int32_t>";
826 let ParserMatchClass = LogicalImm32Operand;
828 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
829 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
830 }], logical_imm64_XFORM> {
831 let PrintMethod = "printLogicalImm<int64_t>";
832 let ParserMatchClass = LogicalImm64Operand;
834 def logical_imm32_not : Operand<i32> {
835 let ParserMatchClass = LogicalImm32NotOperand;
837 def logical_imm64_not : Operand<i64> {
838 let ParserMatchClass = LogicalImm64NotOperand;
841 // iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535].
842 let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in {
843 def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{
844 return ((uint32_t)Imm) < 65536;
847 def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{
848 return ((uint64_t)Imm) < 65536;
852 // imm0_255 predicate - True if the immediate is in the range [0,255].
853 def Imm0_255Operand : AsmImmRange<0,255>;
855 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
856 return ((uint32_t)Imm) < 256;
858 let ParserMatchClass = Imm0_255Operand;
859 let PrintMethod = "printImm";
862 // imm0_127 predicate - True if the immediate is in the range [0,127]
863 def Imm0_127Operand : AsmImmRange<0, 127>;
864 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
865 return ((uint32_t)Imm) < 128;
867 let ParserMatchClass = Imm0_127Operand;
868 let PrintMethod = "printImm";
871 def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{
872 return ((uint64_t)Imm) < 128;
874 let ParserMatchClass = Imm0_127Operand;
875 let PrintMethod = "printImm";
878 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
879 // for all shift-amounts.
881 // imm0_63 predicate - True if the immediate is in the range [0,63]
882 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
883 return ((uint64_t)Imm) < 64;
885 let ParserMatchClass = Imm0_63Operand;
888 // imm0_31 predicate - True if the immediate is in the range [0,31]
889 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
890 return ((uint64_t)Imm) < 32;
892 let ParserMatchClass = Imm0_31Operand;
895 // timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf)
896 // instead of Constant (ImmLeaf)
897 def timm0_31 : Operand<i64>, TImmLeaf<i64, [{
898 return ((uint64_t)Imm) < 32;
900 let ParserMatchClass = Imm0_31Operand;
903 // True if the 32-bit immediate is in the range [0,31]
904 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
905 return ((uint64_t)Imm) < 32;
907 let ParserMatchClass = Imm0_31Operand;
910 // imm0_1 predicate - True if the immediate is in the range [0,1]
911 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
912 return ((uint64_t)Imm) < 2;
914 let ParserMatchClass = Imm0_1Operand;
917 // imm0_15 predicate - True if the immediate is in the range [0,15]
918 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
919 return ((uint64_t)Imm) < 16;
921 let ParserMatchClass = Imm0_15Operand;
924 // imm0_7 predicate - True if the immediate is in the range [0,7]
925 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
926 return ((uint64_t)Imm) < 8;
928 let ParserMatchClass = Imm0_7Operand;
931 // imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
932 def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{
933 return ((uint32_t)Imm) < 8;
935 let ParserMatchClass = Imm0_7Operand;
938 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
939 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
940 return ((uint32_t)Imm) < 16;
942 let ParserMatchClass = Imm0_15Operand;
945 // An arithmetic shifter operand:
946 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
948 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
949 let PrintMethod = "printShifter";
950 let ParserMatchClass = !cast<AsmOperandClass>(
951 "ArithmeticShifterOperand" # width);
954 def arith_shift32 : arith_shift<i32, 32>;
955 def arith_shift64 : arith_shift<i64, 64>;
957 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
959 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
960 let PrintMethod = "printShiftedRegister";
961 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
964 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
965 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
967 def gi_arith_shifted_reg32 :
968 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">,
969 GIComplexPatternEquiv<arith_shifted_reg32>;
971 def gi_arith_shifted_reg64 :
972 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">,
973 GIComplexPatternEquiv<arith_shifted_reg64>;
975 // An arithmetic shifter operand:
976 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
978 class logical_shift<int width> : Operand<i32> {
979 let PrintMethod = "printShifter";
980 let ParserMatchClass = !cast<AsmOperandClass>(
981 "LogicalShifterOperand" # width);
984 def logical_shift32 : logical_shift<32>;
985 def logical_shift64 : logical_shift<64>;
987 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
989 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
990 let PrintMethod = "printShiftedRegister";
991 let MIOperandInfo = (ops regclass, shiftop);
994 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
995 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
997 def gi_logical_shifted_reg32 :
998 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">,
999 GIComplexPatternEquiv<logical_shifted_reg32>;
1001 def gi_logical_shifted_reg64 :
1002 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">,
1003 GIComplexPatternEquiv<logical_shifted_reg64>;
1005 // A logical vector shifter operand:
1006 // {7-6} - shift type: 00 = lsl
1007 // {5-0} - imm6: #0, #8, #16, or #24
1008 def logical_vec_shift : Operand<i32> {
1009 let PrintMethod = "printShifter";
1010 let EncoderMethod = "getVecShifterOpValue";
1011 let ParserMatchClass = LogicalVecShifterOperand;
1014 // A logical vector half-word shifter operand:
1015 // {7-6} - shift type: 00 = lsl
1016 // {5-0} - imm6: #0 or #8
1017 def logical_vec_hw_shift : Operand<i32> {
1018 let PrintMethod = "printShifter";
1019 let EncoderMethod = "getVecShifterOpValue";
1020 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
1023 // A vector move shifter operand:
1024 // {0} - imm1: #8 or #16
1025 def move_vec_shift : Operand<i32> {
1026 let PrintMethod = "printShifter";
1027 let EncoderMethod = "getMoveVecShifterOpValue";
1028 let ParserMatchClass = MoveVecShifterOperand;
1031 let DiagnosticType = "AddSubSecondSource" in {
1032 def AddSubImmOperand : AsmOperandClass {
1033 let Name = "AddSubImm";
1034 let ParserMethod = "tryParseImmWithOptionalShift";
1035 let RenderMethod = "addImmWithOptionalShiftOperands<12>";
1037 def AddSubImmNegOperand : AsmOperandClass {
1038 let Name = "AddSubImmNeg";
1039 let ParserMethod = "tryParseImmWithOptionalShift";
1040 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
1043 // An ADD/SUB immediate shifter operand:
1045 // {7-6} - shift type: 00 = lsl
1046 // {5-0} - imm6: #0 or #12
1047 class addsub_shifted_imm<ValueType Ty>
1048 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
1049 let PrintMethod = "printAddSubImm";
1050 let EncoderMethod = "getAddSubImmOpValue";
1051 let ParserMatchClass = AddSubImmOperand;
1052 let MIOperandInfo = (ops i32imm, i32imm);
1055 class addsub_shifted_imm_neg<ValueType Ty>
1057 let EncoderMethod = "getAddSubImmOpValue";
1058 let ParserMatchClass = AddSubImmNegOperand;
1059 let MIOperandInfo = (ops i32imm, i32imm);
1062 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
1063 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
1064 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
1065 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
1067 def gi_addsub_shifted_imm32 :
1068 GIComplexOperandMatcher<s32, "selectArithImmed">,
1069 GIComplexPatternEquiv<addsub_shifted_imm32>;
1071 def gi_addsub_shifted_imm64 :
1072 GIComplexOperandMatcher<s64, "selectArithImmed">,
1073 GIComplexPatternEquiv<addsub_shifted_imm64>;
1075 class neg_addsub_shifted_imm<ValueType Ty>
1076 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
1077 let PrintMethod = "printAddSubImm";
1078 let EncoderMethod = "getAddSubImmOpValue";
1079 let ParserMatchClass = AddSubImmOperand;
1080 let MIOperandInfo = (ops i32imm, i32imm);
1083 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
1084 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
1086 def gi_neg_addsub_shifted_imm32 :
1087 GIComplexOperandMatcher<s32, "selectNegArithImmed">,
1088 GIComplexPatternEquiv<neg_addsub_shifted_imm32>;
1090 def gi_neg_addsub_shifted_imm64 :
1091 GIComplexOperandMatcher<s64, "selectNegArithImmed">,
1092 GIComplexPatternEquiv<neg_addsub_shifted_imm64>;
1094 // An extend operand:
1095 // {5-3} - extend type
1097 def arith_extend : Operand<i32> {
1098 let PrintMethod = "printArithExtend";
1099 let ParserMatchClass = ExtendOperand;
1101 def arith_extend64 : Operand<i32> {
1102 let PrintMethod = "printArithExtend";
1103 let ParserMatchClass = ExtendOperand64;
1106 // 'extend' that's a lsl of a 64-bit register.
1107 def arith_extendlsl64 : Operand<i32> {
1108 let PrintMethod = "printArithExtend";
1109 let ParserMatchClass = ExtendOperandLSL64;
1112 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
1113 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1114 let PrintMethod = "printExtendedRegister";
1115 let MIOperandInfo = (ops GPR32, arith_extend);
1118 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
1119 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1120 let PrintMethod = "printExtendedRegister";
1121 let MIOperandInfo = (ops GPR32, arith_extend64);
1124 def arith_extended_reg32_i32 : arith_extended_reg32<i32>;
1125 def gi_arith_extended_reg32_i32 :
1126 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">,
1127 GIComplexPatternEquiv<arith_extended_reg32_i32>;
1129 def arith_extended_reg32_i64 : arith_extended_reg32<i64>;
1130 def gi_arith_extended_reg32_i64 :
1131 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1132 GIComplexPatternEquiv<arith_extended_reg32_i64>;
1134 def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>;
1135 def gi_arith_extended_reg32to64_i64 :
1136 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1137 GIComplexPatternEquiv<arith_extended_reg32to64_i64>;
1139 // Floating-point immediate.
1140 def fpimm16 : Operand<f16>,
1142 return AArch64_AM::getFP16Imm(Imm) != -1;
1143 }], SDNodeXForm<fpimm, [{
1144 APFloat InVal = N->getValueAPF();
1145 uint32_t enc = AArch64_AM::getFP16Imm(InVal);
1146 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1148 let ParserMatchClass = FPImmOperand;
1149 let PrintMethod = "printFPImmOperand";
1151 def fpimm32 : Operand<f32>,
1153 return AArch64_AM::getFP32Imm(Imm) != -1;
1154 }], SDNodeXForm<fpimm, [{
1155 APFloat InVal = N->getValueAPF();
1156 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
1157 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1159 let ParserMatchClass = FPImmOperand;
1160 let PrintMethod = "printFPImmOperand";
1162 def fpimm64 : Operand<f64>,
1164 return AArch64_AM::getFP64Imm(Imm) != -1;
1165 }], SDNodeXForm<fpimm, [{
1166 APFloat InVal = N->getValueAPF();
1167 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
1168 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1170 let ParserMatchClass = FPImmOperand;
1171 let PrintMethod = "printFPImmOperand";
1174 def fpimm8 : Operand<i32> {
1175 let ParserMatchClass = FPImmOperand;
1176 let PrintMethod = "printFPImmOperand";
1179 def fpimm0 : FPImmLeaf<fAny, [{
1180 return Imm.isExactlyValue(+0.0);
1183 // Vector lane operands
1184 class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {
1185 let Name = NamePrefix # "IndexRange" # Min # "_" # Max;
1186 let DiagnosticType = "Invalid" # Name;
1187 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">";
1188 let RenderMethod = "addVectorIndexOperands";
1191 class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc>
1193 let ParserMatchClass = mc;
1194 let PrintMethod = "printVectorIndex";
1197 multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> {
1198 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>;
1199 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>;
1202 def VectorIndex1Operand : AsmVectorIndex<1, 1>;
1203 def VectorIndexBOperand : AsmVectorIndex<0, 15>;
1204 def VectorIndexHOperand : AsmVectorIndex<0, 7>;
1205 def VectorIndexSOperand : AsmVectorIndex<0, 3>;
1206 def VectorIndexDOperand : AsmVectorIndex<0, 1>;
1208 defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,
1209 [{ return ((uint64_t)Imm) == 1; }]>;
1210 defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand,
1211 [{ return ((uint64_t)Imm) < 16; }]>;
1212 defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand,
1213 [{ return ((uint64_t)Imm) < 8; }]>;
1214 defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand,
1215 [{ return ((uint64_t)Imm) < 4; }]>;
1216 defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand,
1217 [{ return ((uint64_t)Imm) < 2; }]>;
1219 defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand,
1220 [{ return ((uint64_t)Imm) == 1; }]>;
1221 defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand,
1222 [{ return ((uint64_t)Imm) < 16; }]>;
1223 defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand,
1224 [{ return ((uint64_t)Imm) < 8; }]>;
1225 defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand,
1226 [{ return ((uint64_t)Imm) < 4; }]>;
1227 defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand,
1228 [{ return ((uint64_t)Imm) < 2; }]>;
1230 def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
1231 def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
1232 def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
1233 def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
1234 def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
1236 defm sve_elm_idx_extdup_b
1237 : VectorIndex<i64, SVEVectorIndexExtDupBOperand,
1238 [{ return ((uint64_t)Imm) < 64; }]>;
1239 defm sve_elm_idx_extdup_h
1240 : VectorIndex<i64, SVEVectorIndexExtDupHOperand,
1241 [{ return ((uint64_t)Imm) < 32; }]>;
1242 defm sve_elm_idx_extdup_s
1243 : VectorIndex<i64, SVEVectorIndexExtDupSOperand,
1244 [{ return ((uint64_t)Imm) < 16; }]>;
1245 defm sve_elm_idx_extdup_d
1246 : VectorIndex<i64, SVEVectorIndexExtDupDOperand,
1247 [{ return ((uint64_t)Imm) < 8; }]>;
1248 defm sve_elm_idx_extdup_q
1249 : VectorIndex<i64, SVEVectorIndexExtDupQOperand,
1250 [{ return ((uint64_t)Imm) < 4; }]>;
1252 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
1253 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
1254 // are encoded as the eight bit value 'abcdefgh'.
1255 def simdimmtype10 : Operand<i32>,
1257 return AArch64_AM::isAdvSIMDModImmType10(
1258 Imm.bitcastToAPInt().getZExtValue());
1259 }], SDNodeXForm<fpimm, [{
1260 APFloat InVal = N->getValueAPF();
1261 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
1264 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1266 let ParserMatchClass = SIMDImmType10Operand;
1267 let PrintMethod = "printSIMDType10Operand";
1272 // System management
1275 // Base encoding for system instruction operands.
1276 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
1277 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
1278 list<dag> pattern = []>
1279 : I<oops, iops, asm, operands, "", pattern> {
1280 let Inst{31-22} = 0b1101010100;
1284 // System instructions which do not have an Rt register.
1285 class SimpleSystemI<bit L, dag iops, string asm, string operands,
1286 list<dag> pattern = []>
1287 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
1288 let Inst{4-0} = 0b11111;
1291 // System instructions which have an Rt register.
1292 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
1293 : BaseSystemI<L, oops, iops, asm, operands>,
1299 // System instructions for transactional memory extension
1300 class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops,
1301 string asm, string operands, list<dag> pattern>
1302 : BaseSystemI<L, oops, iops, asm, operands, pattern>,
1304 let Inst{20-12} = 0b000110011;
1305 let Inst{11-8} = CRm;
1306 let Inst{7-5} = op2;
1307 let DecoderMethod = "";
1313 // System instructions for transactional memory - single input operand
1314 class TMSystemI<bits<4> CRm, string asm, list<dag> pattern>
1315 : TMBaseSystemI<0b1, CRm, 0b011,
1316 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> {
1321 // System instructions for transactional memory - no operand
1322 class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern>
1323 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> {
1324 let Inst{4-0} = 0b11111;
1327 // System instructions for exit from transactions
1328 class TMSystemException<bits<3> op1, string asm, list<dag> pattern>
1329 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>,
1332 let Inst{31-24} = 0b11010100;
1333 let Inst{23-21} = op1;
1334 let Inst{20-5} = imm;
1335 let Inst{4-0} = 0b00000;
1338 // Hint instructions that take both a CRm and a 3-bit immediate.
1339 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
1340 // model patterns with sufficiently fine granularity
1341 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
1342 class HintI<string mnemonic>
1343 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
1344 [(int_aarch64_hint imm0_127:$imm)]>,
1345 Sched<[WriteHint]> {
1347 let Inst{20-12} = 0b000110010;
1348 let Inst{11-5} = imm;
1351 // System instructions taking a single literal operand which encodes into
1352 // CRm. op2 differentiates the opcodes.
1353 def BarrierAsmOperand : AsmOperandClass {
1354 let Name = "Barrier";
1355 let ParserMethod = "tryParseBarrierOperand";
1357 def barrier_op : Operand<i32> {
1358 let PrintMethod = "printBarrierOption";
1359 let ParserMatchClass = BarrierAsmOperand;
1361 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
1362 list<dag> pattern = []>
1363 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
1364 Sched<[WriteBarrier]> {
1366 let Inst{20-12} = 0b000110011;
1367 let Inst{11-8} = CRm;
1368 let Inst{7-5} = opc;
1371 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
1372 : SimpleSystemI<0, (ins), asm, "", pattern>,
1376 let Inst{31-12} = 0b11010101000000110010;
1377 let Inst{11-8} = CRm;
1378 let Inst{7-5} = op2;
1379 let Inst{4-0} = 0b11111;
1382 // MRS/MSR system instructions. These have different operand classes because
1383 // a different subset of registers can be accessed through each instruction.
1384 def MRSSystemRegisterOperand : AsmOperandClass {
1385 let Name = "MRSSystemRegister";
1386 let ParserMethod = "tryParseSysReg";
1387 let DiagnosticType = "MRS";
1389 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
1390 def mrs_sysreg_op : Operand<i32> {
1391 let ParserMatchClass = MRSSystemRegisterOperand;
1392 let DecoderMethod = "DecodeMRSSystemRegister";
1393 let PrintMethod = "printMRSSystemRegister";
1396 def MSRSystemRegisterOperand : AsmOperandClass {
1397 let Name = "MSRSystemRegister";
1398 let ParserMethod = "tryParseSysReg";
1399 let DiagnosticType = "MSR";
1401 def msr_sysreg_op : Operand<i32> {
1402 let ParserMatchClass = MSRSystemRegisterOperand;
1403 let DecoderMethod = "DecodeMSRSystemRegister";
1404 let PrintMethod = "printMSRSystemRegister";
1407 def PSBHintOperand : AsmOperandClass {
1408 let Name = "PSBHint";
1409 let ParserMethod = "tryParsePSBHint";
1411 def psbhint_op : Operand<i32> {
1412 let ParserMatchClass = PSBHintOperand;
1413 let PrintMethod = "printPSBHintOp";
1414 let MCOperandPredicate = [{
1415 // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
1416 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
1419 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
1423 def BTIHintOperand : AsmOperandClass {
1424 let Name = "BTIHint";
1425 let ParserMethod = "tryParseBTIHint";
1427 def btihint_op : Operand<i32> {
1428 let ParserMatchClass = BTIHintOperand;
1429 let PrintMethod = "printBTIHintOp";
1430 let MCOperandPredicate = [{
1431 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.
1434 return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr;
1438 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
1439 "mrs", "\t$Rt, $systemreg"> {
1441 let Inst{20-5} = systemreg;
1444 // FIXME: Some of these def NZCV, others don't. Best way to model that?
1445 // Explicitly modeling each of the system register as a register class
1446 // would do it, but feels like overkill at this point.
1447 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
1448 "msr", "\t$systemreg, $Rt"> {
1450 let Inst{20-5} = systemreg;
1453 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
1454 let Name = "SystemPStateFieldWithImm0_15";
1455 let ParserMethod = "tryParseSysReg";
1457 def pstatefield4_op : Operand<i32> {
1458 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
1459 let PrintMethod = "printSystemPStateField";
1462 // Instructions to modify PSTATE, no input reg
1463 let Defs = [NZCV] in
1464 class PstateWriteSimple<dag iops, string asm, string operands>
1465 : SimpleSystemI<0, iops, asm, operands> {
1467 let Inst{20-19} = 0b00;
1468 let Inst{15-12} = 0b0100;
1471 class MSRpstateImm0_15
1472 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr",
1473 "\t$pstatefield, $imm">,
1476 bits<6> pstatefield;
1478 let Inst{18-16} = pstatefield{5-3};
1479 let Inst{11-8} = imm;
1480 let Inst{7-5} = pstatefield{2-0};
1482 let DecoderMethod = "DecodeSystemPStateInstruction";
1483 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1484 // Fail the decoder should attempt to decode the instruction as MSRI.
1485 let hasCompleteDecoder = 0;
1488 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1489 let Name = "SystemPStateFieldWithImm0_1";
1490 let ParserMethod = "tryParseSysReg";
1492 def pstatefield1_op : Operand<i32> {
1493 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1494 let PrintMethod = "printSystemPStateField";
1497 class MSRpstateImm0_1
1498 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",
1499 "\t$pstatefield, $imm">,
1502 bits<6> pstatefield;
1504 let Inst{18-16} = pstatefield{5-3};
1505 let Inst{11-9} = 0b000;
1507 let Inst{7-5} = pstatefield{2-0};
1509 let DecoderMethod = "DecodeSystemPStateInstruction";
1510 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1511 // Fail the decoder should attempt to decode the instruction as MSRI.
1512 let hasCompleteDecoder = 0;
1515 // SYS and SYSL generic system instructions.
1516 def SysCRAsmOperand : AsmOperandClass {
1518 let ParserMethod = "tryParseSysCROperand";
1521 def sys_cr_op : Operand<i32> {
1522 let PrintMethod = "printSysCROperand";
1523 let ParserMatchClass = SysCRAsmOperand;
1526 class SystemXtI<bit L, string asm>
1527 : RtSystemI<L, (outs),
1528 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1529 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1534 let Inst{20-19} = 0b01;
1535 let Inst{18-16} = op1;
1536 let Inst{15-12} = Cn;
1537 let Inst{11-8} = Cm;
1538 let Inst{7-5} = op2;
1541 class SystemLXtI<bit L, string asm>
1542 : RtSystemI<L, (outs),
1543 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1544 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1549 let Inst{20-19} = 0b01;
1550 let Inst{18-16} = op1;
1551 let Inst{15-12} = Cn;
1552 let Inst{11-8} = Cm;
1553 let Inst{7-5} = op2;
1557 // Branch (register) instructions:
1565 // otherwise UNDEFINED
1566 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1567 string operands, list<dag> pattern>
1568 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1569 let Inst{31-25} = 0b1101011;
1570 let Inst{24-21} = opc;
1571 let Inst{20-16} = 0b11111;
1572 let Inst{15-10} = 0b000000;
1573 let Inst{4-0} = 0b00000;
1576 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1577 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1582 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1583 class SpecialReturn<bits<4> opc, string asm>
1584 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1585 let Inst{9-5} = 0b11111;
1589 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
1590 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
1594 let Inst{31-30} = sz;
1595 let Inst{29-10} = 0b11100010111111110000;
1600 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
1602 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
1603 let isAuthenticated = 1;
1604 let Inst{31-25} = 0b1101011;
1605 let Inst{20-11} = 0b1111100001;
1607 let Inst{4-0} = 0b11111;
1610 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
1611 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
1614 let Inst{24-22} = 0b100;
1620 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
1621 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
1624 let Inst{23-21} = opc;
1628 let Uses = [LR,SP] in
1629 class AuthReturn<bits<3> op, bits<1> M, string asm>
1630 : AuthBase<M, (outs), (ins), asm, "", []> {
1632 let Inst{23-21} = op;
1633 let Inst{9-0} = 0b1111111111;
1637 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
1638 string operands, string cstr, Operand opr>
1639 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
1643 let isAuthenticated = 1;
1644 let Inst{31-24} = 0b11111000;
1646 let Inst{22} = offset{9};
1648 let Inst{20-12} = offset{8-0};
1654 let DecoderMethod = "DecodeAuthLoadInstruction";
1657 multiclass AuthLoad<bit M, string asm, Operand opr> {
1658 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
1659 (ins GPR64sp:$Rn, opr:$offset),
1660 asm, "\t$Rt, [$Rn, $offset]", "", opr>;
1661 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
1662 (ins GPR64sp:$Rn, opr:$offset),
1663 asm, "\t$Rt, [$Rn, $offset]!",
1664 "$Rn = $wback,@earlyclobber $wback", opr>;
1666 def : InstAlias<asm # "\t$Rt, [$Rn]",
1667 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
1669 def : InstAlias<asm # "\t$Rt, [$wback]!",
1670 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>;
1674 // Conditional branch instruction.
1678 // 4-bit immediate. Pretty-printed as <cc>
1679 def ccode : Operand<i32> {
1680 let PrintMethod = "printCondCode";
1681 let ParserMatchClass = CondCode;
1683 def inv_ccode : Operand<i32> {
1684 // AL and NV are invalid in the aliases which use inv_ccode
1685 let PrintMethod = "printInverseCondCode";
1686 let ParserMatchClass = CondCode;
1687 let MCOperandPredicate = [{
1688 return MCOp.isImm() &&
1689 MCOp.getImm() != AArch64CC::AL &&
1690 MCOp.getImm() != AArch64CC::NV;
1694 // Conditional branch target. 19-bit immediate. The low two bits of the target
1695 // offset are implied zero and so are not part of the immediate.
1696 def am_brcond : Operand<OtherVT> {
1697 let EncoderMethod = "getCondBranchTargetOpValue";
1698 let DecoderMethod = "DecodePCRelLabel19";
1699 let PrintMethod = "printAlignedLabel";
1700 let ParserMatchClass = PCRelLabel19Operand;
1701 let OperandType = "OPERAND_PCREL";
1704 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1705 "b", ".$cond\t$target", "",
1706 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1709 let isTerminator = 1;
1714 let Inst{31-24} = 0b01010100;
1715 let Inst{23-5} = target;
1717 let Inst{3-0} = cond;
1721 // Compare-and-branch instructions.
1723 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1724 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1725 asm, "\t$Rt, $target", "",
1726 [(node regtype:$Rt, bb:$target)]>,
1729 let isTerminator = 1;
1733 let Inst{30-25} = 0b011010;
1735 let Inst{23-5} = target;
1739 multiclass CmpBranch<bit op, string asm, SDNode node> {
1740 def W : BaseCmpBranch<GPR32, op, asm, node> {
1743 def X : BaseCmpBranch<GPR64, op, asm, node> {
1749 // Test-bit-and-branch instructions.
1751 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1752 // the target offset are implied zero and so are not part of the immediate.
1753 def am_tbrcond : Operand<OtherVT> {
1754 let EncoderMethod = "getTestBranchTargetOpValue";
1755 let PrintMethod = "printAlignedLabel";
1756 let ParserMatchClass = BranchTarget14Operand;
1757 let OperandType = "OPERAND_PCREL";
1760 // AsmOperand classes to emit (or not) special diagnostics
1761 def TBZImm0_31Operand : AsmOperandClass {
1762 let Name = "TBZImm0_31";
1763 let PredicateMethod = "isImmInRange<0,31>";
1764 let RenderMethod = "addImmOperands";
1766 def TBZImm32_63Operand : AsmOperandClass {
1767 let Name = "Imm32_63";
1768 let PredicateMethod = "isImmInRange<32,63>";
1769 let DiagnosticType = "InvalidImm0_63";
1770 let RenderMethod = "addImmOperands";
1773 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1774 return (((uint32_t)Imm) < 32);
1776 let ParserMatchClass = matcher;
1779 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1780 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1782 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1783 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1785 let ParserMatchClass = TBZImm32_63Operand;
1788 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1789 bit op, string asm, SDNode node>
1790 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1791 asm, "\t$Rt, $bit_off, $target", "",
1792 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1795 let isTerminator = 1;
1801 let Inst{30-25} = 0b011011;
1803 let Inst{23-19} = bit_off{4-0};
1804 let Inst{18-5} = target;
1807 let DecoderMethod = "DecodeTestAndBranch";
1810 multiclass TestBranch<bit op, string asm, SDNode node> {
1811 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1815 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1819 // Alias X-reg with 0-31 imm to W-Reg.
1820 def : InstAlias<asm # "\t$Rd, $imm, $target",
1821 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1822 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1823 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1824 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1825 tbz_imm0_31_diag:$imm, bb:$target)>;
1829 // Unconditional branch (immediate) instructions.
1831 def am_b_target : Operand<OtherVT> {
1832 let EncoderMethod = "getBranchTargetOpValue";
1833 let PrintMethod = "printAlignedLabel";
1834 let ParserMatchClass = BranchTarget26Operand;
1835 let OperandType = "OPERAND_PCREL";
1837 def am_bl_target : Operand<i64> {
1838 let EncoderMethod = "getBranchTargetOpValue";
1839 let PrintMethod = "printAlignedLabel";
1840 let ParserMatchClass = BranchTarget26Operand;
1841 let OperandType = "OPERAND_PCREL";
1844 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1845 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1848 let Inst{30-26} = 0b00101;
1849 let Inst{25-0} = addr;
1851 let DecoderMethod = "DecodeUnconditionalBranch";
1854 class BranchImm<bit op, string asm, list<dag> pattern>
1855 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1856 class CallImm<bit op, string asm, list<dag> pattern>
1857 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1860 // Basic one-operand data processing instructions.
1863 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1864 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1865 SDPatternOperator node>
1866 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1867 [(set regtype:$Rd, (node regtype:$Rn))]>,
1868 Sched<[WriteI, ReadI]> {
1872 let Inst{30-13} = 0b101101011000000000;
1873 let Inst{12-10} = opc;
1878 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1879 multiclass OneOperandData<bits<3> opc, string asm,
1880 SDPatternOperator node = null_frag> {
1881 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1885 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1890 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1891 : BaseOneOperandData<opc, GPR32, asm, node> {
1895 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1896 : BaseOneOperandData<opc, GPR64, asm, node> {
1900 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
1901 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "",
1903 Sched<[WriteI, ReadI]> {
1906 let Inst{31-15} = 0b11011010110000010;
1907 let Inst{14-12} = opcode_prefix;
1908 let Inst{11-10} = opcode;
1913 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
1914 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> {
1916 let Inst{31-15} = 0b11011010110000010;
1917 let Inst{14-12} = opcode_prefix;
1918 let Inst{11-10} = opcode;
1919 let Inst{9-5} = 0b11111;
1923 class SignAuthTwoOperand<bits<4> opc, string asm,
1924 SDPatternOperator OpNode>
1925 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
1926 asm, "\t$Rd, $Rn, $Rm", "",
1927 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
1928 Sched<[WriteI, ReadI, ReadI]> {
1932 let Inst{31-21} = 0b10011010110;
1933 let Inst{20-16} = Rm;
1934 let Inst{15-14} = 0b00;
1935 let Inst{13-10} = opc;
1940 // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
1941 class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
1942 : I<(outs), iops, asm, ops, "", []>,
1943 Sched<[WriteI, ReadI, ReadI]> {
1947 let Inst{30-15} = 0b0111010000000000;
1949 let Inst{13-10} = 0b0010;
1951 let Inst{4-0} = 0b01101;
1954 class FlagRotate<dag iops, string asm, string ops>
1955 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
1958 let Inst{20-15} = imm;
1959 let Inst{13-10} = 0b0001;
1961 let Inst{3-0} = mask;
1965 // Basic two-operand data processing instructions.
1967 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1969 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1970 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1971 Sched<[WriteI, ReadI, ReadI]> {
1976 let Inst{30} = isSub;
1977 let Inst{28-21} = 0b11010000;
1978 let Inst{20-16} = Rm;
1979 let Inst{15-10} = 0;
1984 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1986 : BaseBaseAddSubCarry<isSub, regtype, asm,
1987 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1989 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1991 : BaseBaseAddSubCarry<isSub, regtype, asm,
1992 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1997 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1998 SDNode OpNode, SDNode OpNode_setflags> {
1999 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
2003 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
2009 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
2014 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
2021 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
2022 SDPatternOperator OpNode,
2023 RegisterClass in1regtype = regtype,
2024 RegisterClass in2regtype = regtype>
2025 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm),
2026 asm, "\t$Rd, $Rn, $Rm", "",
2027 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> {
2031 let Inst{30-21} = 0b0011010110;
2032 let Inst{20-16} = Rm;
2033 let Inst{15-14} = 0b00;
2034 let Inst{13-10} = opc;
2039 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
2040 SDPatternOperator OpNode>
2041 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
2042 let Inst{10} = isSigned;
2045 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
2046 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
2047 Sched<[WriteID32, ReadID, ReadID]> {
2050 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
2051 Sched<[WriteID64, ReadID, ReadID]> {
2056 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
2057 SDPatternOperator OpNode = null_frag>
2058 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
2059 Sched<[WriteIS, ReadI]> {
2060 let Inst{11-10} = shift_type;
2063 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
2064 def Wr : BaseShift<shift_type, GPR32, asm> {
2068 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
2072 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
2073 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
2074 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
2076 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
2077 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2079 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
2080 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2082 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
2083 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2085 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))),
2086 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2087 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2089 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))),
2090 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2091 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2094 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
2095 : InstAlias<asm#"\t$dst, $src1, $src2",
2096 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
2098 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
2099 RegisterClass addtype, string asm,
2101 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
2102 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
2107 let Inst{30-24} = 0b0011011;
2108 let Inst{23-21} = opc;
2109 let Inst{20-16} = Rm;
2110 let Inst{15} = isSub;
2111 let Inst{14-10} = Ra;
2116 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
2117 // MADD/MSUB generation is decided by MachineCombiner.cpp
2118 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
2119 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
2120 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2124 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
2125 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
2126 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
2131 class WideMulAccum<bit isSub, bits<3> opc, string asm,
2132 SDNode AccNode, SDNode ExtNode>
2133 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
2134 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
2135 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
2136 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2140 class MulHi<bits<3> opc, string asm, SDNode OpNode>
2141 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
2142 asm, "\t$Rd, $Rn, $Rm", "",
2143 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
2144 Sched<[WriteIM64, ReadIM, ReadIM]> {
2148 let Inst{31-24} = 0b10011011;
2149 let Inst{23-21} = opc;
2150 let Inst{20-16} = Rm;
2155 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
2156 // (i.e. all bits 1) but is ignored by the processor.
2157 let PostEncoderMethod = "fixMulHigh";
2160 class MulAccumWAlias<string asm, Instruction inst>
2161 : InstAlias<asm#"\t$dst, $src1, $src2",
2162 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
2163 class MulAccumXAlias<string asm, Instruction inst>
2164 : InstAlias<asm#"\t$dst, $src1, $src2",
2165 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
2166 class WideMulAccumAlias<string asm, Instruction inst>
2167 : InstAlias<asm#"\t$dst, $src1, $src2",
2168 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
2170 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
2171 SDPatternOperator OpNode, string asm>
2172 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
2173 asm, "\t$Rd, $Rn, $Rm", "",
2174 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
2175 Sched<[WriteISReg, ReadI, ReadISReg]> {
2181 let Inst{30-21} = 0b0011010110;
2182 let Inst{20-16} = Rm;
2183 let Inst{15-13} = 0b010;
2185 let Inst{11-10} = sz;
2188 let Predicates = [HasCRC];
2192 // Address generation.
2195 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
2196 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
2201 let Inst{31} = page;
2202 let Inst{30-29} = label{1-0};
2203 let Inst{28-24} = 0b10000;
2204 let Inst{23-5} = label{20-2};
2207 let DecoderMethod = "DecodeAdrInstruction";
2214 def movimm32_imm : Operand<i32> {
2215 let ParserMatchClass = AsmImmRange<0, 65535>;
2216 let EncoderMethod = "getMoveWideImmOpValue";
2217 let PrintMethod = "printImm";
2219 def movimm32_shift : Operand<i32> {
2220 let PrintMethod = "printShifter";
2221 let ParserMatchClass = MovImm32ShifterOperand;
2223 def movimm64_shift : Operand<i32> {
2224 let PrintMethod = "printShifter";
2225 let ParserMatchClass = MovImm64ShifterOperand;
2228 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2229 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2231 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
2232 asm, "\t$Rd, $imm$shift", "", []>,
2237 let Inst{30-29} = opc;
2238 let Inst{28-23} = 0b100101;
2239 let Inst{22-21} = shift{5-4};
2240 let Inst{20-5} = imm;
2243 let DecoderMethod = "DecodeMoveImmInstruction";
2246 multiclass MoveImmediate<bits<2> opc, string asm> {
2247 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
2251 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
2256 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2257 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2259 : I<(outs regtype:$Rd),
2260 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
2261 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
2262 Sched<[WriteI, ReadI]> {
2266 let Inst{30-29} = opc;
2267 let Inst{28-23} = 0b100101;
2268 let Inst{22-21} = shift{5-4};
2269 let Inst{20-5} = imm;
2272 let DecoderMethod = "DecodeMoveImmInstruction";
2275 multiclass InsertImmediate<bits<2> opc, string asm> {
2276 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
2280 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
2289 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
2290 string asm_inst, string asm_ops,
2291 dag inputs, dag pattern>
2292 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>,
2293 Sched<[WriteI, ReadI]> {
2296 let Inst{30} = isSub;
2297 let Inst{29} = setFlags;
2298 let Inst{28-24} = 0b10001;
2303 class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype,
2304 RegisterClass srcRegtype, addsub_shifted_imm immtype,
2305 string asm_inst, SDPatternOperator OpNode>
2306 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm",
2307 (ins srcRegtype:$Rn, immtype:$imm),
2308 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> {
2310 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
2311 let Inst{21-10} = imm{11-0};
2312 let DecoderMethod = "DecodeAddSubImmShift";
2315 class BaseAddSubRegPseudo<RegisterClass regtype,
2316 SDPatternOperator OpNode>
2317 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2318 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2319 Sched<[WriteI, ReadI, ReadI]>;
2321 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
2322 arith_shifted_reg shifted_regtype, string asm,
2323 SDPatternOperator OpNode>
2324 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2325 asm, "\t$Rd, $Rn, $Rm", "",
2326 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
2327 Sched<[WriteISReg, ReadI, ReadISReg]> {
2328 // The operands are in order to match the 'addr' MI operands, so we
2329 // don't need an encoder method and by-name matching. Just use the default
2330 // in-order handling. Since we're using by-order, make sure the names
2336 let Inst{30} = isSub;
2337 let Inst{29} = setFlags;
2338 let Inst{28-24} = 0b01011;
2339 let Inst{23-22} = shift{7-6};
2341 let Inst{20-16} = src2;
2342 let Inst{15-10} = shift{5-0};
2343 let Inst{9-5} = src1;
2344 let Inst{4-0} = dst;
2346 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2349 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
2350 RegisterClass src1Regtype, Operand src2Regtype,
2351 string asm, SDPatternOperator OpNode>
2352 : I<(outs dstRegtype:$R1),
2353 (ins src1Regtype:$R2, src2Regtype:$R3),
2354 asm, "\t$R1, $R2, $R3", "",
2355 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
2356 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2361 let Inst{30} = isSub;
2362 let Inst{29} = setFlags;
2363 let Inst{28-24} = 0b01011;
2364 let Inst{23-21} = 0b001;
2365 let Inst{20-16} = Rm;
2366 let Inst{15-13} = ext{5-3};
2367 let Inst{12-10} = ext{2-0};
2371 let DecoderMethod = "DecodeAddSubERegInstruction";
2374 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2375 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
2376 RegisterClass src1Regtype, RegisterClass src2Regtype,
2377 Operand ext_op, string asm>
2378 : I<(outs dstRegtype:$Rd),
2379 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
2380 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
2381 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2386 let Inst{30} = isSub;
2387 let Inst{29} = setFlags;
2388 let Inst{28-24} = 0b01011;
2389 let Inst{23-21} = 0b001;
2390 let Inst{20-16} = Rm;
2391 let Inst{15} = ext{5};
2392 let Inst{12-10} = ext{2-0};
2396 let DecoderMethod = "DecodeAddSubERegInstruction";
2399 // Aliases for register+register add/subtract.
2400 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
2401 RegisterClass src1Regtype, RegisterClass src2Regtype,
2403 : InstAlias<asm#"\t$dst, $src1, $src2",
2404 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
2407 multiclass AddSub<bit isSub, string mnemonic, string alias,
2408 SDPatternOperator OpNode = null_frag> {
2409 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2410 // Add/Subtract immediate
2411 // Increase the weight of the immediate variant to try to match it before
2412 // the extended register variant.
2413 // We used to match the register variant before the immediate when the
2414 // register argument could be implicitly zero-extended.
2415 let AddedComplexity = 6 in
2416 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
2420 let AddedComplexity = 6 in
2421 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
2426 // Add/Subtract register - Only used for CodeGen
2427 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2428 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2430 // Add/Subtract shifted register
2431 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
2435 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
2441 // Add/Subtract extended register
2442 let AddedComplexity = 1, hasSideEffects = 0 in {
2443 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
2444 arith_extended_reg32_i32, mnemonic, OpNode> {
2447 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
2448 arith_extended_reg32to64_i64, mnemonic, OpNode> {
2453 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
2454 arith_extendlsl64, mnemonic> {
2455 // UXTX and SXTX only.
2456 let Inst{14-13} = 0b11;
2460 // add Rd, Rb, -imm -> sub Rd, Rn, imm
2461 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2462 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
2463 addsub_shifted_imm32_neg:$imm), 0>;
2464 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2465 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
2466 addsub_shifted_imm64_neg:$imm), 0>;
2468 // Register/register aliases with no shift when SP is not used.
2469 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2470 GPR32, GPR32, GPR32, 0>;
2471 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2472 GPR64, GPR64, GPR64, 0>;
2474 // Register/register aliases with no shift when either the destination or
2475 // first source register is SP.
2476 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2477 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
2478 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2479 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
2480 def : AddSubRegAlias<mnemonic,
2481 !cast<Instruction>(NAME#"Xrx64"),
2482 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
2483 def : AddSubRegAlias<mnemonic,
2484 !cast<Instruction>(NAME#"Xrx64"),
2485 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
2488 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
2489 string alias, string cmpAlias> {
2490 let isCompare = 1, Defs = [NZCV] in {
2491 // Add/Subtract immediate
2492 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
2496 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
2501 // Add/Subtract register
2502 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2503 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2505 // Add/Subtract shifted register
2506 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
2510 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
2515 // Add/Subtract extended register
2516 let AddedComplexity = 1 in {
2517 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
2518 arith_extended_reg32_i32, mnemonic, OpNode> {
2521 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
2522 arith_extended_reg32_i64, mnemonic, OpNode> {
2527 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
2528 arith_extendlsl64, mnemonic> {
2529 // UXTX and SXTX only.
2530 let Inst{14-13} = 0b11;
2535 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
2536 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2537 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
2538 addsub_shifted_imm32_neg:$imm), 0>;
2539 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2540 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
2541 addsub_shifted_imm64_neg:$imm), 0>;
2544 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2545 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
2546 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2547 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
2548 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
2549 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2550 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
2551 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2552 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
2553 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
2554 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
2555 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
2556 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
2557 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
2559 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
2560 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2561 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
2562 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2563 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
2565 // Compare shorthands
2566 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
2567 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
2568 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
2569 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
2570 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
2571 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
2572 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
2573 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
2575 // Register/register aliases with no shift when SP is not used.
2576 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2577 GPR32, GPR32, GPR32, 0>;
2578 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2579 GPR64, GPR64, GPR64, 0>;
2581 // Register/register aliases with no shift when the first source register
2583 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2584 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
2585 def : AddSubRegAlias<mnemonic,
2586 !cast<Instruction>(NAME#"Xrx64"),
2587 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
2590 class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode>
2592 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4",
2593 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4),
2594 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> {
2598 let Inst{23-22} = 0b10;
2599 let Inst{21-16} = imm6;
2600 let Inst{15-14} = 0b00;
2601 let Inst{13-10} = imm4;
2602 let Unpredictable{15-14} = 0b11;
2605 class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode>
2606 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> {
2608 let Inst{29} = setsFlags;
2614 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2616 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
2618 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
2620 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
2621 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
2622 Sched<[WriteExtr, ReadExtrHi]> {
2628 let Inst{30-23} = 0b00100111;
2630 let Inst{20-16} = Rm;
2631 let Inst{15-10} = imm;
2636 multiclass ExtractImm<string asm> {
2637 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
2639 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
2642 // imm<5> must be zero.
2645 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
2647 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
2658 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2659 class BaseBitfieldImm<bits<2> opc,
2660 RegisterClass regtype, Operand imm_type, string asm>
2661 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
2662 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
2663 Sched<[WriteIS, ReadI]> {
2669 let Inst{30-29} = opc;
2670 let Inst{28-23} = 0b100110;
2671 let Inst{21-16} = immr;
2672 let Inst{15-10} = imms;
2677 multiclass BitfieldImm<bits<2> opc, string asm> {
2678 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2681 // imms<5> and immr<5> must be zero, else ReservedValue().
2685 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2691 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2692 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2693 RegisterClass regtype, Operand imm_type, string asm>
2694 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2696 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2697 Sched<[WriteIS, ReadI]> {
2703 let Inst{30-29} = opc;
2704 let Inst{28-23} = 0b100110;
2705 let Inst{21-16} = immr;
2706 let Inst{15-10} = imms;
2711 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2712 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2715 // imms<5> and immr<5> must be zero, else ReservedValue().
2719 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2729 // Logical (immediate)
2730 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2731 RegisterClass sregtype, Operand imm_type, string asm,
2733 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2734 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2735 Sched<[WriteI, ReadI]> {
2739 let Inst{30-29} = opc;
2740 let Inst{28-23} = 0b100100;
2741 let Inst{22} = imm{12};
2742 let Inst{21-16} = imm{11-6};
2743 let Inst{15-10} = imm{5-0};
2747 let DecoderMethod = "DecodeLogicalImmInstruction";
2750 // Logical (shifted register)
2751 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2752 logical_shifted_reg shifted_regtype, string asm,
2754 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2755 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2756 Sched<[WriteISReg, ReadI, ReadISReg]> {
2757 // The operands are in order to match the 'addr' MI operands, so we
2758 // don't need an encoder method and by-name matching. Just use the default
2759 // in-order handling. Since we're using by-order, make sure the names
2765 let Inst{30-29} = opc;
2766 let Inst{28-24} = 0b01010;
2767 let Inst{23-22} = shift{7-6};
2769 let Inst{20-16} = src2;
2770 let Inst{15-10} = shift{5-0};
2771 let Inst{9-5} = src1;
2772 let Inst{4-0} = dst;
2774 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2777 // Aliases for register+register logical instructions.
2778 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2779 : InstAlias<asm#"\t$dst, $src1, $src2",
2780 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2782 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2784 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2785 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2786 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2787 logical_imm32:$imm))]> {
2789 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2791 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2792 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2793 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2794 logical_imm64:$imm))]> {
2798 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2799 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2800 logical_imm32_not:$imm), 0>;
2801 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2802 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2803 logical_imm64_not:$imm), 0>;
2806 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2808 let isCompare = 1, Defs = [NZCV] in {
2809 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2810 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2812 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2814 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2815 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2818 } // end Defs = [NZCV]
2820 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2821 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2822 logical_imm32_not:$imm), 0>;
2823 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2824 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2825 logical_imm64_not:$imm), 0>;
2828 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2829 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2830 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2831 Sched<[WriteI, ReadI, ReadI]>;
2833 // Split from LogicalImm as not all instructions have both.
2834 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2835 SDPatternOperator OpNode> {
2836 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2837 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2838 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2841 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2842 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2843 logical_shifted_reg32:$Rm))]> {
2846 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2847 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2848 logical_shifted_reg64:$Rm))]> {
2852 def : LogicalRegAlias<mnemonic,
2853 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2854 def : LogicalRegAlias<mnemonic,
2855 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2858 // Split from LogicalReg to allow setting NZCV Defs
2859 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2860 SDPatternOperator OpNode = null_frag> {
2861 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2862 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2863 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2865 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2866 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2869 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2870 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2875 def : LogicalRegAlias<mnemonic,
2876 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2877 def : LogicalRegAlias<mnemonic,
2878 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2882 // Conditionally set flags
2885 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2886 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2887 string mnemonic, SDNode OpNode>
2888 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2889 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2890 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2891 (i32 imm:$cond), NZCV))]>,
2892 Sched<[WriteI, ReadI]> {
2902 let Inst{29-21} = 0b111010010;
2903 let Inst{20-16} = imm;
2904 let Inst{15-12} = cond;
2905 let Inst{11-10} = 0b10;
2908 let Inst{3-0} = nzcv;
2911 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2912 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2914 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2915 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2916 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2917 (i32 imm:$cond), NZCV))]>,
2918 Sched<[WriteI, ReadI, ReadI]> {
2928 let Inst{29-21} = 0b111010010;
2929 let Inst{20-16} = Rm;
2930 let Inst{15-12} = cond;
2931 let Inst{11-10} = 0b00;
2934 let Inst{3-0} = nzcv;
2937 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2938 // immediate operand variants
2939 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2942 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2945 // register operand variants
2946 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2949 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2955 // Conditional select
2958 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2959 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2960 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2962 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2963 Sched<[WriteI, ReadI, ReadI]> {
2972 let Inst{29-21} = 0b011010100;
2973 let Inst{20-16} = Rm;
2974 let Inst{15-12} = cond;
2975 let Inst{11-10} = op2;
2980 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2981 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2984 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2989 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2991 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2992 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2994 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2995 (i32 imm:$cond), NZCV))]>,
2996 Sched<[WriteI, ReadI, ReadI]> {
3005 let Inst{29-21} = 0b011010100;
3006 let Inst{20-16} = Rm;
3007 let Inst{15-12} = cond;
3008 let Inst{11-10} = op2;
3013 def inv_cond_XFORM : SDNodeXForm<imm, [{
3014 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
3015 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
3019 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
3020 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
3023 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
3027 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
3028 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
3029 (inv_cond_XFORM imm:$cond))>;
3031 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
3032 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
3033 (inv_cond_XFORM imm:$cond))>;
3037 // Special Mask Value
3039 def maski8_or_more : Operand<i32>,
3040 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
3042 def maski16_or_more : Operand<i32>,
3043 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
3051 // (unsigned immediate)
3052 // Indexed for 8-bit registers. offset is in range [0,4095].
3053 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
3054 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
3055 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
3056 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
3057 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
3059 def gi_am_indexed8 :
3060 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
3061 GIComplexPatternEquiv<am_indexed8>;
3062 def gi_am_indexed16 :
3063 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
3064 GIComplexPatternEquiv<am_indexed16>;
3065 def gi_am_indexed32 :
3066 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
3067 GIComplexPatternEquiv<am_indexed32>;
3068 def gi_am_indexed64 :
3069 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
3070 GIComplexPatternEquiv<am_indexed64>;
3071 def gi_am_indexed128 :
3072 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
3073 GIComplexPatternEquiv<am_indexed128>;
3075 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
3076 let Name = "UImm12Offset" # Scale;
3077 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
3078 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
3079 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
3082 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
3083 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
3084 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
3085 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
3086 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
3088 class uimm12_scaled<int Scale> : Operand<i64> {
3089 let ParserMatchClass
3090 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
3092 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
3093 let PrintMethod = "printUImm12Offset<" # Scale # ">";
3096 def uimm12s1 : uimm12_scaled<1>;
3097 def uimm12s2 : uimm12_scaled<2>;
3098 def uimm12s4 : uimm12_scaled<4>;
3099 def uimm12s8 : uimm12_scaled<8>;
3100 def uimm12s16 : uimm12_scaled<16>;
3102 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3103 string asm, list<dag> pattern>
3104 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3110 let Inst{31-30} = sz;
3111 let Inst{29-27} = 0b111;
3113 let Inst{25-24} = 0b01;
3114 let Inst{23-22} = opc;
3115 let Inst{21-10} = offset;
3119 let DecoderMethod = "DecodeUnsignedLdStInstruction";
3122 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3123 Operand indextype, string asm, list<dag> pattern> {
3124 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3125 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
3126 (ins GPR64sp:$Rn, indextype:$offset),
3130 def : InstAlias<asm # "\t$Rt, [$Rn]",
3131 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3134 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3135 Operand indextype, string asm, list<dag> pattern> {
3136 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3137 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3138 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3142 def : InstAlias<asm # "\t$Rt, [$Rn]",
3143 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3146 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
3147 // substitute zero-registers automatically.
3149 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
3151 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3152 Operand indextype, string asm, list<dag> pattern> {
3153 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3154 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3155 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3159 def : InstAlias<asm # "\t$Rt, [$Rn]",
3160 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3163 def PrefetchOperand : AsmOperandClass {
3164 let Name = "Prefetch";
3165 let ParserMethod = "tryParsePrefetch";
3167 def prfop : Operand<i32> {
3168 let PrintMethod = "printPrefetchOp";
3169 let ParserMatchClass = PrefetchOperand;
3172 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3173 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
3174 : BaseLoadStoreUI<sz, V, opc,
3175 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
3183 // Load literal address: 19-bit immediate. The low two bits of the target
3184 // offset are implied zero and so are not part of the immediate.
3185 def am_ldrlit : Operand<iPTR> {
3186 let EncoderMethod = "getLoadLiteralOpValue";
3187 let DecoderMethod = "DecodePCRelLabel19";
3188 let PrintMethod = "printAlignedLabel";
3189 let ParserMatchClass = PCRelLabel19Operand;
3190 let OperandType = "OPERAND_PCREL";
3193 let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
3194 class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
3195 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
3196 asm, "\t$Rt, $label", "", pat>,
3200 let Inst{31-30} = opc;
3201 let Inst{29-27} = 0b011;
3203 let Inst{25-24} = 0b00;
3204 let Inst{23-5} = label;
3208 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3209 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
3210 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
3211 asm, "\t$Rt, $label", "", pat>,
3215 let Inst{31-30} = opc;
3216 let Inst{29-27} = 0b011;
3218 let Inst{25-24} = 0b00;
3219 let Inst{23-5} = label;
3224 // Load/store register offset
3227 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
3228 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
3229 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
3230 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
3231 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
3233 def gi_ro_Xindexed8 :
3234 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">,
3235 GIComplexPatternEquiv<ro_Xindexed8>;
3236 def gi_ro_Xindexed16 :
3237 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">,
3238 GIComplexPatternEquiv<ro_Xindexed16>;
3239 def gi_ro_Xindexed32 :
3240 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">,
3241 GIComplexPatternEquiv<ro_Xindexed32>;
3242 def gi_ro_Xindexed64 :
3243 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">,
3244 GIComplexPatternEquiv<ro_Xindexed64>;
3245 def gi_ro_Xindexed128 :
3246 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">,
3247 GIComplexPatternEquiv<ro_Xindexed128>;
3249 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
3250 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
3251 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
3252 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
3253 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
3255 def gi_ro_Windexed8 :
3256 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">,
3257 GIComplexPatternEquiv<ro_Windexed8>;
3258 def gi_ro_Windexed16 :
3259 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">,
3260 GIComplexPatternEquiv<ro_Windexed16>;
3261 def gi_ro_Windexed32 :
3262 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">,
3263 GIComplexPatternEquiv<ro_Windexed32>;
3264 def gi_ro_Windexed64 :
3265 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">,
3266 GIComplexPatternEquiv<ro_Windexed64>;
3267 def gi_ro_Windexed128 :
3268 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">,
3269 GIComplexPatternEquiv<ro_Windexed128>;
3271 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
3272 let Name = "Mem" # Reg # "Extend" # Width;
3273 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
3274 let RenderMethod = "addMemExtendOperands";
3275 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
3278 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
3279 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3280 // the trivial shift.
3281 let RenderMethod = "addMemExtend8Operands";
3283 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
3284 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
3285 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
3286 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
3288 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
3289 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3290 // the trivial shift.
3291 let RenderMethod = "addMemExtend8Operands";
3293 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
3294 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
3295 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
3296 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
3298 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
3300 let ParserMatchClass = ParserClass;
3301 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
3302 let DecoderMethod = "DecodeMemExtend";
3303 let EncoderMethod = "getMemExtendOpValue";
3304 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
3307 def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
3308 def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
3309 def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
3310 def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
3311 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
3313 def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
3314 def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
3315 def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
3316 def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
3317 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
3319 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
3320 Operand wextend, Operand xextend> {
3321 // CodeGen-level pattern covering the entire addressing mode.
3322 ComplexPattern Wpat = windex;
3323 ComplexPattern Xpat = xindex;
3325 // Asm-level Operand covering the valid "uxtw #3" style syntax.
3326 Operand Wext = wextend;
3327 Operand Xext = xextend;
3330 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
3331 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
3332 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
3333 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
3334 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
3337 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3338 string asm, dag ins, dag outs, list<dag> pat>
3339 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3344 let Inst{31-30} = sz;
3345 let Inst{29-27} = 0b111;
3347 let Inst{25-24} = 0b00;
3348 let Inst{23-22} = opc;
3350 let Inst{20-16} = Rm;
3351 let Inst{15} = extend{1}; // sign extend Rm?
3353 let Inst{12} = extend{0}; // do shift?
3354 let Inst{11-10} = 0b10;
3359 class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST>
3360 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
3361 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3363 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3364 string asm, ValueType Ty, SDPatternOperator loadop> {
3365 let AddedComplexity = 10 in
3366 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
3368 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3369 [(set (Ty regtype:$Rt),
3370 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3371 ro_Wextend8:$extend)))]>,
3372 Sched<[WriteLDIdx, ReadAdrBase]> {
3376 let AddedComplexity = 10 in
3377 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
3379 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3380 [(set (Ty regtype:$Rt),
3381 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3382 ro_Xextend8:$extend)))]>,
3383 Sched<[WriteLDIdx, ReadAdrBase]> {
3387 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3390 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3391 string asm, ValueType Ty, SDPatternOperator storeop> {
3392 let AddedComplexity = 10 in
3393 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3394 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3395 [(storeop (Ty regtype:$Rt),
3396 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3397 ro_Wextend8:$extend))]>,
3398 Sched<[WriteSTIdx, ReadAdrBase]> {
3402 let AddedComplexity = 10 in
3403 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3404 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3405 [(storeop (Ty regtype:$Rt),
3406 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3407 ro_Xextend8:$extend))]>,
3408 Sched<[WriteSTIdx, ReadAdrBase]> {
3412 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3415 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3416 string asm, dag ins, dag outs, list<dag> pat>
3417 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3422 let Inst{31-30} = sz;
3423 let Inst{29-27} = 0b111;
3425 let Inst{25-24} = 0b00;
3426 let Inst{23-22} = opc;
3428 let Inst{20-16} = Rm;
3429 let Inst{15} = extend{1}; // sign extend Rm?
3431 let Inst{12} = extend{0}; // do shift?
3432 let Inst{11-10} = 0b10;
3437 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3438 string asm, ValueType Ty, SDPatternOperator loadop> {
3439 let AddedComplexity = 10 in
3440 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3441 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3442 [(set (Ty regtype:$Rt),
3443 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3444 ro_Wextend16:$extend)))]>,
3445 Sched<[WriteLDIdx, ReadAdrBase]> {
3449 let AddedComplexity = 10 in
3450 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3451 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3452 [(set (Ty regtype:$Rt),
3453 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3454 ro_Xextend16:$extend)))]>,
3455 Sched<[WriteLDIdx, ReadAdrBase]> {
3459 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3462 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3463 string asm, ValueType Ty, SDPatternOperator storeop> {
3464 let AddedComplexity = 10 in
3465 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3466 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3467 [(storeop (Ty regtype:$Rt),
3468 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3469 ro_Wextend16:$extend))]>,
3470 Sched<[WriteSTIdx, ReadAdrBase]> {
3474 let AddedComplexity = 10 in
3475 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3476 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3477 [(storeop (Ty regtype:$Rt),
3478 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3479 ro_Xextend16:$extend))]>,
3480 Sched<[WriteSTIdx, ReadAdrBase]> {
3484 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3487 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3488 string asm, dag ins, dag outs, list<dag> pat>
3489 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3494 let Inst{31-30} = sz;
3495 let Inst{29-27} = 0b111;
3497 let Inst{25-24} = 0b00;
3498 let Inst{23-22} = opc;
3500 let Inst{20-16} = Rm;
3501 let Inst{15} = extend{1}; // sign extend Rm?
3503 let Inst{12} = extend{0}; // do shift?
3504 let Inst{11-10} = 0b10;
3509 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3510 string asm, ValueType Ty, SDPatternOperator loadop> {
3511 let AddedComplexity = 10 in
3512 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3513 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3514 [(set (Ty regtype:$Rt),
3515 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3516 ro_Wextend32:$extend)))]>,
3517 Sched<[WriteLDIdx, ReadAdrBase]> {
3521 let AddedComplexity = 10 in
3522 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3523 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3524 [(set (Ty regtype:$Rt),
3525 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3526 ro_Xextend32:$extend)))]>,
3527 Sched<[WriteLDIdx, ReadAdrBase]> {
3531 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3534 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3535 string asm, ValueType Ty, SDPatternOperator storeop> {
3536 let AddedComplexity = 10 in
3537 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3538 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3539 [(storeop (Ty regtype:$Rt),
3540 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3541 ro_Wextend32:$extend))]>,
3542 Sched<[WriteSTIdx, ReadAdrBase]> {
3546 let AddedComplexity = 10 in
3547 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3548 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3549 [(storeop (Ty regtype:$Rt),
3550 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3551 ro_Xextend32:$extend))]>,
3552 Sched<[WriteSTIdx, ReadAdrBase]> {
3556 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3559 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3560 string asm, dag ins, dag outs, list<dag> pat>
3561 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3566 let Inst{31-30} = sz;
3567 let Inst{29-27} = 0b111;
3569 let Inst{25-24} = 0b00;
3570 let Inst{23-22} = opc;
3572 let Inst{20-16} = Rm;
3573 let Inst{15} = extend{1}; // sign extend Rm?
3575 let Inst{12} = extend{0}; // do shift?
3576 let Inst{11-10} = 0b10;
3581 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3582 string asm, ValueType Ty, SDPatternOperator loadop> {
3583 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3584 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3585 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3586 [(set (Ty regtype:$Rt),
3587 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3588 ro_Wextend64:$extend)))]>,
3589 Sched<[WriteLDIdx, ReadAdrBase]> {
3593 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3594 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3595 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3596 [(set (Ty regtype:$Rt),
3597 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3598 ro_Xextend64:$extend)))]>,
3599 Sched<[WriteLDIdx, ReadAdrBase]> {
3603 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3606 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3607 string asm, ValueType Ty, SDPatternOperator storeop> {
3608 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3609 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3610 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3611 [(storeop (Ty regtype:$Rt),
3612 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3613 ro_Wextend64:$extend))]>,
3614 Sched<[WriteSTIdx, ReadAdrBase]> {
3618 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3619 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3620 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3621 [(storeop (Ty regtype:$Rt),
3622 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3623 ro_Xextend64:$extend))]>,
3624 Sched<[WriteSTIdx, ReadAdrBase]> {
3628 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3631 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3632 string asm, dag ins, dag outs, list<dag> pat>
3633 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3638 let Inst{31-30} = sz;
3639 let Inst{29-27} = 0b111;
3641 let Inst{25-24} = 0b00;
3642 let Inst{23-22} = opc;
3644 let Inst{20-16} = Rm;
3645 let Inst{15} = extend{1}; // sign extend Rm?
3647 let Inst{12} = extend{0}; // do shift?
3648 let Inst{11-10} = 0b10;
3653 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3654 string asm, ValueType Ty, SDPatternOperator loadop> {
3655 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3656 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3657 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3658 [(set (Ty regtype:$Rt),
3659 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
3660 ro_Wextend128:$extend)))]>,
3661 Sched<[WriteLDIdx, ReadAdrBase]> {
3665 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3666 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3667 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3668 [(set (Ty regtype:$Rt),
3669 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
3670 ro_Xextend128:$extend)))]>,
3671 Sched<[WriteLDIdx, ReadAdrBase]> {
3675 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3678 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3679 string asm, ValueType Ty, SDPatternOperator storeop> {
3680 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3681 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3682 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3684 Sched<[WriteSTIdx, ReadAdrBase]> {
3688 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3689 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3690 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3692 Sched<[WriteSTIdx, ReadAdrBase]> {
3696 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3699 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3700 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
3701 string asm, list<dag> pat>
3702 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
3708 let Inst{31-30} = sz;
3709 let Inst{29-27} = 0b111;
3711 let Inst{25-24} = 0b00;
3712 let Inst{23-22} = opc;
3714 let Inst{20-16} = Rm;
3715 let Inst{15} = extend{1}; // sign extend Rm?
3717 let Inst{12} = extend{0}; // do shift?
3718 let Inst{11-10} = 0b10;
3723 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
3724 def roW : BasePrefetchRO<sz, V, opc, (outs),
3725 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3726 asm, [(AArch64Prefetch imm:$Rt,
3727 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3728 ro_Wextend64:$extend))]> {
3732 def roX : BasePrefetchRO<sz, V, opc, (outs),
3733 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3734 asm, [(AArch64Prefetch imm:$Rt,
3735 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3736 ro_Xextend64:$extend))]> {
3740 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3741 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3742 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3746 // Load/store unscaled immediate
3749 def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3750 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3751 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3752 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3753 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3755 def gi_am_unscaled8 :
3756 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
3757 GIComplexPatternEquiv<am_unscaled8>;
3758 def gi_am_unscaled16 :
3759 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
3760 GIComplexPatternEquiv<am_unscaled16>;
3761 def gi_am_unscaled32 :
3762 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
3763 GIComplexPatternEquiv<am_unscaled32>;
3764 def gi_am_unscaled64 :
3765 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
3766 GIComplexPatternEquiv<am_unscaled64>;
3767 def gi_am_unscaled128 :
3768 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
3769 GIComplexPatternEquiv<am_unscaled128>;
3772 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3773 string asm, list<dag> pattern>
3774 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3778 let Inst{31-30} = sz;
3779 let Inst{29-27} = 0b111;
3781 let Inst{25-24} = 0b00;
3782 let Inst{23-22} = opc;
3784 let Inst{20-12} = offset;
3785 let Inst{11-10} = 0b00;
3789 let DecoderMethod = "DecodeSignedLdStInstruction";
3792 // Armv8.4 LDAPR & STLR with Immediate Offset instruction
3793 multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3794 RegisterOperand regtype > {
3795 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),
3796 (ins GPR64sp:$Rn, simm9:$offset), asm, []>,
3801 def : InstAlias<asm # "\t$Rt, [$Rn]",
3802 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3805 multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3806 RegisterOperand regtype > {
3807 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),
3808 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3814 def : InstAlias<asm # "\t$Rt, [$Rn]",
3815 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3818 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3819 string asm, list<dag> pattern> {
3820 let AddedComplexity = 1 in // try this before LoadUI
3821 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3822 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3825 def : InstAlias<asm # "\t$Rt, [$Rn]",
3826 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3829 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3830 string asm, list<dag> pattern> {
3831 let AddedComplexity = 1 in // try this before StoreUI
3832 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3833 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3837 def : InstAlias<asm # "\t$Rt, [$Rn]",
3838 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3841 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3843 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3844 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3845 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3849 def : InstAlias<asm # "\t$Rt, [$Rn]",
3850 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3854 // Load/store unscaled immediate, unprivileged
3857 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3858 dag oops, dag iops, string asm>
3859 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3863 let Inst{31-30} = sz;
3864 let Inst{29-27} = 0b111;
3866 let Inst{25-24} = 0b00;
3867 let Inst{23-22} = opc;
3869 let Inst{20-12} = offset;
3870 let Inst{11-10} = 0b10;
3874 let DecoderMethod = "DecodeSignedLdStInstruction";
3877 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3878 RegisterClass regtype, string asm> {
3879 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3880 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3881 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3884 def : InstAlias<asm # "\t$Rt, [$Rn]",
3885 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3888 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3889 RegisterClass regtype, string asm> {
3890 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3891 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3892 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3896 def : InstAlias<asm # "\t$Rt, [$Rn]",
3897 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3901 // Load/store pre-indexed
3904 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3905 string asm, string cstr, list<dag> pat>
3906 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3910 let Inst{31-30} = sz;
3911 let Inst{29-27} = 0b111;
3913 let Inst{25-24} = 0;
3914 let Inst{23-22} = opc;
3916 let Inst{20-12} = offset;
3917 let Inst{11-10} = 0b11;
3921 let DecoderMethod = "DecodeSignedLdStInstruction";
3924 let hasSideEffects = 0 in {
3925 let mayStore = 0, mayLoad = 1 in
3926 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3928 : BaseLoadStorePreIdx<sz, V, opc,
3929 (outs GPR64sp:$wback, regtype:$Rt),
3930 (ins GPR64sp:$Rn, simm9:$offset), asm,
3931 "$Rn = $wback,@earlyclobber $wback", []>,
3932 Sched<[WriteLD, WriteAdr]>;
3934 let mayStore = 1, mayLoad = 0 in
3935 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3936 string asm, SDPatternOperator storeop, ValueType Ty>
3937 : BaseLoadStorePreIdx<sz, V, opc,
3938 (outs GPR64sp:$wback),
3939 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3940 asm, "$Rn = $wback,@earlyclobber $wback",
3941 [(set GPR64sp:$wback,
3942 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3943 Sched<[WriteAdr, WriteST]>;
3944 } // hasSideEffects = 0
3947 // Load/store post-indexed
3950 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3951 string asm, string cstr, list<dag> pat>
3952 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3956 let Inst{31-30} = sz;
3957 let Inst{29-27} = 0b111;
3959 let Inst{25-24} = 0b00;
3960 let Inst{23-22} = opc;
3962 let Inst{20-12} = offset;
3963 let Inst{11-10} = 0b01;
3967 let DecoderMethod = "DecodeSignedLdStInstruction";
3970 let hasSideEffects = 0 in {
3971 let mayStore = 0, mayLoad = 1 in
3972 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3974 : BaseLoadStorePostIdx<sz, V, opc,
3975 (outs GPR64sp:$wback, regtype:$Rt),
3976 (ins GPR64sp:$Rn, simm9:$offset),
3977 asm, "$Rn = $wback,@earlyclobber $wback", []>,
3978 Sched<[WriteLD, WriteAdr]>;
3980 let mayStore = 1, mayLoad = 0 in
3981 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3982 string asm, SDPatternOperator storeop, ValueType Ty>
3983 : BaseLoadStorePostIdx<sz, V, opc,
3984 (outs GPR64sp:$wback),
3985 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3986 asm, "$Rn = $wback,@earlyclobber $wback",
3987 [(set GPR64sp:$wback,
3988 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3989 Sched<[WriteAdr, WriteST]>;
3990 } // hasSideEffects = 0
3997 // (indexed, offset)
3999 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
4001 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4006 let Inst{31-30} = opc;
4007 let Inst{29-27} = 0b101;
4009 let Inst{25-23} = 0b010;
4011 let Inst{21-15} = offset;
4012 let Inst{14-10} = Rt2;
4016 let DecoderMethod = "DecodePairLdStInstruction";
4019 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4020 Operand indextype, string asm> {
4021 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4022 def i : BaseLoadStorePairOffset<opc, V, 1,
4023 (outs regtype:$Rt, regtype:$Rt2),
4024 (ins GPR64sp:$Rn, indextype:$offset), asm>,
4025 Sched<[WriteLD, WriteLDHi]>;
4027 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4028 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4033 multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4034 Operand indextype, string asm> {
4035 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
4036 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
4037 (ins regtype:$Rt, regtype:$Rt2,
4038 GPR64sp:$Rn, indextype:$offset),
4042 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4043 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4048 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4050 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
4055 let Inst{31-30} = opc;
4056 let Inst{29-27} = 0b101;
4058 let Inst{25-23} = 0b011;
4060 let Inst{21-15} = offset;
4061 let Inst{14-10} = Rt2;
4065 let DecoderMethod = "DecodePairLdStInstruction";
4068 let hasSideEffects = 0 in {
4069 let mayStore = 0, mayLoad = 1 in
4070 class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4071 Operand indextype, string asm>
4072 : BaseLoadStorePairPreIdx<opc, V, 1,
4073 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4074 (ins GPR64sp:$Rn, indextype:$offset), asm>,
4075 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
4077 let mayStore = 1, mayLoad = 0 in
4078 class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4079 Operand indextype, string asm>
4080 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
4081 (ins regtype:$Rt, regtype:$Rt2,
4082 GPR64sp:$Rn, indextype:$offset),
4084 Sched<[WriteAdr, WriteSTP]>;
4085 } // hasSideEffects = 0
4089 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4091 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
4096 let Inst{31-30} = opc;
4097 let Inst{29-27} = 0b101;
4099 let Inst{25-23} = 0b001;
4101 let Inst{21-15} = offset;
4102 let Inst{14-10} = Rt2;
4106 let DecoderMethod = "DecodePairLdStInstruction";
4109 let hasSideEffects = 0 in {
4110 let mayStore = 0, mayLoad = 1 in
4111 class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4112 Operand idxtype, string asm>
4113 : BaseLoadStorePairPostIdx<opc, V, 1,
4114 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4115 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
4116 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
4118 let mayStore = 1, mayLoad = 0 in
4119 class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4120 Operand idxtype, string asm>
4121 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
4122 (ins regtype:$Rt, regtype:$Rt2,
4123 GPR64sp:$Rn, idxtype:$offset),
4125 Sched<[WriteAdr, WriteSTP]>;
4126 } // hasSideEffects = 0
4130 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
4132 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4137 let Inst{31-30} = opc;
4138 let Inst{29-27} = 0b101;
4140 let Inst{25-23} = 0b000;
4142 let Inst{21-15} = offset;
4143 let Inst{14-10} = Rt2;
4147 let DecoderMethod = "DecodePairLdStInstruction";
4150 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
4151 Operand indextype, string asm> {
4152 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4153 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
4154 (outs regtype:$Rt, regtype:$Rt2),
4155 (ins GPR64sp:$Rn, indextype:$offset), asm>,
4156 Sched<[WriteLD, WriteLDHi]>;
4159 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4160 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4164 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
4165 Operand indextype, string asm> {
4166 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
4167 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
4168 (ins regtype:$Rt, regtype:$Rt2,
4169 GPR64sp:$Rn, indextype:$offset),
4173 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4174 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4179 // Load/store exclusive
4182 // True exclusive operations write to and/or read from the system's exclusive
4183 // monitors, which as far as a compiler is concerned can be modelled as a
4184 // random shared memory address. Hence LoadExclusive mayStore.
4186 // Since these instructions have the undefined register bits set to 1 in
4187 // their canonical form, we need a post encoder method to set those bits
4188 // to 1 when encoding these instructions. We do this using the
4189 // fixLoadStoreExclusive function. This function has template parameters:
4191 // fixLoadStoreExclusive<int hasRs, int hasRt2>
4193 // hasRs indicates that the instruction uses the Rs field, so we won't set
4194 // it to 1 (and the same for Rt2). We don't need template parameters for
4195 // the other register fields since Rt and Rn are always used.
4197 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
4198 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4199 dag oops, dag iops, string asm, string operands>
4200 : I<oops, iops, asm, operands, "", []> {
4201 let Inst{31-30} = sz;
4202 let Inst{29-24} = 0b001000;
4208 let DecoderMethod = "DecodeExclusiveLdStInstruction";
4211 // Neither Rs nor Rt2 operands.
4212 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4213 dag oops, dag iops, string asm, string operands>
4214 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
4217 let Inst{20-16} = 0b11111;
4218 let Unpredictable{20-16} = 0b11111;
4219 let Inst{14-10} = 0b11111;
4220 let Unpredictable{14-10} = 0b11111;
4224 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
4227 // Simple load acquires don't set the exclusive monitor
4228 let mayLoad = 1, mayStore = 0 in
4229 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4230 RegisterClass regtype, string asm>
4231 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4232 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4235 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4236 RegisterClass regtype, string asm>
4237 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4238 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4241 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4242 RegisterClass regtype, string asm>
4243 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4244 (outs regtype:$Rt, regtype:$Rt2),
4245 (ins GPR64sp0:$Rn), asm,
4246 "\t$Rt, $Rt2, [$Rn]">,
4247 Sched<[WriteLD, WriteLDHi]> {
4251 let Inst{14-10} = Rt2;
4255 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
4258 // Simple store release operations do not check the exclusive monitor.
4259 let mayLoad = 0, mayStore = 1 in
4260 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4261 RegisterClass regtype, string asm>
4262 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
4263 (ins regtype:$Rt, GPR64sp0:$Rn),
4264 asm, "\t$Rt, [$Rn]">,
4267 let mayLoad = 1, mayStore = 1 in
4268 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4269 RegisterClass regtype, string asm>
4270 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
4271 (ins regtype:$Rt, GPR64sp0:$Rn),
4272 asm, "\t$Ws, $Rt, [$Rn]">,
4277 let Inst{20-16} = Ws;
4281 let Constraints = "@earlyclobber $Ws";
4282 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
4285 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4286 RegisterClass regtype, string asm>
4287 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4289 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
4290 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
4296 let Inst{20-16} = Ws;
4297 let Inst{14-10} = Rt2;
4301 let Constraints = "@earlyclobber $Ws";
4304 // Armv8.5-A Memory Tagging Extension
4305 class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn,
4306 string asm_opnds, string cstr, dag oops, dag iops>
4307 : I<oops, iops, asm_insn, asm_opnds, cstr, []>,
4311 let Inst{31-24} = 0b11011001;
4312 let Inst{23-22} = opc1;
4314 // Inst{20-12} defined by subclass
4315 let Inst{11-10} = opc2;
4317 // Inst{4-0} defined by subclass
4320 class MemTagVector<bit Load, string asm_insn, string asm_opnds,
4322 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,
4326 let Inst{20-12} = 0b000000000;
4332 class MemTagLoad<string asm_insn, string asm_opnds>
4333 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback",
4334 (outs GPR64:$wback),
4335 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> {
4339 let Inst{20-12} = offset;
4345 class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn,
4346 string asm_opnds, string cstr, dag oops, dag iops>
4347 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> {
4351 let Inst{20-12} = offset;
4357 multiclass MemTagStore<bits<2> opc1, string insn> {
4359 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",
4360 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4362 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",
4364 (outs GPR64sp:$wback),
4365 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4367 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",
4369 (outs GPR64sp:$wback),
4370 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4372 def : InstAlias<insn # "\t$Rt, [$Rn]",
4373 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>;
4377 // Exception generation
4380 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
4381 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
4382 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>,
4385 let Inst{31-24} = 0b11010100;
4386 let Inst{23-21} = op1;
4387 let Inst{20-5} = imm;
4388 let Inst{4-2} = 0b000;
4393 // UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm.
4395 let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in {
4396 class UDFType<bits<16> opc, string asm>
4397 : I<(outs), (ins uimm16:$imm),
4398 asm, "\t$imm", "", []>,
4401 let Inst{31-16} = opc;
4402 let Inst{15-0} = imm;
4405 let Predicates = [HasFPARMv8] in {
4408 // Floating point to integer conversion
4411 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
4412 RegisterClass srcType, RegisterClass dstType,
4413 string asm, list<dag> pattern>
4414 : I<(outs dstType:$Rd), (ins srcType:$Rn),
4415 asm, "\t$Rd, $Rn", "", pattern>,
4416 Sched<[WriteFCvt]> {
4419 let Inst{30-29} = 0b00;
4420 let Inst{28-24} = 0b11110;
4421 let Inst{23-22} = type;
4423 let Inst{20-19} = rmode;
4424 let Inst{18-16} = opcode;
4425 let Inst{15-10} = 0;
4430 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4431 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
4432 RegisterClass srcType, RegisterClass dstType,
4433 Operand immType, string asm, list<dag> pattern>
4434 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4435 asm, "\t$Rd, $Rn, $scale", "", pattern>,
4436 Sched<[WriteFCvt]> {
4440 let Inst{30-29} = 0b00;
4441 let Inst{28-24} = 0b11110;
4442 let Inst{23-22} = type;
4444 let Inst{20-19} = rmode;
4445 let Inst{18-16} = opcode;
4446 let Inst{15-10} = scale;
4451 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
4452 SDPatternOperator OpN> {
4453 // Unscaled half-precision to 32-bit
4454 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
4455 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4456 let Inst{31} = 0; // 32-bit GPR flag
4457 let Predicates = [HasFullFP16];
4460 // Unscaled half-precision to 64-bit
4461 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
4462 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4463 let Inst{31} = 1; // 64-bit GPR flag
4464 let Predicates = [HasFullFP16];
4467 // Unscaled single-precision to 32-bit
4468 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
4469 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
4470 let Inst{31} = 0; // 32-bit GPR flag
4473 // Unscaled single-precision to 64-bit
4474 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
4475 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
4476 let Inst{31} = 1; // 64-bit GPR flag
4479 // Unscaled double-precision to 32-bit
4480 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
4481 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4482 let Inst{31} = 0; // 32-bit GPR flag
4485 // Unscaled double-precision to 64-bit
4486 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
4487 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4488 let Inst{31} = 1; // 64-bit GPR flag
4492 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
4493 SDPatternOperator OpN> {
4494 // Scaled half-precision to 32-bit
4495 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
4496 fixedpoint_f16_i32, asm,
4497 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn),
4498 fixedpoint_f16_i32:$scale)))]> {
4499 let Inst{31} = 0; // 32-bit GPR flag
4501 let Predicates = [HasFullFP16];
4504 // Scaled half-precision to 64-bit
4505 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
4506 fixedpoint_f16_i64, asm,
4507 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn),
4508 fixedpoint_f16_i64:$scale)))]> {
4509 let Inst{31} = 1; // 64-bit GPR flag
4510 let Predicates = [HasFullFP16];
4513 // Scaled single-precision to 32-bit
4514 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
4515 fixedpoint_f32_i32, asm,
4516 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
4517 fixedpoint_f32_i32:$scale)))]> {
4518 let Inst{31} = 0; // 32-bit GPR flag
4522 // Scaled single-precision to 64-bit
4523 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
4524 fixedpoint_f32_i64, asm,
4525 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
4526 fixedpoint_f32_i64:$scale)))]> {
4527 let Inst{31} = 1; // 64-bit GPR flag
4530 // Scaled double-precision to 32-bit
4531 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
4532 fixedpoint_f64_i32, asm,
4533 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
4534 fixedpoint_f64_i32:$scale)))]> {
4535 let Inst{31} = 0; // 32-bit GPR flag
4539 // Scaled double-precision to 64-bit
4540 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
4541 fixedpoint_f64_i64, asm,
4542 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
4543 fixedpoint_f64_i64:$scale)))]> {
4544 let Inst{31} = 1; // 64-bit GPR flag
4549 // Integer to floating point conversion
4552 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
4553 class BaseIntegerToFP<bit isUnsigned,
4554 RegisterClass srcType, RegisterClass dstType,
4555 Operand immType, string asm, list<dag> pattern>
4556 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4557 asm, "\t$Rd, $Rn, $scale", "", pattern>,
4558 Sched<[WriteFCvt]> {
4562 let Inst{30-24} = 0b0011110;
4563 let Inst{21-17} = 0b00001;
4564 let Inst{16} = isUnsigned;
4565 let Inst{15-10} = scale;
4570 class BaseIntegerToFPUnscaled<bit isUnsigned,
4571 RegisterClass srcType, RegisterClass dstType,
4572 ValueType dvt, string asm, SDNode node>
4573 : I<(outs dstType:$Rd), (ins srcType:$Rn),
4574 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
4575 Sched<[WriteFCvt]> {
4579 let Inst{30-24} = 0b0011110;
4580 let Inst{21-17} = 0b10001;
4581 let Inst{16} = isUnsigned;
4582 let Inst{15-10} = 0b000000;
4587 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
4589 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
4590 let Inst{31} = 0; // 32-bit GPR flag
4591 let Inst{23-22} = 0b11; // 16-bit FPR flag
4592 let Predicates = [HasFullFP16];
4595 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
4596 let Inst{31} = 0; // 32-bit GPR flag
4597 let Inst{23-22} = 0b00; // 32-bit FPR flag
4600 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
4601 let Inst{31} = 0; // 32-bit GPR flag
4602 let Inst{23-22} = 0b01; // 64-bit FPR flag
4605 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
4606 let Inst{31} = 1; // 64-bit GPR flag
4607 let Inst{23-22} = 0b11; // 16-bit FPR flag
4608 let Predicates = [HasFullFP16];
4611 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
4612 let Inst{31} = 1; // 64-bit GPR flag
4613 let Inst{23-22} = 0b00; // 32-bit FPR flag
4616 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
4617 let Inst{31} = 1; // 64-bit GPR flag
4618 let Inst{23-22} = 0b01; // 64-bit FPR flag
4622 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
4623 [(set (f16 FPR16:$Rd),
4624 (fdiv (node GPR32:$Rn),
4625 fixedpoint_f16_i32:$scale))]> {
4626 let Inst{31} = 0; // 32-bit GPR flag
4627 let Inst{23-22} = 0b11; // 16-bit FPR flag
4629 let Predicates = [HasFullFP16];
4632 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
4634 (fdiv (node GPR32:$Rn),
4635 fixedpoint_f32_i32:$scale))]> {
4636 let Inst{31} = 0; // 32-bit GPR flag
4637 let Inst{23-22} = 0b00; // 32-bit FPR flag
4641 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
4643 (fdiv (node GPR32:$Rn),
4644 fixedpoint_f64_i32:$scale))]> {
4645 let Inst{31} = 0; // 32-bit GPR flag
4646 let Inst{23-22} = 0b01; // 64-bit FPR flag
4650 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
4651 [(set (f16 FPR16:$Rd),
4652 (fdiv (node GPR64:$Rn),
4653 fixedpoint_f16_i64:$scale))]> {
4654 let Inst{31} = 1; // 64-bit GPR flag
4655 let Inst{23-22} = 0b11; // 16-bit FPR flag
4656 let Predicates = [HasFullFP16];
4659 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
4661 (fdiv (node GPR64:$Rn),
4662 fixedpoint_f32_i64:$scale))]> {
4663 let Inst{31} = 1; // 64-bit GPR flag
4664 let Inst{23-22} = 0b00; // 32-bit FPR flag
4667 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
4669 (fdiv (node GPR64:$Rn),
4670 fixedpoint_f64_i64:$scale))]> {
4671 let Inst{31} = 1; // 64-bit GPR flag
4672 let Inst{23-22} = 0b01; // 64-bit FPR flag
4677 // Unscaled integer <-> floating point conversion (i.e. FMOV)
4680 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4681 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
4682 RegisterClass srcType, RegisterClass dstType,
4684 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
4685 // We use COPY_TO_REGCLASS for these bitconvert operations.
4686 // copyPhysReg() expands the resultant COPY instructions after
4687 // regalloc is done. This gives greater freedom for the allocator
4688 // and related passes (coalescing, copy propagation, et. al.) to
4689 // be more effective.
4690 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
4691 Sched<[WriteFCopy]> {
4694 let Inst{30-24} = 0b0011110;
4696 let Inst{20-19} = rmode;
4697 let Inst{18-16} = opcode;
4698 let Inst{15-10} = 0b000000;
4703 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4704 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
4705 RegisterClass srcType, RegisterOperand dstType, string asm,
4707 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4708 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
4709 Sched<[WriteFCopy]> {
4712 let Inst{30-23} = 0b00111101;
4714 let Inst{20-19} = rmode;
4715 let Inst{18-16} = opcode;
4716 let Inst{15-10} = 0b000000;
4720 let DecoderMethod = "DecodeFMOVLaneInstruction";
4723 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4724 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
4725 RegisterOperand srcType, RegisterClass dstType, string asm,
4727 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4728 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
4729 Sched<[WriteFCopy]> {
4732 let Inst{30-23} = 0b00111101;
4734 let Inst{20-19} = rmode;
4735 let Inst{18-16} = opcode;
4736 let Inst{15-10} = 0b000000;
4740 let DecoderMethod = "DecodeFMOVLaneInstruction";
4744 multiclass UnscaledConversion<string asm> {
4745 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
4746 let Inst{31} = 0; // 32-bit GPR flag
4747 let Inst{23-22} = 0b11; // 16-bit FPR flag
4748 let Predicates = [HasFullFP16];
4751 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
4752 let Inst{31} = 1; // 64-bit GPR flag
4753 let Inst{23-22} = 0b11; // 16-bit FPR flag
4754 let Predicates = [HasFullFP16];
4757 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
4758 let Inst{31} = 0; // 32-bit GPR flag
4759 let Inst{23-22} = 0b00; // 32-bit FPR flag
4762 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
4763 let Inst{31} = 1; // 64-bit GPR flag
4764 let Inst{23-22} = 0b01; // 64-bit FPR flag
4767 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
4768 let Inst{31} = 0; // 32-bit GPR flag
4769 let Inst{23-22} = 0b11; // 16-bit FPR flag
4770 let Predicates = [HasFullFP16];
4773 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
4774 let Inst{31} = 1; // 64-bit GPR flag
4775 let Inst{23-22} = 0b11; // 16-bit FPR flag
4776 let Predicates = [HasFullFP16];
4779 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
4780 let Inst{31} = 0; // 32-bit GPR flag
4781 let Inst{23-22} = 0b00; // 32-bit FPR flag
4784 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
4785 let Inst{31} = 1; // 64-bit GPR flag
4786 let Inst{23-22} = 0b01; // 64-bit FPR flag
4789 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
4795 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
4803 // Floating point conversion
4806 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
4807 RegisterClass srcType, string asm, list<dag> pattern>
4808 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
4809 Sched<[WriteFCvt]> {
4812 let Inst{31-24} = 0b00011110;
4813 let Inst{23-22} = type;
4814 let Inst{21-17} = 0b10001;
4815 let Inst{16-15} = opcode;
4816 let Inst{14-10} = 0b10000;
4821 multiclass FPConversion<string asm> {
4822 // Double-precision to Half-precision
4823 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4824 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>;
4826 // Double-precision to Single-precision
4827 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4828 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;
4830 // Half-precision to Double-precision
4831 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
4832 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
4834 // Half-precision to Single-precision
4835 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
4836 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
4838 // Single-precision to Double-precision
4839 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
4840 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
4842 // Single-precision to Half-precision
4843 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4844 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>;
4848 // Single operand floating point data processing
4851 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4852 class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype,
4853 ValueType vt, string asm, SDPatternOperator node>
4854 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
4855 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
4859 let Inst{31-24} = 0b00011110;
4861 let Inst{20-15} = opcode;
4862 let Inst{14-10} = 0b10000;
4867 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4868 SDPatternOperator node = null_frag> {
4870 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> {
4871 let Inst{23-22} = 0b11; // 16-bit size flag
4872 let Predicates = [HasFullFP16];
4875 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {
4876 let Inst{23-22} = 0b00; // 32-bit size flag
4879 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {
4880 let Inst{23-22} = 0b01; // 64-bit size flag
4884 multiclass SingleOperandFPNo16<bits<6> opcode, string asm,
4885 SDPatternOperator node = null_frag>{
4887 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4888 let Inst{23-22} = 0b00; // 32-bit registers
4891 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4892 let Inst{23-22} = 0b01; // 64-bit registers
4896 // FRInt[32|64][Z|N] instructions
4897 multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> :
4898 SingleOperandFPNo16<{0b0100,opcode}, asm, node>;
4901 // Two operand floating point data processing
4904 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4905 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4906 string asm, list<dag> pat>
4907 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4908 asm, "\t$Rd, $Rn, $Rm", "", pat>,
4913 let Inst{31-24} = 0b00011110;
4915 let Inst{20-16} = Rm;
4916 let Inst{15-12} = opcode;
4917 let Inst{11-10} = 0b10;
4922 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4923 SDPatternOperator node = null_frag> {
4924 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4925 [(set (f16 FPR16:$Rd),
4926 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4927 let Inst{23-22} = 0b11; // 16-bit size flag
4928 let Predicates = [HasFullFP16];
4931 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4932 [(set (f32 FPR32:$Rd),
4933 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4934 let Inst{23-22} = 0b00; // 32-bit size flag
4937 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4938 [(set (f64 FPR64:$Rd),
4939 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4940 let Inst{23-22} = 0b01; // 64-bit size flag
4944 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4945 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4946 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> {
4947 let Inst{23-22} = 0b11; // 16-bit size flag
4948 let Predicates = [HasFullFP16];
4951 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4952 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4953 let Inst{23-22} = 0b00; // 32-bit size flag
4956 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4957 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4958 let Inst{23-22} = 0b01; // 64-bit size flag
4964 // Three operand floating point data processing
4967 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4968 RegisterClass regtype, string asm, list<dag> pat>
4969 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4970 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4971 Sched<[WriteFMul]> {
4976 let Inst{31-24} = 0b00011111;
4977 let Inst{21} = isNegated;
4978 let Inst{20-16} = Rm;
4979 let Inst{15} = isSub;
4980 let Inst{14-10} = Ra;
4985 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4986 SDPatternOperator node> {
4987 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4988 [(set (f16 FPR16:$Rd),
4989 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4990 let Inst{23-22} = 0b11; // 16-bit size flag
4991 let Predicates = [HasFullFP16];
4994 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4996 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4997 let Inst{23-22} = 0b00; // 32-bit size flag
5000 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
5002 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
5003 let Inst{23-22} = 0b01; // 64-bit size flag
5008 // Floating point data comparisons
5011 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5012 class BaseOneOperandFPComparison<bit signalAllNans,
5013 RegisterClass regtype, string asm,
5015 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
5016 Sched<[WriteFCmp]> {
5018 let Inst{31-24} = 0b00011110;
5021 let Inst{15-10} = 0b001000;
5023 let Inst{4} = signalAllNans;
5024 let Inst{3-0} = 0b1000;
5026 // Rm should be 0b00000 canonically, but we need to accept any value.
5027 let PostEncoderMethod = "fixOneOperandFPComparison";
5030 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5031 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
5032 string asm, list<dag> pat>
5033 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
5034 Sched<[WriteFCmp]> {
5037 let Inst{31-24} = 0b00011110;
5039 let Inst{20-16} = Rm;
5040 let Inst{15-10} = 0b001000;
5042 let Inst{4} = signalAllNans;
5043 let Inst{3-0} = 0b0000;
5046 multiclass FPComparison<bit signalAllNans, string asm,
5047 SDPatternOperator OpNode = null_frag> {
5048 let Defs = [NZCV] in {
5049 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
5050 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> {
5051 let Inst{23-22} = 0b11;
5052 let Predicates = [HasFullFP16];
5055 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
5056 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
5057 let Inst{23-22} = 0b11;
5058 let Predicates = [HasFullFP16];
5061 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
5062 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
5063 let Inst{23-22} = 0b00;
5066 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
5067 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
5068 let Inst{23-22} = 0b00;
5071 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
5072 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
5073 let Inst{23-22} = 0b01;
5076 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
5077 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
5078 let Inst{23-22} = 0b01;
5084 // Floating point conditional comparisons
5087 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5088 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
5089 string mnemonic, list<dag> pat>
5090 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
5091 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
5092 Sched<[WriteFCmp]> {
5101 let Inst{31-24} = 0b00011110;
5103 let Inst{20-16} = Rm;
5104 let Inst{15-12} = cond;
5105 let Inst{11-10} = 0b01;
5107 let Inst{4} = signalAllNans;
5108 let Inst{3-0} = nzcv;
5111 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
5112 SDPatternOperator OpNode = null_frag> {
5113 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,
5114 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),
5115 (i32 imm:$cond), NZCV))]> {
5116 let Inst{23-22} = 0b11;
5117 let Predicates = [HasFullFP16];
5120 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
5121 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
5122 (i32 imm:$cond), NZCV))]> {
5123 let Inst{23-22} = 0b00;
5126 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
5127 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
5128 (i32 imm:$cond), NZCV))]> {
5129 let Inst{23-22} = 0b01;
5134 // Floating point conditional select
5137 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
5138 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
5139 asm, "\t$Rd, $Rn, $Rm, $cond", "",
5141 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
5142 (i32 imm:$cond), NZCV))]>,
5149 let Inst{31-24} = 0b00011110;
5151 let Inst{20-16} = Rm;
5152 let Inst{15-12} = cond;
5153 let Inst{11-10} = 0b11;
5158 multiclass FPCondSelect<string asm> {
5159 let Uses = [NZCV] in {
5160 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
5161 let Inst{23-22} = 0b11;
5162 let Predicates = [HasFullFP16];
5165 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
5166 let Inst{23-22} = 0b00;
5169 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
5170 let Inst{23-22} = 0b01;
5176 // Floating move immediate
5179 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
5180 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
5181 [(set regtype:$Rd, fpimmtype:$imm)]>,
5182 Sched<[WriteFImm]> {
5185 let Inst{31-24} = 0b00011110;
5187 let Inst{20-13} = imm;
5188 let Inst{12-5} = 0b10000000;
5192 multiclass FPMoveImmediate<string asm> {
5193 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
5194 let Inst{23-22} = 0b11;
5195 let Predicates = [HasFullFP16];
5198 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
5199 let Inst{23-22} = 0b00;
5202 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
5203 let Inst{23-22} = 0b01;
5206 } // end of 'let Predicates = [HasFPARMv8]'
5208 //----------------------------------------------------------------------------
5210 //----------------------------------------------------------------------------
5212 let Predicates = [HasNEON] in {
5214 //----------------------------------------------------------------------------
5215 // AdvSIMD three register vector instructions
5216 //----------------------------------------------------------------------------
5218 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5219 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
5220 RegisterOperand regtype, string asm, string kind,
5222 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5223 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5224 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
5232 let Inst{28-24} = 0b01110;
5233 let Inst{23-21} = size;
5234 let Inst{20-16} = Rm;
5235 let Inst{15-11} = opcode;
5241 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5242 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
5243 RegisterOperand regtype, string asm, string kind,
5245 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
5246 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5247 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5255 let Inst{28-24} = 0b01110;
5256 let Inst{23-21} = size;
5257 let Inst{20-16} = Rm;
5258 let Inst{15-11} = opcode;
5264 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5265 class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern>
5266 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>,
5269 multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> {
5270 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64,
5271 [(set (v8i8 V64:$dst),
5272 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5273 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128,
5274 [(set (v16i8 V128:$dst),
5275 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5276 (v16i8 V128:$Rm)))]>;
5278 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5280 (!cast<Instruction>(NAME#"v8i8")
5281 V64:$LHS, V64:$MHS, V64:$RHS)>;
5282 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5284 (!cast<Instruction>(NAME#"v8i8")
5285 V64:$LHS, V64:$MHS, V64:$RHS)>;
5286 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5288 (!cast<Instruction>(NAME#"v8i8")
5289 V64:$LHS, V64:$MHS, V64:$RHS)>;
5291 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5292 (v8i16 V128:$RHS))),
5293 (!cast<Instruction>(NAME#"v16i8")
5294 V128:$LHS, V128:$MHS, V128:$RHS)>;
5295 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5296 (v4i32 V128:$RHS))),
5297 (!cast<Instruction>(NAME#"v16i8")
5298 V128:$LHS, V128:$MHS, V128:$RHS)>;
5299 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5300 (v2i64 V128:$RHS))),
5301 (!cast<Instruction>(NAME#"v16i8")
5302 V128:$LHS, V128:$MHS, V128:$RHS)>;
5305 // All operand sizes distinguished in the encoding.
5306 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
5307 SDPatternOperator OpNode> {
5308 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5310 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5311 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5313 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5314 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5316 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5317 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5319 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5320 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5322 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5323 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5325 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5326 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
5328 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5331 multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> {
5332 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)),
5333 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>;
5334 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5335 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>;
5336 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5337 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>;
5339 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)),
5340 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>;
5341 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5342 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>;
5343 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5344 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>;
5345 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5346 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>;
5349 // As above, but D sized elements unsupported.
5350 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
5351 SDPatternOperator OpNode> {
5352 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5354 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
5355 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5357 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
5358 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5360 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
5361 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5363 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
5364 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5366 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
5367 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5369 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
5372 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
5373 SDPatternOperator OpNode> {
5374 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
5376 [(set (v8i8 V64:$dst),
5377 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5378 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
5380 [(set (v16i8 V128:$dst),
5381 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5382 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
5384 [(set (v4i16 V64:$dst),
5385 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5386 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
5388 [(set (v8i16 V128:$dst),
5389 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5390 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
5392 [(set (v2i32 V64:$dst),
5393 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5394 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
5396 [(set (v4i32 V128:$dst),
5397 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5400 // As above, but only B sized elements supported.
5401 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
5402 SDPatternOperator OpNode> {
5403 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5405 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5406 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5408 [(set (v16i8 V128:$Rd),
5409 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5412 // As above, but only floating point elements supported.
5413 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
5414 string asm, SDPatternOperator OpNode> {
5415 let Predicates = [HasNEON, HasFullFP16] in {
5416 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5418 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5419 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5421 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5422 } // Predicates = [HasNEON, HasFullFP16]
5423 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5425 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5426 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5428 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5429 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5431 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5434 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
5436 SDPatternOperator OpNode> {
5437 let Predicates = [HasNEON, HasFullFP16] in {
5438 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5440 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5441 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5443 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5444 } // Predicates = [HasNEON, HasFullFP16]
5445 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5447 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5448 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5450 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5451 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5453 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5456 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
5457 string asm, SDPatternOperator OpNode> {
5458 let Predicates = [HasNEON, HasFullFP16] in {
5459 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
5461 [(set (v4f16 V64:$dst),
5462 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5463 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
5465 [(set (v8f16 V128:$dst),
5466 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5467 } // Predicates = [HasNEON, HasFullFP16]
5468 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
5470 [(set (v2f32 V64:$dst),
5471 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5472 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
5474 [(set (v4f32 V128:$dst),
5475 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5476 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
5478 [(set (v2f64 V128:$dst),
5479 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5482 // As above, but D and B sized elements unsupported.
5483 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
5484 SDPatternOperator OpNode> {
5485 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5487 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5488 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5490 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5491 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5493 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5494 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5496 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5499 // Logical three vector ops share opcode bits, and only use B sized elements.
5500 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
5501 SDPatternOperator OpNode = null_frag> {
5502 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
5504 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
5505 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
5507 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
5509 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5510 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5511 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5512 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5513 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
5514 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5516 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5517 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5518 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5519 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5520 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5521 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5524 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
5525 string asm, SDPatternOperator OpNode = null_frag> {
5526 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
5528 [(set (v8i8 V64:$dst),
5529 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5530 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
5532 [(set (v16i8 V128:$dst),
5533 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5534 (v16i8 V128:$Rm)))]>;
5536 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5538 (!cast<Instruction>(NAME#"v8i8")
5539 V64:$LHS, V64:$MHS, V64:$RHS)>;
5540 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5542 (!cast<Instruction>(NAME#"v8i8")
5543 V64:$LHS, V64:$MHS, V64:$RHS)>;
5544 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5546 (!cast<Instruction>(NAME#"v8i8")
5547 V64:$LHS, V64:$MHS, V64:$RHS)>;
5549 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5550 (v8i16 V128:$RHS))),
5551 (!cast<Instruction>(NAME#"v16i8")
5552 V128:$LHS, V128:$MHS, V128:$RHS)>;
5553 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5554 (v4i32 V128:$RHS))),
5555 (!cast<Instruction>(NAME#"v16i8")
5556 V128:$LHS, V128:$MHS, V128:$RHS)>;
5557 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5558 (v2i64 V128:$RHS))),
5559 (!cast<Instruction>(NAME#"v16i8")
5560 V128:$LHS, V128:$MHS, V128:$RHS)>;
5563 // ARMv8.2-A Dot Product Instructions (Vector): These instructions extract
5564 // bytes from S-sized elements.
5565 class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1,
5566 string kind2, RegisterOperand RegType,
5567 ValueType AccumType, ValueType InputType,
5568 SDPatternOperator OpNode> :
5569 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1,
5570 [(set (AccumType RegType:$dst),
5571 (OpNode (AccumType RegType:$Rd),
5572 (InputType RegType:$Rn),
5573 (InputType RegType:$Rm)))]> {
5574 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5577 multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> {
5578 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64,
5579 v2i32, v8i8, OpNode>;
5580 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128,
5581 v4i32, v16i8, OpNode>;
5584 // ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions
5585 // select inputs from 4H vectors and accumulate outputs to a 2S vector (or from
5586 // 8H to 4S, when Q=1).
5587 class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1,
5588 string kind2, RegisterOperand RegType,
5589 ValueType AccumType, ValueType InputType,
5590 SDPatternOperator OpNode> :
5591 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1,
5592 [(set (AccumType RegType:$dst),
5593 (OpNode (AccumType RegType:$Rd),
5594 (InputType RegType:$Rn),
5595 (InputType RegType:$Rm)))]> {
5596 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5600 multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,
5601 SDPatternOperator OpNode> {
5602 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64,
5603 v2f32, v4f16, OpNode>;
5604 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128,
5605 v4f32, v8f16, OpNode>;
5609 //----------------------------------------------------------------------------
5610 // AdvSIMD two register vector instructions.
5611 //----------------------------------------------------------------------------
5613 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5614 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5615 bits<2> size2, RegisterOperand regtype, string asm,
5616 string dstkind, string srckind, list<dag> pattern>
5617 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5618 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5619 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
5626 let Inst{28-24} = 0b01110;
5627 let Inst{23-22} = size;
5629 let Inst{20-19} = size2;
5630 let Inst{18-17} = 0b00;
5631 let Inst{16-12} = opcode;
5632 let Inst{11-10} = 0b10;
5637 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5638 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5639 bits<2> size2, RegisterOperand regtype,
5640 string asm, string dstkind, string srckind,
5642 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
5643 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5644 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5651 let Inst{28-24} = 0b01110;
5652 let Inst{23-22} = size;
5654 let Inst{20-19} = size2;
5655 let Inst{18-17} = 0b00;
5656 let Inst{16-12} = opcode;
5657 let Inst{11-10} = 0b10;
5662 // Supports B, H, and S element sizes.
5663 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
5664 SDPatternOperator OpNode> {
5665 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5667 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5668 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5669 asm, ".16b", ".16b",
5670 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5671 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5673 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5674 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5676 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5677 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5679 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5680 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5682 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5685 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
5686 RegisterOperand regtype, string asm, string dstkind,
5687 string srckind, string amount>
5688 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
5689 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
5690 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
5696 let Inst{29-24} = 0b101110;
5697 let Inst{23-22} = size;
5698 let Inst{21-10} = 0b100001001110;
5703 multiclass SIMDVectorLShiftLongBySizeBHS {
5704 let hasSideEffects = 0 in {
5705 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
5706 "shll", ".8h", ".8b", "8">;
5707 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
5708 "shll2", ".8h", ".16b", "8">;
5709 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
5710 "shll", ".4s", ".4h", "16">;
5711 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
5712 "shll2", ".4s", ".8h", "16">;
5713 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
5714 "shll", ".2d", ".2s", "32">;
5715 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
5716 "shll2", ".2d", ".4s", "32">;
5720 // Supports all element sizes.
5721 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
5722 SDPatternOperator OpNode> {
5723 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5725 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5726 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5728 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5729 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5731 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5732 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5734 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5735 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5737 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5738 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5740 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5743 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
5744 SDPatternOperator OpNode> {
5745 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5747 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
5749 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5751 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
5752 (v16i8 V128:$Rn)))]>;
5753 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5755 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
5756 (v4i16 V64:$Rn)))]>;
5757 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5759 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
5760 (v8i16 V128:$Rn)))]>;
5761 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5763 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
5764 (v2i32 V64:$Rn)))]>;
5765 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5767 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
5768 (v4i32 V128:$Rn)))]>;
5771 // Supports all element sizes, except 1xD.
5772 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
5773 SDPatternOperator OpNode> {
5774 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5776 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
5777 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5778 asm, ".16b", ".16b",
5779 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
5780 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5782 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
5783 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5785 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
5786 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5788 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
5789 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5791 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
5792 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
5794 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
5797 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
5798 SDPatternOperator OpNode = null_frag> {
5799 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5801 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5802 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5803 asm, ".16b", ".16b",
5804 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5805 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5807 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5808 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5810 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5811 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5813 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5814 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5816 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5817 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5819 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5823 // Supports only B element sizes.
5824 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5825 SDPatternOperator OpNode> {
5826 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5828 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5829 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5830 asm, ".16b", ".16b",
5831 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5835 // Supports only B and H element sizes.
5836 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5837 SDPatternOperator OpNode> {
5838 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5840 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5841 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5842 asm, ".16b", ".16b",
5843 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5844 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5846 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5847 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5849 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5852 // Supports H, S and D element sizes, uses high bit of the size field
5853 // as an extra opcode bit.
5854 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5855 SDPatternOperator OpNode> {
5856 let Predicates = [HasNEON, HasFullFP16] in {
5857 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5859 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5860 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5862 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5863 } // Predicates = [HasNEON, HasFullFP16]
5864 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5866 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5867 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5869 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5870 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5872 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5875 // Supports only S and D element sizes
5876 multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm,
5877 SDPatternOperator OpNode = null_frag> {
5879 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64,
5881 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5882 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,
5884 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5885 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,
5887 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5890 multiclass FRIntNNTVector<bit U, bit op, string asm,
5891 SDPatternOperator OpNode = null_frag> :
5892 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>;
5894 // Supports only S element size.
5895 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5896 SDPatternOperator OpNode> {
5897 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5899 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5900 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5902 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5906 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5907 SDPatternOperator OpNode> {
5908 let Predicates = [HasNEON, HasFullFP16] in {
5909 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5911 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5912 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5914 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5915 } // Predicates = [HasNEON, HasFullFP16]
5916 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5918 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5919 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5921 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5922 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5924 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5927 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
5928 SDPatternOperator OpNode> {
5929 let Predicates = [HasNEON, HasFullFP16] in {
5930 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5932 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5933 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5935 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5936 } // Predicates = [HasNEON, HasFullFP16]
5937 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5939 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5940 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5942 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5943 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5945 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5949 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5950 RegisterOperand inreg, RegisterOperand outreg,
5951 string asm, string outkind, string inkind,
5953 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
5954 "{\t$Rd" # outkind # ", $Rn" # inkind #
5955 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
5962 let Inst{28-24} = 0b01110;
5963 let Inst{23-22} = size;
5964 let Inst{21-17} = 0b10000;
5965 let Inst{16-12} = opcode;
5966 let Inst{11-10} = 0b10;
5971 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5972 RegisterOperand inreg, RegisterOperand outreg,
5973 string asm, string outkind, string inkind,
5975 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
5976 "{\t$Rd" # outkind # ", $Rn" # inkind #
5977 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5984 let Inst{28-24} = 0b01110;
5985 let Inst{23-22} = size;
5986 let Inst{21-17} = 0b10000;
5987 let Inst{16-12} = opcode;
5988 let Inst{11-10} = 0b10;
5993 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
5994 SDPatternOperator OpNode> {
5995 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
5997 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5998 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
5999 asm#"2", ".16b", ".8h", []>;
6000 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
6002 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6003 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
6004 asm#"2", ".8h", ".4s", []>;
6005 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
6007 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
6008 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
6009 asm#"2", ".4s", ".2d", []>;
6011 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
6012 (!cast<Instruction>(NAME # "v16i8")
6013 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6014 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
6015 (!cast<Instruction>(NAME # "v8i16")
6016 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6017 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
6018 (!cast<Instruction>(NAME # "v4i32")
6019 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6022 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
6023 bits<5> opcode, RegisterOperand regtype, string asm,
6024 string kind, string zero, ValueType dty,
6025 ValueType sty, SDNode OpNode>
6026 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6027 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
6028 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
6029 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
6036 let Inst{28-24} = 0b01110;
6037 let Inst{23-22} = size;
6039 let Inst{20-19} = size2;
6040 let Inst{18-17} = 0b00;
6041 let Inst{16-12} = opcode;
6042 let Inst{11-10} = 0b10;
6047 // Comparisons support all element sizes, except 1xD.
6048 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
6050 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
6052 v8i8, v8i8, OpNode>;
6053 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
6055 v16i8, v16i8, OpNode>;
6056 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
6058 v4i16, v4i16, OpNode>;
6059 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
6061 v8i16, v8i16, OpNode>;
6062 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
6064 v2i32, v2i32, OpNode>;
6065 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
6067 v4i32, v4i32, OpNode>;
6068 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
6070 v2i64, v2i64, OpNode>;
6073 // FP Comparisons support only S and D element sizes (and H for v8.2a).
6074 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
6075 string asm, SDNode OpNode> {
6077 let Predicates = [HasNEON, HasFullFP16] in {
6078 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
6080 v4i16, v4f16, OpNode>;
6081 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
6083 v8i16, v8f16, OpNode>;
6084 } // Predicates = [HasNEON, HasFullFP16]
6085 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
6087 v2i32, v2f32, OpNode>;
6088 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
6090 v4i32, v4f32, OpNode>;
6091 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
6093 v2i64, v2f64, OpNode>;
6095 let Predicates = [HasNEON, HasFullFP16] in {
6096 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
6097 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6098 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
6099 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6101 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
6102 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6103 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
6104 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6105 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
6106 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6107 let Predicates = [HasNEON, HasFullFP16] in {
6108 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
6109 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6110 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
6111 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6113 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
6114 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6115 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
6116 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6117 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
6118 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6121 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6122 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
6123 RegisterOperand outtype, RegisterOperand intype,
6124 string asm, string VdTy, string VnTy,
6126 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
6127 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
6134 let Inst{28-24} = 0b01110;
6135 let Inst{23-22} = size;
6136 let Inst{21-17} = 0b10000;
6137 let Inst{16-12} = opcode;
6138 let Inst{11-10} = 0b10;
6143 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
6144 RegisterOperand outtype, RegisterOperand intype,
6145 string asm, string VdTy, string VnTy,
6147 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
6148 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
6155 let Inst{28-24} = 0b01110;
6156 let Inst{23-22} = size;
6157 let Inst{21-17} = 0b10000;
6158 let Inst{16-12} = opcode;
6159 let Inst{11-10} = 0b10;
6164 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
6165 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
6166 asm, ".4s", ".4h", []>;
6167 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
6168 asm#"2", ".4s", ".8h", []>;
6169 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
6170 asm, ".2d", ".2s", []>;
6171 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
6172 asm#"2", ".2d", ".4s", []>;
6175 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
6176 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
6177 asm, ".4h", ".4s", []>;
6178 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
6179 asm#"2", ".8h", ".4s", []>;
6180 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6181 asm, ".2s", ".2d", []>;
6182 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6183 asm#"2", ".4s", ".2d", []>;
6186 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
6188 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6190 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6191 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6192 asm#"2", ".4s", ".2d", []>;
6194 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
6195 (!cast<Instruction>(NAME # "v4f32")
6196 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6199 //----------------------------------------------------------------------------
6200 // AdvSIMD three register different-size vector instructions.
6201 //----------------------------------------------------------------------------
6203 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6204 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
6205 RegisterOperand outtype, RegisterOperand intype1,
6206 RegisterOperand intype2, string asm,
6207 string outkind, string inkind1, string inkind2,
6209 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
6210 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6211 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
6217 let Inst{30} = size{0};
6219 let Inst{28-24} = 0b01110;
6220 let Inst{23-22} = size{2-1};
6222 let Inst{20-16} = Rm;
6223 let Inst{15-12} = opcode;
6224 let Inst{11-10} = 0b00;
6229 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6230 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
6231 RegisterOperand outtype, RegisterOperand intype1,
6232 RegisterOperand intype2, string asm,
6233 string outkind, string inkind1, string inkind2,
6235 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
6236 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6237 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
6243 let Inst{30} = size{0};
6245 let Inst{28-24} = 0b01110;
6246 let Inst{23-22} = size{2-1};
6248 let Inst{20-16} = Rm;
6249 let Inst{15-12} = opcode;
6250 let Inst{11-10} = 0b00;
6255 // FIXME: TableGen doesn't know how to deal with expanded types that also
6256 // change the element count (in this case, placing the results in
6257 // the high elements of the result register rather than the low
6258 // elements). Until that's fixed, we can't code-gen those.
6259 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
6261 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6263 asm, ".8b", ".8h", ".8h",
6264 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
6265 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6267 asm#"2", ".16b", ".8h", ".8h",
6269 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6271 asm, ".4h", ".4s", ".4s",
6272 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
6273 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6275 asm#"2", ".8h", ".4s", ".4s",
6277 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6279 asm, ".2s", ".2d", ".2d",
6280 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
6281 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6283 asm#"2", ".4s", ".2d", ".2d",
6287 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
6288 // a version attached to an instruction.
6289 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
6291 (!cast<Instruction>(NAME # "v8i16_v16i8")
6292 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6293 V128:$Rn, V128:$Rm)>;
6294 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
6296 (!cast<Instruction>(NAME # "v4i32_v8i16")
6297 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6298 V128:$Rn, V128:$Rm)>;
6299 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
6301 (!cast<Instruction>(NAME # "v2i64_v4i32")
6302 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6303 V128:$Rn, V128:$Rm)>;
6306 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
6308 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6310 asm, ".8h", ".8b", ".8b",
6311 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6312 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6314 asm#"2", ".8h", ".16b", ".16b", []>;
6315 let Predicates = [HasAES] in {
6316 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
6318 asm, ".1q", ".1d", ".1d", []>;
6319 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
6321 asm#"2", ".1q", ".2d", ".2d", []>;
6324 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
6325 (v8i8 (extract_high_v16i8 V128:$Rm)))),
6326 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
6329 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
6330 SDPatternOperator OpNode> {
6331 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6333 asm, ".4s", ".4h", ".4h",
6334 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6335 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6337 asm#"2", ".4s", ".8h", ".8h",
6338 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6339 (extract_high_v8i16 V128:$Rm)))]>;
6340 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6342 asm, ".2d", ".2s", ".2s",
6343 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6344 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6346 asm#"2", ".2d", ".4s", ".4s",
6347 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6348 (extract_high_v4i32 V128:$Rm)))]>;
6351 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
6352 SDPatternOperator OpNode = null_frag> {
6353 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6355 asm, ".8h", ".8b", ".8b",
6356 [(set (v8i16 V128:$Rd),
6357 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
6358 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6360 asm#"2", ".8h", ".16b", ".16b",
6361 [(set (v8i16 V128:$Rd),
6362 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6363 (extract_high_v16i8 V128:$Rm)))))]>;
6364 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6366 asm, ".4s", ".4h", ".4h",
6367 [(set (v4i32 V128:$Rd),
6368 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
6369 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6371 asm#"2", ".4s", ".8h", ".8h",
6372 [(set (v4i32 V128:$Rd),
6373 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6374 (extract_high_v8i16 V128:$Rm)))))]>;
6375 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6377 asm, ".2d", ".2s", ".2s",
6378 [(set (v2i64 V128:$Rd),
6379 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
6380 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6382 asm#"2", ".2d", ".4s", ".4s",
6383 [(set (v2i64 V128:$Rd),
6384 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6385 (extract_high_v4i32 V128:$Rm)))))]>;
6388 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
6390 SDPatternOperator OpNode> {
6391 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6393 asm, ".8h", ".8b", ".8b",
6394 [(set (v8i16 V128:$dst),
6395 (add (v8i16 V128:$Rd),
6396 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
6397 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6399 asm#"2", ".8h", ".16b", ".16b",
6400 [(set (v8i16 V128:$dst),
6401 (add (v8i16 V128:$Rd),
6402 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6403 (extract_high_v16i8 V128:$Rm))))))]>;
6404 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6406 asm, ".4s", ".4h", ".4h",
6407 [(set (v4i32 V128:$dst),
6408 (add (v4i32 V128:$Rd),
6409 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
6410 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6412 asm#"2", ".4s", ".8h", ".8h",
6413 [(set (v4i32 V128:$dst),
6414 (add (v4i32 V128:$Rd),
6415 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6416 (extract_high_v8i16 V128:$Rm))))))]>;
6417 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6419 asm, ".2d", ".2s", ".2s",
6420 [(set (v2i64 V128:$dst),
6421 (add (v2i64 V128:$Rd),
6422 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
6423 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6425 asm#"2", ".2d", ".4s", ".4s",
6426 [(set (v2i64 V128:$dst),
6427 (add (v2i64 V128:$Rd),
6428 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6429 (extract_high_v4i32 V128:$Rm))))))]>;
6432 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
6433 SDPatternOperator OpNode = null_frag> {
6434 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6436 asm, ".8h", ".8b", ".8b",
6437 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6438 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6440 asm#"2", ".8h", ".16b", ".16b",
6441 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
6442 (extract_high_v16i8 V128:$Rm)))]>;
6443 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6445 asm, ".4s", ".4h", ".4h",
6446 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6447 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6449 asm#"2", ".4s", ".8h", ".8h",
6450 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6451 (extract_high_v8i16 V128:$Rm)))]>;
6452 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6454 asm, ".2d", ".2s", ".2s",
6455 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6456 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6458 asm#"2", ".2d", ".4s", ".4s",
6459 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6460 (extract_high_v4i32 V128:$Rm)))]>;
6463 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
6465 SDPatternOperator OpNode> {
6466 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6468 asm, ".8h", ".8b", ".8b",
6469 [(set (v8i16 V128:$dst),
6470 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6471 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6473 asm#"2", ".8h", ".16b", ".16b",
6474 [(set (v8i16 V128:$dst),
6475 (OpNode (v8i16 V128:$Rd),
6476 (extract_high_v16i8 V128:$Rn),
6477 (extract_high_v16i8 V128:$Rm)))]>;
6478 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6480 asm, ".4s", ".4h", ".4h",
6481 [(set (v4i32 V128:$dst),
6482 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6483 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6485 asm#"2", ".4s", ".8h", ".8h",
6486 [(set (v4i32 V128:$dst),
6487 (OpNode (v4i32 V128:$Rd),
6488 (extract_high_v8i16 V128:$Rn),
6489 (extract_high_v8i16 V128:$Rm)))]>;
6490 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6492 asm, ".2d", ".2s", ".2s",
6493 [(set (v2i64 V128:$dst),
6494 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6495 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6497 asm#"2", ".2d", ".4s", ".4s",
6498 [(set (v2i64 V128:$dst),
6499 (OpNode (v2i64 V128:$Rd),
6500 (extract_high_v4i32 V128:$Rn),
6501 (extract_high_v4i32 V128:$Rm)))]>;
6504 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
6505 SDPatternOperator Accum> {
6506 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6508 asm, ".4s", ".4h", ".4h",
6509 [(set (v4i32 V128:$dst),
6510 (Accum (v4i32 V128:$Rd),
6511 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6512 (v4i16 V64:$Rm)))))]>;
6513 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6515 asm#"2", ".4s", ".8h", ".8h",
6516 [(set (v4i32 V128:$dst),
6517 (Accum (v4i32 V128:$Rd),
6518 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
6519 (extract_high_v8i16 V128:$Rm)))))]>;
6520 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6522 asm, ".2d", ".2s", ".2s",
6523 [(set (v2i64 V128:$dst),
6524 (Accum (v2i64 V128:$Rd),
6525 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
6526 (v2i32 V64:$Rm)))))]>;
6527 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6529 asm#"2", ".2d", ".4s", ".4s",
6530 [(set (v2i64 V128:$dst),
6531 (Accum (v2i64 V128:$Rd),
6532 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
6533 (extract_high_v4i32 V128:$Rm)))))]>;
6536 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
6537 SDPatternOperator OpNode> {
6538 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6540 asm, ".8h", ".8h", ".8b",
6541 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
6542 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6544 asm#"2", ".8h", ".8h", ".16b",
6545 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
6546 (extract_high_v16i8 V128:$Rm)))]>;
6547 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6549 asm, ".4s", ".4s", ".4h",
6550 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
6551 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6553 asm#"2", ".4s", ".4s", ".8h",
6554 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
6555 (extract_high_v8i16 V128:$Rm)))]>;
6556 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6558 asm, ".2d", ".2d", ".2s",
6559 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
6560 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6562 asm#"2", ".2d", ".2d", ".4s",
6563 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
6564 (extract_high_v4i32 V128:$Rm)))]>;
6567 //----------------------------------------------------------------------------
6568 // AdvSIMD bitwise extract from vector
6569 //----------------------------------------------------------------------------
6571 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
6572 string asm, string kind>
6573 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
6574 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
6575 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
6576 [(set (vty regtype:$Rd),
6577 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
6584 let Inst{30} = size;
6585 let Inst{29-21} = 0b101110000;
6586 let Inst{20-16} = Rm;
6588 let Inst{14-11} = imm;
6595 multiclass SIMDBitwiseExtract<string asm> {
6596 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
6599 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
6602 //----------------------------------------------------------------------------
6603 // AdvSIMD zip vector
6604 //----------------------------------------------------------------------------
6606 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
6607 string asm, string kind, SDNode OpNode, ValueType valty>
6608 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6609 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
6610 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
6611 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
6617 let Inst{30} = size{0};
6618 let Inst{29-24} = 0b001110;
6619 let Inst{23-22} = size{2-1};
6621 let Inst{20-16} = Rm;
6623 let Inst{14-12} = opc;
6624 let Inst{11-10} = 0b10;
6629 multiclass SIMDZipVector<bits<3>opc, string asm,
6631 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
6632 asm, ".8b", OpNode, v8i8>;
6633 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
6634 asm, ".16b", OpNode, v16i8>;
6635 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
6636 asm, ".4h", OpNode, v4i16>;
6637 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
6638 asm, ".8h", OpNode, v8i16>;
6639 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
6640 asm, ".2s", OpNode, v2i32>;
6641 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
6642 asm, ".4s", OpNode, v4i32>;
6643 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
6644 asm, ".2d", OpNode, v2i64>;
6646 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
6647 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
6648 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
6649 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
6650 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
6651 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
6652 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
6653 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
6654 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
6655 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
6658 //----------------------------------------------------------------------------
6659 // AdvSIMD three register scalar instructions
6660 //----------------------------------------------------------------------------
6662 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6663 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
6664 RegisterClass regtype, string asm,
6666 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6667 "\t$Rd, $Rn, $Rm", "", pattern>,
6672 let Inst{31-30} = 0b01;
6674 let Inst{28-24} = 0b11110;
6675 let Inst{23-21} = size;
6676 let Inst{20-16} = Rm;
6677 let Inst{15-11} = opcode;
6683 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6684 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
6685 dag oops, dag iops, string asm,
6687 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
6692 let Inst{31-30} = 0b01;
6694 let Inst{28-24} = 0b11110;
6695 let Inst{23-22} = size;
6697 let Inst{20-16} = Rm;
6698 let Inst{15-11} = opcode;
6704 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
6705 SDPatternOperator OpNode> {
6706 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6707 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6710 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
6711 SDPatternOperator OpNode> {
6712 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6713 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6714 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
6715 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6716 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
6718 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
6719 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
6720 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
6721 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
6724 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
6725 SDPatternOperator OpNode> {
6726 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
6727 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6728 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6731 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
6732 SDPatternOperator OpNode = null_frag> {
6733 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
6734 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
6736 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
6737 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
6741 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
6742 SDPatternOperator OpNode = null_frag> {
6743 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6744 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6745 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6746 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6747 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6748 let Predicates = [HasNEON, HasFullFP16] in {
6749 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6750 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>;
6751 } // Predicates = [HasNEON, HasFullFP16]
6754 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6755 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6758 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
6759 SDPatternOperator OpNode = null_frag> {
6760 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6761 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6762 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6763 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6764 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
6765 let Predicates = [HasNEON, HasFullFP16] in {
6766 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6768 } // Predicates = [HasNEON, HasFullFP16]
6771 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6772 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6775 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
6776 dag oops, dag iops, string asm, string cstr, list<dag> pat>
6777 : I<oops, iops, asm,
6778 "\t$Rd, $Rn, $Rm", cstr, pat>,
6783 let Inst{31-30} = 0b01;
6785 let Inst{28-24} = 0b11110;
6786 let Inst{23-22} = size;
6788 let Inst{20-16} = Rm;
6789 let Inst{15-11} = opcode;
6795 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6796 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
6797 SDPatternOperator OpNode = null_frag> {
6798 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6800 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
6801 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6803 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
6804 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6807 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6808 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
6809 SDPatternOperator OpNode = null_frag> {
6810 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6812 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
6813 asm, "$Rd = $dst", []>;
6814 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6816 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
6818 [(set (i64 FPR64:$dst),
6819 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6822 //----------------------------------------------------------------------------
6823 // AdvSIMD two register scalar instructions
6824 //----------------------------------------------------------------------------
6826 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6827 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6828 RegisterClass regtype, RegisterClass regtype2,
6829 string asm, list<dag> pat>
6830 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6831 "\t$Rd, $Rn", "", pat>,
6835 let Inst{31-30} = 0b01;
6837 let Inst{28-24} = 0b11110;
6838 let Inst{23-22} = size;
6840 let Inst{20-19} = size2;
6841 let Inst{18-17} = 0b00;
6842 let Inst{16-12} = opcode;
6843 let Inst{11-10} = 0b10;
6848 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6849 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6850 RegisterClass regtype, RegisterClass regtype2,
6851 string asm, list<dag> pat>
6852 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6853 "\t$Rd, $Rn", "$Rd = $dst", pat>,
6857 let Inst{31-30} = 0b01;
6859 let Inst{28-24} = 0b11110;
6860 let Inst{23-22} = size;
6861 let Inst{21-17} = 0b10000;
6862 let Inst{16-12} = opcode;
6863 let Inst{11-10} = 0b10;
6869 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6870 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6871 RegisterClass regtype, string asm, string zero>
6872 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6873 "\t$Rd, $Rn, #" # zero, "", []>,
6877 let Inst{31-30} = 0b01;
6879 let Inst{28-24} = 0b11110;
6880 let Inst{23-22} = size;
6882 let Inst{20-19} = size2;
6883 let Inst{18-17} = 0b00;
6884 let Inst{16-12} = opcode;
6885 let Inst{11-10} = 0b10;
6890 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6891 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6892 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6896 let Inst{31-17} = 0b011111100110000;
6897 let Inst{16-12} = opcode;
6898 let Inst{11-10} = 0b10;
6903 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6904 SDPatternOperator OpNode> {
6905 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6907 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6908 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6911 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6912 SDPatternOperator OpNode> {
6913 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
6914 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
6915 let Predicates = [HasNEON, HasFullFP16] in {
6916 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
6919 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6920 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
6921 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6922 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
6923 let Predicates = [HasNEON, HasFullFP16] in {
6924 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6925 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
6928 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
6929 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6932 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
6933 SDPatternOperator OpNode = null_frag> {
6934 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6935 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
6937 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
6938 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
6941 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
6942 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
6943 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
6944 let Predicates = [HasNEON, HasFullFP16] in {
6945 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
6949 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
6950 SDPatternOperator OpNode> {
6951 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
6952 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
6953 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
6954 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
6955 let Predicates = [HasNEON, HasFullFP16] in {
6956 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
6957 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>;
6961 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
6962 SDPatternOperator OpNode = null_frag> {
6963 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6964 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6965 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6966 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
6967 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
6968 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
6969 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
6972 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
6973 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
6976 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
6978 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6979 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
6980 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
6981 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
6982 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
6983 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
6984 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
6987 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
6988 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
6993 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6994 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
6995 SDPatternOperator OpNode = null_frag> {
6996 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
6997 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6998 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
6999 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
7002 //----------------------------------------------------------------------------
7003 // AdvSIMD scalar pairwise instructions
7004 //----------------------------------------------------------------------------
7006 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7007 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
7008 RegisterOperand regtype, RegisterOperand vectype,
7009 string asm, string kind>
7010 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7011 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
7015 let Inst{31-30} = 0b01;
7017 let Inst{28-24} = 0b11110;
7018 let Inst{23-22} = size;
7019 let Inst{21-17} = 0b11000;
7020 let Inst{16-12} = opcode;
7021 let Inst{11-10} = 0b10;
7026 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
7027 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
7031 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
7032 let Predicates = [HasNEON, HasFullFP16] in {
7033 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
7036 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
7038 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
7042 //----------------------------------------------------------------------------
7043 // AdvSIMD across lanes instructions
7044 //----------------------------------------------------------------------------
7046 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7047 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
7048 RegisterClass regtype, RegisterOperand vectype,
7049 string asm, string kind, list<dag> pattern>
7050 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7051 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
7058 let Inst{28-24} = 0b01110;
7059 let Inst{23-22} = size;
7060 let Inst{21-17} = 0b11000;
7061 let Inst{16-12} = opcode;
7062 let Inst{11-10} = 0b10;
7067 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
7069 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
7071 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
7073 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
7075 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
7077 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
7081 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
7082 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
7084 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
7086 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
7088 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
7090 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
7094 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
7096 let Predicates = [HasNEON, HasFullFP16] in {
7097 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
7099 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>;
7100 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
7102 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>;
7103 } // Predicates = [HasNEON, HasFullFP16]
7104 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
7106 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
7109 //----------------------------------------------------------------------------
7110 // AdvSIMD INS/DUP instructions
7111 //----------------------------------------------------------------------------
7113 // FIXME: There has got to be a better way to factor these. ugh.
7115 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
7116 string operands, string constraints, list<dag> pattern>
7117 : I<outs, ins, asm, operands, constraints, pattern>,
7124 let Inst{28-21} = 0b01110000;
7131 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
7132 RegisterOperand vecreg, RegisterClass regtype>
7133 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
7134 "{\t$Rd" # size # ", $Rn" #
7135 "|" # size # "\t$Rd, $Rn}", "",
7136 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
7137 let Inst{20-16} = imm5;
7138 let Inst{14-11} = 0b0001;
7141 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
7142 ValueType vectype, ValueType insreg,
7143 RegisterOperand vecreg, Operand idxtype,
7144 ValueType elttype, SDNode OpNode>
7145 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
7146 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
7147 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
7148 [(set (vectype vecreg:$Rd),
7149 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
7150 let Inst{14-11} = 0b0000;
7153 class SIMDDup64FromElement
7154 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
7155 VectorIndexD, i64, AArch64duplane64> {
7158 let Inst{19-16} = 0b1000;
7161 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
7162 RegisterOperand vecreg>
7163 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
7164 VectorIndexS, i64, AArch64duplane32> {
7166 let Inst{20-19} = idx;
7167 let Inst{18-16} = 0b100;
7170 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
7171 RegisterOperand vecreg>
7172 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
7173 VectorIndexH, i64, AArch64duplane16> {
7175 let Inst{20-18} = idx;
7176 let Inst{17-16} = 0b10;
7179 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
7180 RegisterOperand vecreg>
7181 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
7182 VectorIndexB, i64, AArch64duplane8> {
7184 let Inst{20-17} = idx;
7188 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
7189 Operand idxtype, string asm, list<dag> pattern>
7190 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
7191 "{\t$Rd, $Rn" # size # "$idx" #
7192 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
7193 let Inst{14-11} = imm4;
7196 class SIMDSMov<bit Q, string size, RegisterClass regtype,
7198 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
7199 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
7201 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
7202 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
7204 class SIMDMovAlias<string asm, string size, Instruction inst,
7205 RegisterClass regtype, Operand idxtype>
7206 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
7207 "|" # size # "\t$dst, $src$idx}",
7208 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
7211 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
7213 let Inst{20-17} = idx;
7216 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
7218 let Inst{20-17} = idx;
7221 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
7223 let Inst{20-18} = idx;
7224 let Inst{17-16} = 0b10;
7226 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
7228 let Inst{20-18} = idx;
7229 let Inst{17-16} = 0b10;
7231 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
7233 let Inst{20-19} = idx;
7234 let Inst{18-16} = 0b100;
7239 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
7241 let Inst{20-17} = idx;
7244 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
7246 let Inst{20-18} = idx;
7247 let Inst{17-16} = 0b10;
7249 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
7251 let Inst{20-19} = idx;
7252 let Inst{18-16} = 0b100;
7254 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
7257 let Inst{19-16} = 0b1000;
7259 def : SIMDMovAlias<"mov", ".s",
7260 !cast<Instruction>(NAME#"vi32"),
7261 GPR32, VectorIndexS>;
7262 def : SIMDMovAlias<"mov", ".d",
7263 !cast<Instruction>(NAME#"vi64"),
7264 GPR64, VectorIndexD>;
7267 class SIMDInsFromMain<string size, ValueType vectype,
7268 RegisterClass regtype, Operand idxtype>
7269 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
7270 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
7271 "{\t$Rd" # size # "$idx, $Rn" #
7272 "|" # size # "\t$Rd$idx, $Rn}",
7275 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
7276 let Inst{14-11} = 0b0011;
7279 class SIMDInsFromElement<string size, ValueType vectype,
7280 ValueType elttype, Operand idxtype>
7281 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
7282 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
7283 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
7284 "|" # size # "\t$Rd$idx, $Rn$idx2}",
7289 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
7292 class SIMDInsMainMovAlias<string size, Instruction inst,
7293 RegisterClass regtype, Operand idxtype>
7294 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
7295 "|" # size #"\t$dst$idx, $src}",
7296 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
7297 class SIMDInsElementMovAlias<string size, Instruction inst,
7299 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2"
7300 # "|" # size #"\t$dst$idx, $src$idx2}",
7301 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
7304 multiclass SIMDIns {
7305 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
7307 let Inst{20-17} = idx;
7310 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
7312 let Inst{20-18} = idx;
7313 let Inst{17-16} = 0b10;
7315 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
7317 let Inst{20-19} = idx;
7318 let Inst{18-16} = 0b100;
7320 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
7323 let Inst{19-16} = 0b1000;
7326 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
7329 let Inst{20-17} = idx;
7331 let Inst{14-11} = idx2;
7333 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
7336 let Inst{20-18} = idx;
7337 let Inst{17-16} = 0b10;
7338 let Inst{14-12} = idx2;
7341 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
7344 let Inst{20-19} = idx;
7345 let Inst{18-16} = 0b100;
7346 let Inst{14-13} = idx2;
7347 let Inst{12-11} = {?,?};
7349 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
7353 let Inst{19-16} = 0b1000;
7354 let Inst{14} = idx2;
7355 let Inst{13-11} = {?,?,?};
7358 // For all forms of the INS instruction, the "mov" mnemonic is the
7359 // preferred alias. Why they didn't just call the instruction "mov" in
7360 // the first place is a very good question indeed...
7361 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
7362 GPR32, VectorIndexB>;
7363 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
7364 GPR32, VectorIndexH>;
7365 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
7366 GPR32, VectorIndexS>;
7367 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
7368 GPR64, VectorIndexD>;
7370 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
7372 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
7374 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
7376 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
7380 //----------------------------------------------------------------------------
7382 //----------------------------------------------------------------------------
7384 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7385 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7386 RegisterOperand listtype, string asm, string kind>
7387 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
7388 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
7395 let Inst{29-21} = 0b001110000;
7396 let Inst{20-16} = Vm;
7398 let Inst{14-13} = len;
7400 let Inst{11-10} = 0b00;
7405 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7406 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7407 RegisterOperand listtype, string asm, string kind>
7408 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
7409 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
7416 let Inst{29-21} = 0b001110000;
7417 let Inst{20-16} = Vm;
7419 let Inst{14-13} = len;
7421 let Inst{11-10} = 0b00;
7426 class SIMDTableLookupAlias<string asm, Instruction inst,
7427 RegisterOperand vectype, RegisterOperand listtype>
7428 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
7429 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
7431 multiclass SIMDTableLookup<bit op, string asm> {
7432 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
7434 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
7436 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
7438 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
7440 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
7442 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
7444 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
7446 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
7449 def : SIMDTableLookupAlias<asm # ".8b",
7450 !cast<Instruction>(NAME#"v8i8One"),
7451 V64, VecListOne128>;
7452 def : SIMDTableLookupAlias<asm # ".8b",
7453 !cast<Instruction>(NAME#"v8i8Two"),
7454 V64, VecListTwo128>;
7455 def : SIMDTableLookupAlias<asm # ".8b",
7456 !cast<Instruction>(NAME#"v8i8Three"),
7457 V64, VecListThree128>;
7458 def : SIMDTableLookupAlias<asm # ".8b",
7459 !cast<Instruction>(NAME#"v8i8Four"),
7460 V64, VecListFour128>;
7461 def : SIMDTableLookupAlias<asm # ".16b",
7462 !cast<Instruction>(NAME#"v16i8One"),
7463 V128, VecListOne128>;
7464 def : SIMDTableLookupAlias<asm # ".16b",
7465 !cast<Instruction>(NAME#"v16i8Two"),
7466 V128, VecListTwo128>;
7467 def : SIMDTableLookupAlias<asm # ".16b",
7468 !cast<Instruction>(NAME#"v16i8Three"),
7469 V128, VecListThree128>;
7470 def : SIMDTableLookupAlias<asm # ".16b",
7471 !cast<Instruction>(NAME#"v16i8Four"),
7472 V128, VecListFour128>;
7475 multiclass SIMDTableLookupTied<bit op, string asm> {
7476 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
7478 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
7480 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
7482 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
7484 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
7486 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
7488 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
7490 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
7493 def : SIMDTableLookupAlias<asm # ".8b",
7494 !cast<Instruction>(NAME#"v8i8One"),
7495 V64, VecListOne128>;
7496 def : SIMDTableLookupAlias<asm # ".8b",
7497 !cast<Instruction>(NAME#"v8i8Two"),
7498 V64, VecListTwo128>;
7499 def : SIMDTableLookupAlias<asm # ".8b",
7500 !cast<Instruction>(NAME#"v8i8Three"),
7501 V64, VecListThree128>;
7502 def : SIMDTableLookupAlias<asm # ".8b",
7503 !cast<Instruction>(NAME#"v8i8Four"),
7504 V64, VecListFour128>;
7505 def : SIMDTableLookupAlias<asm # ".16b",
7506 !cast<Instruction>(NAME#"v16i8One"),
7507 V128, VecListOne128>;
7508 def : SIMDTableLookupAlias<asm # ".16b",
7509 !cast<Instruction>(NAME#"v16i8Two"),
7510 V128, VecListTwo128>;
7511 def : SIMDTableLookupAlias<asm # ".16b",
7512 !cast<Instruction>(NAME#"v16i8Three"),
7513 V128, VecListThree128>;
7514 def : SIMDTableLookupAlias<asm # ".16b",
7515 !cast<Instruction>(NAME#"v16i8Four"),
7516 V128, VecListFour128>;
7520 //----------------------------------------------------------------------------
7521 // AdvSIMD scalar CPY
7522 //----------------------------------------------------------------------------
7523 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7524 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
7525 string kind, Operand idxtype>
7526 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
7527 "{\t$dst, $src" # kind # "$idx" #
7528 "|\t$dst, $src$idx}", "", []>,
7532 let Inst{31-21} = 0b01011110000;
7533 let Inst{15-10} = 0b000001;
7534 let Inst{9-5} = src;
7535 let Inst{4-0} = dst;
7538 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
7539 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
7540 : InstAlias<asm # "{\t$dst, $src" # size # "$index"
7541 # "|\t$dst, $src$index}",
7542 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
7545 multiclass SIMDScalarCPY<string asm> {
7546 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
7548 let Inst{20-17} = idx;
7551 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
7553 let Inst{20-18} = idx;
7554 let Inst{17-16} = 0b10;
7556 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
7558 let Inst{20-19} = idx;
7559 let Inst{18-16} = 0b100;
7561 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
7564 let Inst{19-16} = 0b1000;
7567 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
7568 VectorIndexD:$idx)))),
7569 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
7571 // 'DUP' mnemonic aliases.
7572 def : SIMDScalarCPYAlias<"dup", ".b",
7573 !cast<Instruction>(NAME#"i8"),
7574 FPR8, V128, VectorIndexB>;
7575 def : SIMDScalarCPYAlias<"dup", ".h",
7576 !cast<Instruction>(NAME#"i16"),
7577 FPR16, V128, VectorIndexH>;
7578 def : SIMDScalarCPYAlias<"dup", ".s",
7579 !cast<Instruction>(NAME#"i32"),
7580 FPR32, V128, VectorIndexS>;
7581 def : SIMDScalarCPYAlias<"dup", ".d",
7582 !cast<Instruction>(NAME#"i64"),
7583 FPR64, V128, VectorIndexD>;
7586 //----------------------------------------------------------------------------
7587 // AdvSIMD modified immediate instructions
7588 //----------------------------------------------------------------------------
7590 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
7591 string asm, string op_string,
7592 string cstr, list<dag> pattern>
7593 : I<oops, iops, asm, op_string, cstr, pattern>,
7600 let Inst{28-19} = 0b0111100000;
7601 let Inst{18-16} = imm8{7-5};
7604 let Inst{9-5} = imm8{4-0};
7608 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
7609 Operand immtype, dag opt_shift_iop,
7610 string opt_shift, string asm, string kind,
7612 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
7613 !con((ins immtype:$imm8), opt_shift_iop), asm,
7614 "{\t$Rd" # kind # ", $imm8" # opt_shift #
7615 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7617 let DecoderMethod = "DecodeModImmInstruction";
7620 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
7621 Operand immtype, dag opt_shift_iop,
7622 string opt_shift, string asm, string kind,
7624 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
7625 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
7626 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
7627 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7628 "$Rd = $dst", pattern> {
7629 let DecoderMethod = "DecodeModImmTiedInstruction";
7632 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
7633 RegisterOperand vectype, string asm,
7634 string kind, list<dag> pattern>
7635 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7636 (ins logical_vec_shift:$shift),
7637 "$shift", asm, kind, pattern> {
7639 let Inst{15} = b15_b12{1};
7640 let Inst{14-13} = shift;
7641 let Inst{12} = b15_b12{0};
7644 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
7645 RegisterOperand vectype, string asm,
7646 string kind, list<dag> pattern>
7647 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7648 (ins logical_vec_shift:$shift),
7649 "$shift", asm, kind, pattern> {
7651 let Inst{15} = b15_b12{1};
7652 let Inst{14-13} = shift;
7653 let Inst{12} = b15_b12{0};
7657 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
7658 RegisterOperand vectype, string asm,
7659 string kind, list<dag> pattern>
7660 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7661 (ins logical_vec_hw_shift:$shift),
7662 "$shift", asm, kind, pattern> {
7664 let Inst{15} = b15_b12{1};
7666 let Inst{13} = shift{0};
7667 let Inst{12} = b15_b12{0};
7670 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
7671 RegisterOperand vectype, string asm,
7672 string kind, list<dag> pattern>
7673 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7674 (ins logical_vec_hw_shift:$shift),
7675 "$shift", asm, kind, pattern> {
7677 let Inst{15} = b15_b12{1};
7679 let Inst{13} = shift{0};
7680 let Inst{12} = b15_b12{0};
7683 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
7685 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
7687 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
7690 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
7692 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
7696 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
7697 bits<2> w_cmode, string asm,
7699 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
7701 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
7703 (i32 imm:$shift)))]>;
7704 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
7706 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
7708 (i32 imm:$shift)))]>;
7710 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
7712 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
7714 (i32 imm:$shift)))]>;
7715 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
7717 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
7719 (i32 imm:$shift)))]>;
7722 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
7723 RegisterOperand vectype, string asm,
7724 string kind, list<dag> pattern>
7725 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7726 (ins move_vec_shift:$shift),
7727 "$shift", asm, kind, pattern> {
7729 let Inst{15-13} = cmode{3-1};
7730 let Inst{12} = shift;
7733 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
7734 RegisterOperand vectype,
7735 Operand imm_type, string asm,
7736 string kind, list<dag> pattern>
7737 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
7738 asm, kind, pattern> {
7739 let Inst{15-12} = cmode;
7742 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
7744 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
7745 "\t$Rd, $imm8", "", pattern> {
7746 let Inst{15-12} = cmode;
7747 let DecoderMethod = "DecodeModImmInstruction";
7750 //----------------------------------------------------------------------------
7751 // AdvSIMD indexed element
7752 //----------------------------------------------------------------------------
7754 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7755 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7756 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7757 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7758 string apple_kind, string dst_kind, string lhs_kind,
7759 string rhs_kind, list<dag> pattern>
7760 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
7762 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7763 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
7772 let Inst{28} = Scalar;
7773 let Inst{27-24} = 0b1111;
7774 let Inst{23-22} = size;
7775 // Bit 21 must be set by the derived class.
7776 let Inst{20-16} = Rm;
7777 let Inst{15-12} = opc;
7778 // Bit 11 must be set by the derived class.
7784 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7785 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7786 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7787 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7788 string apple_kind, string dst_kind, string lhs_kind,
7789 string rhs_kind, list<dag> pattern>
7790 : I<(outs dst_reg:$dst),
7791 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
7792 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7793 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
7802 let Inst{28} = Scalar;
7803 let Inst{27-24} = 0b1111;
7804 let Inst{23-22} = size;
7805 // Bit 21 must be set by the derived class.
7806 let Inst{20-16} = Rm;
7807 let Inst{15-12} = opc;
7808 // Bit 11 must be set by the derived class.
7815 //----------------------------------------------------------------------------
7816 // Armv8.6 BFloat16 Extension
7817 //----------------------------------------------------------------------------
7818 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in {
7820 class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1,
7821 string kind2, RegisterOperand RegType,
7822 ValueType AccumType, ValueType InputType>
7823 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst),
7824 (int_aarch64_neon_bfdot (AccumType RegType:$Rd),
7825 (InputType RegType:$Rn),
7826 (InputType RegType:$Rm)))]> {
7827 let AsmString = !strconcat(asm,
7828 "{\t$Rd" # kind1 # ", $Rn" # kind2 #
7829 ", $Rm" # kind2 # "}");
7832 multiclass SIMDThreeSameVectorBFDot<bit U, string asm> {
7833 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64,
7835 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,
7839 class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
7840 string dst_kind, string lhs_kind,
7842 RegisterOperand RegType,
7843 ValueType AccumType,
7844 ValueType InputType>
7845 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111,
7846 RegType, RegType, V128, VectorIndexS,
7847 asm, "", dst_kind, lhs_kind, rhs_kind,
7848 [(set (AccumType RegType:$dst),
7849 (AccumType (int_aarch64_neon_bfdot
7850 (AccumType RegType:$Rd),
7851 (InputType RegType:$Rn),
7852 (InputType (bitconvert (AccumType
7853 (AArch64duplane32 (v4f32 V128:$Rm),
7854 VectorIndexH:$idx)))))))]> {
7857 let Inst{21} = idx{0}; // L
7858 let Inst{11} = idx{1}; // H
7861 multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> {
7863 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h",
7864 ".2h", V64, v2f32, v8i8>;
7865 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h",
7866 ".2h", V128, v4f32, v16i8>;
7869 class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode>
7870 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s",
7871 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
7873 (v16i8 V128:$Rm)))]> {
7874 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}");
7877 class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode>
7878 : I<(outs V128:$dst),
7879 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm,
7880 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst",
7881 [(set (v4f32 V128:$dst),
7882 (v4f32 (OpNode (v4f32 V128:$Rd),
7884 (v16i8 (bitconvert (v8bf16
7885 (AArch64duplane16 (v8bf16 V128_lo:$Rm),
7886 VectorIndexH:$idx)))))))]>,
7895 let Inst{29-22} = 0b00111111;
7896 let Inst{21-20} = idx{1-0};
7897 let Inst{19-16} = Rm;
7898 let Inst{15-12} = 0b1111;
7899 let Inst{11} = idx{2}; // H
7905 class SIMDThreeSameVectorBF16MatrixMul<string asm>
7906 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101,
7908 [(set (v4f32 V128:$dst),
7909 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd),
7911 (v16i8 V128:$Rm)))]> {
7912 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h",
7913 ", $Rm", ".8h", "}");
7917 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128,
7918 "bfcvtn", ".4h", ".4s",
7919 [(set (v8bf16 V128:$Rd),
7920 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>;
7923 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128,
7924 "bfcvtn2", ".8h", ".4s",
7925 [(set (v8bf16 V128:$dst),
7926 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>;
7928 class BF16ToSinglePrecision<string asm>
7929 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "",
7930 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>,
7931 Sched<[WriteFCvt]> {
7934 let Inst{31-10} = 0b0001111001100011010000;
7938 } // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0
7940 //----------------------------------------------------------------------------
7941 // Armv8.6 Matrix Multiply Extension
7942 //----------------------------------------------------------------------------
7944 class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode>
7945 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s",
7946 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
7948 (v16i8 V128:$Rm)))]> {
7949 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}";
7952 //----------------------------------------------------------------------------
7953 // ARMv8.2-A Dot Product Instructions (Indexed)
7954 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm,
7955 string dst_kind, string lhs_kind, string rhs_kind,
7956 RegisterOperand RegType,
7957 ValueType AccumType, ValueType InputType,
7958 SDPatternOperator OpNode> :
7959 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128,
7960 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
7961 [(set (AccumType RegType:$dst),
7962 (AccumType (OpNode (AccumType RegType:$Rd),
7963 (InputType RegType:$Rn),
7964 (InputType (bitconvert (AccumType
7965 (AArch64duplane32 (v4i32 V128:$Rm),
7966 VectorIndexS:$idx)))))))]> {
7968 let Inst{21} = idx{0}; // L
7969 let Inst{11} = idx{1}; // H
7972 multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm,
7973 SDPatternOperator OpNode> {
7974 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b",
7975 V64, v2i32, v8i8, OpNode>;
7976 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b",
7977 V128, v4i32, v16i8, OpNode>;
7980 // ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed)
7981 class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm,
7982 string dst_kind, string lhs_kind,
7983 string rhs_kind, RegisterOperand RegType,
7984 ValueType AccumType, ValueType InputType,
7985 SDPatternOperator OpNode> :
7986 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128,
7987 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind,
7988 [(set (AccumType RegType:$dst),
7989 (AccumType (OpNode (AccumType RegType:$Rd),
7990 (InputType RegType:$Rn),
7991 (InputType (AArch64duplane16 (v8f16 V128:$Rm),
7992 VectorIndexH:$idx)))))]> {
7995 let Inst{11} = idx{2}; // H
7996 let Inst{21} = idx{1}; // L
7997 let Inst{20} = idx{0}; // M
8000 multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm,
8001 SDPatternOperator OpNode> {
8002 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h",
8003 V64, v2f32, v4f16, OpNode>;
8004 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h",
8005 V128, v4f32, v8f16, OpNode>;
8008 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
8009 SDPatternOperator OpNode> {
8010 let Predicates = [HasNEON, HasFullFP16] in {
8011 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
8013 V128_lo, VectorIndexH,
8014 asm, ".4h", ".4h", ".4h", ".h",
8015 [(set (v4f16 V64:$Rd),
8016 (OpNode (v4f16 V64:$Rn),
8017 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8019 let Inst{11} = idx{2};
8020 let Inst{21} = idx{1};
8021 let Inst{20} = idx{0};
8024 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
8026 V128_lo, VectorIndexH,
8027 asm, ".8h", ".8h", ".8h", ".h",
8028 [(set (v8f16 V128:$Rd),
8029 (OpNode (v8f16 V128:$Rn),
8030 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8032 let Inst{11} = idx{2};
8033 let Inst{21} = idx{1};
8034 let Inst{20} = idx{0};
8036 } // Predicates = [HasNEON, HasFullFP16]
8038 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8041 asm, ".2s", ".2s", ".2s", ".s",
8042 [(set (v2f32 V64:$Rd),
8043 (OpNode (v2f32 V64:$Rn),
8044 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8046 let Inst{11} = idx{1};
8047 let Inst{21} = idx{0};
8050 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8053 asm, ".4s", ".4s", ".4s", ".s",
8054 [(set (v4f32 V128:$Rd),
8055 (OpNode (v4f32 V128:$Rn),
8056 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8058 let Inst{11} = idx{1};
8059 let Inst{21} = idx{0};
8062 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
8065 asm, ".2d", ".2d", ".2d", ".d",
8066 [(set (v2f64 V128:$Rd),
8067 (OpNode (v2f64 V128:$Rn),
8068 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
8070 let Inst{11} = idx{0};
8074 let Predicates = [HasNEON, HasFullFP16] in {
8075 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
8076 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8077 asm, ".h", "", "", ".h",
8078 [(set (f16 FPR16Op:$Rd),
8079 (OpNode (f16 FPR16Op:$Rn),
8080 (f16 (vector_extract (v8f16 V128_lo:$Rm),
8081 VectorIndexH:$idx))))]> {
8083 let Inst{11} = idx{2};
8084 let Inst{21} = idx{1};
8085 let Inst{20} = idx{0};
8087 } // Predicates = [HasNEON, HasFullFP16]
8089 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8090 FPR32Op, FPR32Op, V128, VectorIndexS,
8091 asm, ".s", "", "", ".s",
8092 [(set (f32 FPR32Op:$Rd),
8093 (OpNode (f32 FPR32Op:$Rn),
8094 (f32 (vector_extract (v4f32 V128:$Rm),
8095 VectorIndexS:$idx))))]> {
8097 let Inst{11} = idx{1};
8098 let Inst{21} = idx{0};
8101 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
8102 FPR64Op, FPR64Op, V128, VectorIndexD,
8103 asm, ".d", "", "", ".d",
8104 [(set (f64 FPR64Op:$Rd),
8105 (OpNode (f64 FPR64Op:$Rn),
8106 (f64 (vector_extract (v2f64 V128:$Rm),
8107 VectorIndexD:$idx))))]> {
8109 let Inst{11} = idx{0};
8114 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
8115 let Predicates = [HasNEON, HasFullFP16] in {
8116 // Patterns for f16: DUPLANE, DUP scalar and vector_extract.
8117 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8118 (AArch64duplane16 (v8f16 V128_lo:$Rm),
8119 VectorIndexH:$idx))),
8120 (!cast<Instruction>(INST # "v8i16_indexed")
8121 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8122 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8123 (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8124 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn,
8125 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8127 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8128 (AArch64duplane16 (v8f16 V128_lo:$Rm),
8129 VectorIndexH:$idx))),
8130 (!cast<Instruction>(INST # "v4i16_indexed")
8131 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8132 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8133 (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8134 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn,
8135 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8137 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn),
8138 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))),
8139 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn,
8140 V128_lo:$Rm, VectorIndexH:$idx)>;
8141 } // Predicates = [HasNEON, HasFullFP16]
8143 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
8144 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8145 (AArch64duplane32 (v4f32 V128:$Rm),
8146 VectorIndexS:$idx))),
8147 (!cast<Instruction>(INST # v2i32_indexed)
8148 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8149 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8150 (AArch64dup (f32 FPR32Op:$Rm)))),
8151 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
8152 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8155 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
8156 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8157 (AArch64duplane32 (v4f32 V128:$Rm),
8158 VectorIndexS:$idx))),
8159 (!cast<Instruction>(INST # "v4i32_indexed")
8160 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8161 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8162 (AArch64dup (f32 FPR32Op:$Rm)))),
8163 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
8164 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8166 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
8167 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
8168 (AArch64duplane64 (v2f64 V128:$Rm),
8169 VectorIndexD:$idx))),
8170 (!cast<Instruction>(INST # "v2i64_indexed")
8171 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8172 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
8173 (AArch64dup (f64 FPR64Op:$Rm)))),
8174 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
8175 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
8177 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s
8178 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
8179 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
8180 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
8181 V128:$Rm, VectorIndexS:$idx)>;
8183 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
8184 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
8185 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
8186 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
8187 V128:$Rm, VectorIndexD:$idx)>;
8190 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
8191 let Predicates = [HasNEON, HasFullFP16] in {
8192 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
8193 V128_lo, VectorIndexH,
8194 asm, ".4h", ".4h", ".4h", ".h", []> {
8196 let Inst{11} = idx{2};
8197 let Inst{21} = idx{1};
8198 let Inst{20} = idx{0};
8201 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
8203 V128_lo, VectorIndexH,
8204 asm, ".8h", ".8h", ".8h", ".h", []> {
8206 let Inst{11} = idx{2};
8207 let Inst{21} = idx{1};
8208 let Inst{20} = idx{0};
8210 } // Predicates = [HasNEON, HasFullFP16]
8212 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
8214 asm, ".2s", ".2s", ".2s", ".s", []> {
8216 let Inst{11} = idx{1};
8217 let Inst{21} = idx{0};
8220 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8223 asm, ".4s", ".4s", ".4s", ".s", []> {
8225 let Inst{11} = idx{1};
8226 let Inst{21} = idx{0};
8229 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
8232 asm, ".2d", ".2d", ".2d", ".d", []> {
8234 let Inst{11} = idx{0};
8238 let Predicates = [HasNEON, HasFullFP16] in {
8239 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
8240 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8241 asm, ".h", "", "", ".h", []> {
8243 let Inst{11} = idx{2};
8244 let Inst{21} = idx{1};
8245 let Inst{20} = idx{0};
8247 } // Predicates = [HasNEON, HasFullFP16]
8249 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8250 FPR32Op, FPR32Op, V128, VectorIndexS,
8251 asm, ".s", "", "", ".s", []> {
8253 let Inst{11} = idx{1};
8254 let Inst{21} = idx{0};
8257 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
8258 FPR64Op, FPR64Op, V128, VectorIndexD,
8259 asm, ".d", "", "", ".d", []> {
8261 let Inst{11} = idx{0};
8266 multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane,
8267 SDPatternOperator OpNodeLaneQ> {
8269 def : Pat<(v4i16 (OpNodeLane
8270 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm),
8271 VectorIndexS32b:$idx)),
8272 (!cast<Instruction>(NAME # v4i16_indexed) $Rn,
8273 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub),
8274 (UImmS1XForm $idx))>;
8276 def : Pat<(v4i16 (OpNodeLaneQ
8277 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm),
8278 VectorIndexH32b:$idx)),
8279 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm,
8280 (UImmS1XForm $idx))>;
8282 def : Pat<(v8i16 (OpNodeLane
8283 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm),
8284 VectorIndexS32b:$idx)),
8285 (!cast<Instruction>(NAME # v8i16_indexed) $Rn,
8286 (SUBREG_TO_REG (i32 0), $Rm, dsub),
8287 (UImmS1XForm $idx))>;
8289 def : Pat<(v8i16 (OpNodeLaneQ
8290 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm),
8291 VectorIndexH32b:$idx)),
8292 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm,
8293 (UImmS1XForm $idx))>;
8295 def : Pat<(v2i32 (OpNodeLane
8296 (v2i32 V64:$Rn), (v2i32 V64:$Rm),
8297 VectorIndexD32b:$idx)),
8298 (!cast<Instruction>(NAME # v2i32_indexed) $Rn,
8299 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub),
8300 (UImmS1XForm $idx))>;
8302 def : Pat<(v2i32 (OpNodeLaneQ
8303 (v2i32 V64:$Rn), (v4i32 V128:$Rm),
8304 VectorIndexS32b:$idx)),
8305 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm,
8306 (UImmS1XForm $idx))>;
8308 def : Pat<(v4i32 (OpNodeLane
8309 (v4i32 V128:$Rn), (v2i32 V64:$Rm),
8310 VectorIndexD32b:$idx)),
8311 (!cast<Instruction>(NAME # v4i32_indexed) $Rn,
8312 (SUBREG_TO_REG (i32 0), $Rm, dsub),
8313 (UImmS1XForm $idx))>;
8315 def : Pat<(v4i32 (OpNodeLaneQ
8318 VectorIndexS32b:$idx)),
8319 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm,
8320 (UImmS1XForm $idx))>;
8324 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
8325 SDPatternOperator OpNode> {
8326 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
8327 V128_lo, VectorIndexH,
8328 asm, ".4h", ".4h", ".4h", ".h",
8329 [(set (v4i16 V64:$Rd),
8330 (OpNode (v4i16 V64:$Rn),
8331 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8333 let Inst{11} = idx{2};
8334 let Inst{21} = idx{1};
8335 let Inst{20} = idx{0};
8338 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8340 V128_lo, VectorIndexH,
8341 asm, ".8h", ".8h", ".8h", ".h",
8342 [(set (v8i16 V128:$Rd),
8343 (OpNode (v8i16 V128:$Rn),
8344 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8346 let Inst{11} = idx{2};
8347 let Inst{21} = idx{1};
8348 let Inst{20} = idx{0};
8351 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8354 asm, ".2s", ".2s", ".2s", ".s",
8355 [(set (v2i32 V64:$Rd),
8356 (OpNode (v2i32 V64:$Rn),
8357 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8359 let Inst{11} = idx{1};
8360 let Inst{21} = idx{0};
8363 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8366 asm, ".4s", ".4s", ".4s", ".s",
8367 [(set (v4i32 V128:$Rd),
8368 (OpNode (v4i32 V128:$Rn),
8369 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8371 let Inst{11} = idx{1};
8372 let Inst{21} = idx{0};
8375 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
8376 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8377 asm, ".h", "", "", ".h", []> {
8379 let Inst{11} = idx{2};
8380 let Inst{21} = idx{1};
8381 let Inst{20} = idx{0};
8384 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8385 FPR32Op, FPR32Op, V128, VectorIndexS,
8386 asm, ".s", "", "", ".s",
8387 [(set (i32 FPR32Op:$Rd),
8388 (OpNode FPR32Op:$Rn,
8389 (i32 (vector_extract (v4i32 V128:$Rm),
8390 VectorIndexS:$idx))))]> {
8392 let Inst{11} = idx{1};
8393 let Inst{21} = idx{0};
8397 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
8398 SDPatternOperator OpNode> {
8399 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8401 V128_lo, VectorIndexH,
8402 asm, ".4h", ".4h", ".4h", ".h",
8403 [(set (v4i16 V64:$Rd),
8404 (OpNode (v4i16 V64:$Rn),
8405 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8407 let Inst{11} = idx{2};
8408 let Inst{21} = idx{1};
8409 let Inst{20} = idx{0};
8412 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8414 V128_lo, VectorIndexH,
8415 asm, ".8h", ".8h", ".8h", ".h",
8416 [(set (v8i16 V128:$Rd),
8417 (OpNode (v8i16 V128:$Rn),
8418 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8420 let Inst{11} = idx{2};
8421 let Inst{21} = idx{1};
8422 let Inst{20} = idx{0};
8425 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8428 asm, ".2s", ".2s", ".2s", ".s",
8429 [(set (v2i32 V64:$Rd),
8430 (OpNode (v2i32 V64:$Rn),
8431 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8433 let Inst{11} = idx{1};
8434 let Inst{21} = idx{0};
8437 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8440 asm, ".4s", ".4s", ".4s", ".s",
8441 [(set (v4i32 V128:$Rd),
8442 (OpNode (v4i32 V128:$Rn),
8443 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8445 let Inst{11} = idx{1};
8446 let Inst{21} = idx{0};
8450 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
8451 SDPatternOperator OpNode> {
8452 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
8453 V128_lo, VectorIndexH,
8454 asm, ".4h", ".4h", ".4h", ".h",
8455 [(set (v4i16 V64:$dst),
8456 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
8457 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8459 let Inst{11} = idx{2};
8460 let Inst{21} = idx{1};
8461 let Inst{20} = idx{0};
8464 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8466 V128_lo, VectorIndexH,
8467 asm, ".8h", ".8h", ".8h", ".h",
8468 [(set (v8i16 V128:$dst),
8469 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8470 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8472 let Inst{11} = idx{2};
8473 let Inst{21} = idx{1};
8474 let Inst{20} = idx{0};
8477 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8480 asm, ".2s", ".2s", ".2s", ".s",
8481 [(set (v2i32 V64:$dst),
8482 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8483 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8485 let Inst{11} = idx{1};
8486 let Inst{21} = idx{0};
8489 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8492 asm, ".4s", ".4s", ".4s", ".s",
8493 [(set (v4i32 V128:$dst),
8494 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8495 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8497 let Inst{11} = idx{1};
8498 let Inst{21} = idx{0};
8502 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
8503 SDPatternOperator OpNode> {
8504 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8506 V128_lo, VectorIndexH,
8507 asm, ".4s", ".4s", ".4h", ".h",
8508 [(set (v4i32 V128:$Rd),
8509 (OpNode (v4i16 V64:$Rn),
8510 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8512 let Inst{11} = idx{2};
8513 let Inst{21} = idx{1};
8514 let Inst{20} = idx{0};
8517 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8519 V128_lo, VectorIndexH,
8520 asm#"2", ".4s", ".4s", ".8h", ".h",
8521 [(set (v4i32 V128:$Rd),
8522 (OpNode (extract_high_v8i16 V128:$Rn),
8523 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8524 VectorIndexH:$idx))))]> {
8527 let Inst{11} = idx{2};
8528 let Inst{21} = idx{1};
8529 let Inst{20} = idx{0};
8532 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8535 asm, ".2d", ".2d", ".2s", ".s",
8536 [(set (v2i64 V128:$Rd),
8537 (OpNode (v2i32 V64:$Rn),
8538 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8540 let Inst{11} = idx{1};
8541 let Inst{21} = idx{0};
8544 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8547 asm#"2", ".2d", ".2d", ".4s", ".s",
8548 [(set (v2i64 V128:$Rd),
8549 (OpNode (extract_high_v4i32 V128:$Rn),
8550 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8551 VectorIndexS:$idx))))]> {
8553 let Inst{11} = idx{1};
8554 let Inst{21} = idx{0};
8557 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
8558 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8559 asm, ".h", "", "", ".h", []> {
8561 let Inst{11} = idx{2};
8562 let Inst{21} = idx{1};
8563 let Inst{20} = idx{0};
8566 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8567 FPR64Op, FPR32Op, V128, VectorIndexS,
8568 asm, ".s", "", "", ".s", []> {
8570 let Inst{11} = idx{1};
8571 let Inst{21} = idx{0};
8575 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
8576 SDPatternOperator Accum> {
8577 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8579 V128_lo, VectorIndexH,
8580 asm, ".4s", ".4s", ".4h", ".h",
8581 [(set (v4i32 V128:$dst),
8582 (Accum (v4i32 V128:$Rd),
8583 (v4i32 (int_aarch64_neon_sqdmull
8585 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8586 VectorIndexH:$idx))))))]> {
8588 let Inst{11} = idx{2};
8589 let Inst{21} = idx{1};
8590 let Inst{20} = idx{0};
8593 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
8594 // intermediate EXTRACT_SUBREG would be untyped.
8595 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8596 (i32 (vector_extract (v4i32
8597 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
8598 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8599 VectorIndexH:$idx)))),
8602 (!cast<Instruction>(NAME # v4i16_indexed)
8603 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
8604 V128_lo:$Rm, VectorIndexH:$idx),
8607 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8609 V128_lo, VectorIndexH,
8610 asm#"2", ".4s", ".4s", ".8h", ".h",
8611 [(set (v4i32 V128:$dst),
8612 (Accum (v4i32 V128:$Rd),
8613 (v4i32 (int_aarch64_neon_sqdmull
8614 (extract_high_v8i16 V128:$Rn),
8616 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8617 VectorIndexH:$idx))))))]> {
8619 let Inst{11} = idx{2};
8620 let Inst{21} = idx{1};
8621 let Inst{20} = idx{0};
8624 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8627 asm, ".2d", ".2d", ".2s", ".s",
8628 [(set (v2i64 V128:$dst),
8629 (Accum (v2i64 V128:$Rd),
8630 (v2i64 (int_aarch64_neon_sqdmull
8632 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8633 VectorIndexS:$idx))))))]> {
8635 let Inst{11} = idx{1};
8636 let Inst{21} = idx{0};
8639 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8642 asm#"2", ".2d", ".2d", ".4s", ".s",
8643 [(set (v2i64 V128:$dst),
8644 (Accum (v2i64 V128:$Rd),
8645 (v2i64 (int_aarch64_neon_sqdmull
8646 (extract_high_v4i32 V128:$Rn),
8648 (AArch64duplane32 (v4i32 V128:$Rm),
8649 VectorIndexS:$idx))))))]> {
8651 let Inst{11} = idx{1};
8652 let Inst{21} = idx{0};
8655 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8656 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8657 asm, ".h", "", "", ".h", []> {
8659 let Inst{11} = idx{2};
8660 let Inst{21} = idx{1};
8661 let Inst{20} = idx{0};
8665 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8666 FPR64Op, FPR32Op, V128, VectorIndexS,
8667 asm, ".s", "", "", ".s",
8668 [(set (i64 FPR64Op:$dst),
8669 (Accum (i64 FPR64Op:$Rd),
8670 (i64 (int_aarch64_neon_sqdmulls_scalar
8672 (i32 (vector_extract (v4i32 V128:$Rm),
8673 VectorIndexS:$idx))))))]> {
8676 let Inst{11} = idx{1};
8677 let Inst{21} = idx{0};
8681 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
8682 SDPatternOperator OpNode> {
8683 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8684 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8686 V128_lo, VectorIndexH,
8687 asm, ".4s", ".4s", ".4h", ".h",
8688 [(set (v4i32 V128:$Rd),
8689 (OpNode (v4i16 V64:$Rn),
8690 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8692 let Inst{11} = idx{2};
8693 let Inst{21} = idx{1};
8694 let Inst{20} = idx{0};
8697 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8699 V128_lo, VectorIndexH,
8700 asm#"2", ".4s", ".4s", ".8h", ".h",
8701 [(set (v4i32 V128:$Rd),
8702 (OpNode (extract_high_v8i16 V128:$Rn),
8703 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8704 VectorIndexH:$idx))))]> {
8707 let Inst{11} = idx{2};
8708 let Inst{21} = idx{1};
8709 let Inst{20} = idx{0};
8712 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8715 asm, ".2d", ".2d", ".2s", ".s",
8716 [(set (v2i64 V128:$Rd),
8717 (OpNode (v2i32 V64:$Rn),
8718 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8720 let Inst{11} = idx{1};
8721 let Inst{21} = idx{0};
8724 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8727 asm#"2", ".2d", ".2d", ".4s", ".s",
8728 [(set (v2i64 V128:$Rd),
8729 (OpNode (extract_high_v4i32 V128:$Rn),
8730 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8731 VectorIndexS:$idx))))]> {
8733 let Inst{11} = idx{1};
8734 let Inst{21} = idx{0};
8739 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
8740 SDPatternOperator OpNode> {
8741 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8742 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8744 V128_lo, VectorIndexH,
8745 asm, ".4s", ".4s", ".4h", ".h",
8746 [(set (v4i32 V128:$dst),
8747 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
8748 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8750 let Inst{11} = idx{2};
8751 let Inst{21} = idx{1};
8752 let Inst{20} = idx{0};
8755 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8757 V128_lo, VectorIndexH,
8758 asm#"2", ".4s", ".4s", ".8h", ".h",
8759 [(set (v4i32 V128:$dst),
8760 (OpNode (v4i32 V128:$Rd),
8761 (extract_high_v8i16 V128:$Rn),
8762 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8763 VectorIndexH:$idx))))]> {
8765 let Inst{11} = idx{2};
8766 let Inst{21} = idx{1};
8767 let Inst{20} = idx{0};
8770 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8773 asm, ".2d", ".2d", ".2s", ".s",
8774 [(set (v2i64 V128:$dst),
8775 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
8776 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8778 let Inst{11} = idx{1};
8779 let Inst{21} = idx{0};
8782 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8785 asm#"2", ".2d", ".2d", ".4s", ".s",
8786 [(set (v2i64 V128:$dst),
8787 (OpNode (v2i64 V128:$Rd),
8788 (extract_high_v4i32 V128:$Rn),
8789 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8790 VectorIndexS:$idx))))]> {
8792 let Inst{11} = idx{1};
8793 let Inst{21} = idx{0};
8798 //----------------------------------------------------------------------------
8799 // AdvSIMD scalar shift by immediate
8800 //----------------------------------------------------------------------------
8802 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8803 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
8804 RegisterClass regtype1, RegisterClass regtype2,
8805 Operand immtype, string asm, list<dag> pattern>
8806 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
8807 asm, "\t$Rd, $Rn, $imm", "", pattern>,
8812 let Inst{31-30} = 0b01;
8814 let Inst{28-23} = 0b111110;
8815 let Inst{22-16} = fixed_imm;
8816 let Inst{15-11} = opc;
8822 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8823 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
8824 RegisterClass regtype1, RegisterClass regtype2,
8825 Operand immtype, string asm, list<dag> pattern>
8826 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
8827 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
8832 let Inst{31-30} = 0b01;
8834 let Inst{28-23} = 0b111110;
8835 let Inst{22-16} = fixed_imm;
8836 let Inst{15-11} = opc;
8843 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
8844 let Predicates = [HasNEON, HasFullFP16] in {
8845 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8846 FPR16, FPR16, vecshiftR16, asm, []> {
8847 let Inst{19-16} = imm{3-0};
8849 } // Predicates = [HasNEON, HasFullFP16]
8850 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8851 FPR32, FPR32, vecshiftR32, asm, []> {
8852 let Inst{20-16} = imm{4-0};
8854 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8855 FPR64, FPR64, vecshiftR64, asm, []> {
8856 let Inst{21-16} = imm{5-0};
8860 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
8861 SDPatternOperator OpNode> {
8862 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8863 FPR64, FPR64, vecshiftR64, asm,
8864 [(set (i64 FPR64:$Rd),
8865 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
8866 let Inst{21-16} = imm{5-0};
8869 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
8870 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
8873 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
8874 SDPatternOperator OpNode = null_frag> {
8875 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8876 FPR64, FPR64, vecshiftR64, asm,
8877 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
8878 (i32 vecshiftR64:$imm)))]> {
8879 let Inst{21-16} = imm{5-0};
8882 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
8883 (i32 vecshiftR64:$imm))),
8884 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
8888 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
8889 SDPatternOperator OpNode> {
8890 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8891 FPR64, FPR64, vecshiftL64, asm,
8892 [(set (v1i64 FPR64:$Rd),
8893 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8894 let Inst{21-16} = imm{5-0};
8898 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8899 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
8900 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8901 FPR64, FPR64, vecshiftL64, asm, []> {
8902 let Inst{21-16} = imm{5-0};
8906 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8907 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
8908 SDPatternOperator OpNode = null_frag> {
8909 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8910 FPR8, FPR16, vecshiftR8, asm, []> {
8911 let Inst{18-16} = imm{2-0};
8914 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8915 FPR16, FPR32, vecshiftR16, asm, []> {
8916 let Inst{19-16} = imm{3-0};
8919 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8920 FPR32, FPR64, vecshiftR32, asm,
8921 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
8922 let Inst{20-16} = imm{4-0};
8926 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
8927 SDPatternOperator OpNode> {
8928 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8929 FPR8, FPR8, vecshiftL8, asm, []> {
8930 let Inst{18-16} = imm{2-0};
8933 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8934 FPR16, FPR16, vecshiftL16, asm, []> {
8935 let Inst{19-16} = imm{3-0};
8938 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8939 FPR32, FPR32, vecshiftL32, asm,
8940 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
8941 let Inst{20-16} = imm{4-0};
8944 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8945 FPR64, FPR64, vecshiftL64, asm,
8946 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8947 let Inst{21-16} = imm{5-0};
8950 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
8951 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
8954 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
8955 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8956 FPR8, FPR8, vecshiftR8, asm, []> {
8957 let Inst{18-16} = imm{2-0};
8960 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8961 FPR16, FPR16, vecshiftR16, asm, []> {
8962 let Inst{19-16} = imm{3-0};
8965 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8966 FPR32, FPR32, vecshiftR32, asm, []> {
8967 let Inst{20-16} = imm{4-0};
8970 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8971 FPR64, FPR64, vecshiftR64, asm, []> {
8972 let Inst{21-16} = imm{5-0};
8976 //----------------------------------------------------------------------------
8977 // AdvSIMD vector x indexed element
8978 //----------------------------------------------------------------------------
8980 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8981 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8982 RegisterOperand dst_reg, RegisterOperand src_reg,
8984 string asm, string dst_kind, string src_kind,
8986 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
8987 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8988 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
8995 let Inst{28-23} = 0b011110;
8996 let Inst{22-16} = fixed_imm;
8997 let Inst{15-11} = opc;
9003 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9004 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
9005 RegisterOperand vectype1, RegisterOperand vectype2,
9007 string asm, string dst_kind, string src_kind,
9009 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
9010 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
9011 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
9018 let Inst{28-23} = 0b011110;
9019 let Inst{22-16} = fixed_imm;
9020 let Inst{15-11} = opc;
9026 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
9028 let Predicates = [HasNEON, HasFullFP16] in {
9029 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9030 V64, V64, vecshiftR16,
9032 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
9034 let Inst{19-16} = imm;
9037 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9038 V128, V128, vecshiftR16,
9040 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
9042 let Inst{19-16} = imm;
9044 } // Predicates = [HasNEON, HasFullFP16]
9045 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9046 V64, V64, vecshiftR32,
9048 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
9050 let Inst{20-16} = imm;
9053 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9054 V128, V128, vecshiftR32,
9056 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
9058 let Inst{20-16} = imm;
9061 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9062 V128, V128, vecshiftR64,
9064 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
9066 let Inst{21-16} = imm;
9070 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
9072 let Predicates = [HasNEON, HasFullFP16] in {
9073 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9074 V64, V64, vecshiftR16,
9076 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
9078 let Inst{19-16} = imm;
9081 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9082 V128, V128, vecshiftR16,
9084 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
9086 let Inst{19-16} = imm;
9088 } // Predicates = [HasNEON, HasFullFP16]
9090 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9091 V64, V64, vecshiftR32,
9093 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
9095 let Inst{20-16} = imm;
9098 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9099 V128, V128, vecshiftR32,
9101 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
9103 let Inst{20-16} = imm;
9106 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9107 V128, V128, vecshiftR64,
9109 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
9111 let Inst{21-16} = imm;
9115 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
9116 SDPatternOperator OpNode> {
9117 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9118 V64, V128, vecshiftR16Narrow,
9120 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
9122 let Inst{18-16} = imm;
9125 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9126 V128, V128, vecshiftR16Narrow,
9127 asm#"2", ".16b", ".8h", []> {
9129 let Inst{18-16} = imm;
9130 let hasSideEffects = 0;
9133 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9134 V64, V128, vecshiftR32Narrow,
9136 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
9138 let Inst{19-16} = imm;
9141 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9142 V128, V128, vecshiftR32Narrow,
9143 asm#"2", ".8h", ".4s", []> {
9145 let Inst{19-16} = imm;
9146 let hasSideEffects = 0;
9149 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9150 V64, V128, vecshiftR64Narrow,
9152 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
9154 let Inst{20-16} = imm;
9157 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9158 V128, V128, vecshiftR64Narrow,
9159 asm#"2", ".4s", ".2d", []> {
9161 let Inst{20-16} = imm;
9162 let hasSideEffects = 0;
9165 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
9166 // themselves, so put them here instead.
9168 // Patterns involving what's effectively an insert high and a normal
9169 // intrinsic, represented by CONCAT_VECTORS.
9170 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
9171 vecshiftR16Narrow:$imm)),
9172 (!cast<Instruction>(NAME # "v16i8_shift")
9173 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9174 V128:$Rn, vecshiftR16Narrow:$imm)>;
9175 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
9176 vecshiftR32Narrow:$imm)),
9177 (!cast<Instruction>(NAME # "v8i16_shift")
9178 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9179 V128:$Rn, vecshiftR32Narrow:$imm)>;
9180 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
9181 vecshiftR64Narrow:$imm)),
9182 (!cast<Instruction>(NAME # "v4i32_shift")
9183 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9184 V128:$Rn, vecshiftR64Narrow:$imm)>;
9187 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
9188 SDPatternOperator OpNode> {
9189 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9190 V64, V64, vecshiftL8,
9192 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
9193 (i32 vecshiftL8:$imm)))]> {
9195 let Inst{18-16} = imm;
9198 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9199 V128, V128, vecshiftL8,
9200 asm, ".16b", ".16b",
9201 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
9202 (i32 vecshiftL8:$imm)))]> {
9204 let Inst{18-16} = imm;
9207 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9208 V64, V64, vecshiftL16,
9210 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
9211 (i32 vecshiftL16:$imm)))]> {
9213 let Inst{19-16} = imm;
9216 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9217 V128, V128, vecshiftL16,
9219 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
9220 (i32 vecshiftL16:$imm)))]> {
9222 let Inst{19-16} = imm;
9225 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9226 V64, V64, vecshiftL32,
9228 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
9229 (i32 vecshiftL32:$imm)))]> {
9231 let Inst{20-16} = imm;
9234 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9235 V128, V128, vecshiftL32,
9237 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
9238 (i32 vecshiftL32:$imm)))]> {
9240 let Inst{20-16} = imm;
9243 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9244 V128, V128, vecshiftL64,
9246 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
9247 (i32 vecshiftL64:$imm)))]> {
9249 let Inst{21-16} = imm;
9253 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
9254 SDPatternOperator OpNode> {
9255 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9256 V64, V64, vecshiftR8,
9258 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
9259 (i32 vecshiftR8:$imm)))]> {
9261 let Inst{18-16} = imm;
9264 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9265 V128, V128, vecshiftR8,
9266 asm, ".16b", ".16b",
9267 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
9268 (i32 vecshiftR8:$imm)))]> {
9270 let Inst{18-16} = imm;
9273 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9274 V64, V64, vecshiftR16,
9276 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
9277 (i32 vecshiftR16:$imm)))]> {
9279 let Inst{19-16} = imm;
9282 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9283 V128, V128, vecshiftR16,
9285 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
9286 (i32 vecshiftR16:$imm)))]> {
9288 let Inst{19-16} = imm;
9291 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9292 V64, V64, vecshiftR32,
9294 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
9295 (i32 vecshiftR32:$imm)))]> {
9297 let Inst{20-16} = imm;
9300 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9301 V128, V128, vecshiftR32,
9303 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
9304 (i32 vecshiftR32:$imm)))]> {
9306 let Inst{20-16} = imm;
9309 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9310 V128, V128, vecshiftR64,
9312 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
9313 (i32 vecshiftR64:$imm)))]> {
9315 let Inst{21-16} = imm;
9319 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9320 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
9321 SDPatternOperator OpNode = null_frag> {
9322 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
9323 V64, V64, vecshiftR8, asm, ".8b", ".8b",
9324 [(set (v8i8 V64:$dst),
9325 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
9326 (i32 vecshiftR8:$imm)))]> {
9328 let Inst{18-16} = imm;
9331 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9332 V128, V128, vecshiftR8, asm, ".16b", ".16b",
9333 [(set (v16i8 V128:$dst),
9334 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
9335 (i32 vecshiftR8:$imm)))]> {
9337 let Inst{18-16} = imm;
9340 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
9341 V64, V64, vecshiftR16, asm, ".4h", ".4h",
9342 [(set (v4i16 V64:$dst),
9343 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
9344 (i32 vecshiftR16:$imm)))]> {
9346 let Inst{19-16} = imm;
9349 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9350 V128, V128, vecshiftR16, asm, ".8h", ".8h",
9351 [(set (v8i16 V128:$dst),
9352 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9353 (i32 vecshiftR16:$imm)))]> {
9355 let Inst{19-16} = imm;
9358 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
9359 V64, V64, vecshiftR32, asm, ".2s", ".2s",
9360 [(set (v2i32 V64:$dst),
9361 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9362 (i32 vecshiftR32:$imm)))]> {
9364 let Inst{20-16} = imm;
9367 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9368 V128, V128, vecshiftR32, asm, ".4s", ".4s",
9369 [(set (v4i32 V128:$dst),
9370 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9371 (i32 vecshiftR32:$imm)))]> {
9373 let Inst{20-16} = imm;
9376 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
9377 V128, V128, vecshiftR64,
9378 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
9379 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
9380 (i32 vecshiftR64:$imm)))]> {
9382 let Inst{21-16} = imm;
9386 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
9387 SDPatternOperator OpNode = null_frag> {
9388 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
9389 V64, V64, vecshiftL8,
9391 [(set (v8i8 V64:$dst),
9392 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
9393 (i32 vecshiftL8:$imm)))]> {
9395 let Inst{18-16} = imm;
9398 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9399 V128, V128, vecshiftL8,
9400 asm, ".16b", ".16b",
9401 [(set (v16i8 V128:$dst),
9402 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
9403 (i32 vecshiftL8:$imm)))]> {
9405 let Inst{18-16} = imm;
9408 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
9409 V64, V64, vecshiftL16,
9411 [(set (v4i16 V64:$dst),
9412 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
9413 (i32 vecshiftL16:$imm)))]> {
9415 let Inst{19-16} = imm;
9418 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9419 V128, V128, vecshiftL16,
9421 [(set (v8i16 V128:$dst),
9422 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9423 (i32 vecshiftL16:$imm)))]> {
9425 let Inst{19-16} = imm;
9428 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
9429 V64, V64, vecshiftL32,
9431 [(set (v2i32 V64:$dst),
9432 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9433 (i32 vecshiftL32:$imm)))]> {
9435 let Inst{20-16} = imm;
9438 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9439 V128, V128, vecshiftL32,
9441 [(set (v4i32 V128:$dst),
9442 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9443 (i32 vecshiftL32:$imm)))]> {
9445 let Inst{20-16} = imm;
9448 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
9449 V128, V128, vecshiftL64,
9451 [(set (v2i64 V128:$dst),
9452 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
9453 (i32 vecshiftL64:$imm)))]> {
9455 let Inst{21-16} = imm;
9459 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
9460 SDPatternOperator OpNode> {
9461 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9462 V128, V64, vecshiftL8, asm, ".8h", ".8b",
9463 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
9465 let Inst{18-16} = imm;
9468 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9469 V128, V128, vecshiftL8,
9470 asm#"2", ".8h", ".16b",
9471 [(set (v8i16 V128:$Rd),
9472 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
9474 let Inst{18-16} = imm;
9477 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9478 V128, V64, vecshiftL16, asm, ".4s", ".4h",
9479 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
9481 let Inst{19-16} = imm;
9484 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9485 V128, V128, vecshiftL16,
9486 asm#"2", ".4s", ".8h",
9487 [(set (v4i32 V128:$Rd),
9488 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
9491 let Inst{19-16} = imm;
9494 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9495 V128, V64, vecshiftL32, asm, ".2d", ".2s",
9496 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
9498 let Inst{20-16} = imm;
9501 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9502 V128, V128, vecshiftL32,
9503 asm#"2", ".2d", ".4s",
9504 [(set (v2i64 V128:$Rd),
9505 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
9507 let Inst{20-16} = imm;
9513 // Vector load/store
9515 // SIMD ldX/stX no-index memory references don't allow the optional
9516 // ", #0" constant and handle post-indexing explicitly, so we use
9517 // a more specialized parse method for them. Otherwise, it's the same as
9518 // the general GPR64sp handling.
9520 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
9521 string asm, dag oops, dag iops, list<dag> pattern>
9522 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
9527 let Inst{29-23} = 0b0011000;
9529 let Inst{21-16} = 0b000000;
9530 let Inst{15-12} = opcode;
9531 let Inst{11-10} = size;
9536 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
9537 string asm, dag oops, dag iops>
9538 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
9544 let Inst{29-23} = 0b0011001;
9547 let Inst{20-16} = Xm;
9548 let Inst{15-12} = opcode;
9549 let Inst{11-10} = size;
9554 // The immediate form of AdvSIMD post-indexed addressing is encoded with
9555 // register post-index addressing from the zero register.
9556 multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
9557 int Offset, int Size> {
9558 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
9559 // "ld1\t$Vt, [$Rn], #16"
9560 // may get mapped to
9561 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
9562 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9563 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9565 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9568 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
9569 // "ld1.8b\t$Vt, [$Rn], #16"
9570 // may get mapped to
9571 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
9572 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9573 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9575 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9578 // E.g. "ld1.8b { v0, v1 }, [x1]"
9579 // "ld1\t$Vt, [$Rn]"
9580 // may get mapped to
9581 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
9582 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9583 (!cast<Instruction>(BaseName # Count # "v" # layout)
9584 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9587 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
9588 // "ld1\t$Vt, [$Rn], $Xm"
9589 // may get mapped to
9590 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
9591 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9592 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9594 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9595 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9598 multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
9599 int Offset128, int Offset64, bits<4> opcode> {
9600 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9601 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
9602 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
9603 (ins GPR64sp:$Rn), []>;
9604 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
9605 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
9606 (ins GPR64sp:$Rn), []>;
9607 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
9608 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
9609 (ins GPR64sp:$Rn), []>;
9610 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
9611 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
9612 (ins GPR64sp:$Rn), []>;
9613 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
9614 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
9615 (ins GPR64sp:$Rn), []>;
9616 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
9617 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
9618 (ins GPR64sp:$Rn), []>;
9619 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
9620 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
9621 (ins GPR64sp:$Rn), []>;
9624 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
9625 (outs GPR64sp:$wback,
9626 !cast<RegisterOperand>(veclist # "16b"):$Vt),
9628 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9629 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
9630 (outs GPR64sp:$wback,
9631 !cast<RegisterOperand>(veclist # "8h"):$Vt),
9633 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9634 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
9635 (outs GPR64sp:$wback,
9636 !cast<RegisterOperand>(veclist # "4s"):$Vt),
9638 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9639 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
9640 (outs GPR64sp:$wback,
9641 !cast<RegisterOperand>(veclist # "2d"):$Vt),
9643 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9644 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
9645 (outs GPR64sp:$wback,
9646 !cast<RegisterOperand>(veclist # "8b"):$Vt),
9648 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9649 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
9650 (outs GPR64sp:$wback,
9651 !cast<RegisterOperand>(veclist # "4h"):$Vt),
9653 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9654 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
9655 (outs GPR64sp:$wback,
9656 !cast<RegisterOperand>(veclist # "2s"):$Vt),
9658 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9661 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9662 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9663 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9664 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9665 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9666 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9667 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9670 // Only ld1/st1 has a v1d version.
9671 multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
9672 int Offset128, int Offset64, bits<4> opcode> {
9673 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
9674 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
9675 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9677 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
9678 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9680 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
9681 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9683 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
9684 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9686 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
9687 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9689 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
9690 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9692 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
9693 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9696 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
9697 (outs GPR64sp:$wback),
9698 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9700 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9701 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
9702 (outs GPR64sp:$wback),
9703 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9705 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9706 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
9707 (outs GPR64sp:$wback),
9708 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9710 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9711 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
9712 (outs GPR64sp:$wback),
9713 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9715 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9716 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
9717 (outs GPR64sp:$wback),
9718 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9720 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9721 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
9722 (outs GPR64sp:$wback),
9723 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9725 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9726 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
9727 (outs GPR64sp:$wback),
9728 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9730 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9733 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9734 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9735 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9736 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9737 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9738 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9739 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9742 multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
9743 int Offset128, int Offset64, bits<4> opcode>
9744 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9746 // LD1 instructions have extra "1d" variants.
9747 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9748 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
9749 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
9750 (ins GPR64sp:$Rn), []>;
9752 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
9753 (outs GPR64sp:$wback,
9754 !cast<RegisterOperand>(veclist # "1d"):$Vt),
9756 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9759 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9762 multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
9763 int Offset128, int Offset64, bits<4> opcode>
9764 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9766 // ST1 instructions have extra "1d" variants.
9767 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
9768 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
9769 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9772 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
9773 (outs GPR64sp:$wback),
9774 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9776 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9779 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9782 multiclass SIMDLd1Multiple<string asm> {
9783 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
9784 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9785 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9786 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9789 multiclass SIMDSt1Multiple<string asm> {
9790 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
9791 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9792 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9793 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9796 multiclass SIMDLd2Multiple<string asm> {
9797 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9800 multiclass SIMDSt2Multiple<string asm> {
9801 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9804 multiclass SIMDLd3Multiple<string asm> {
9805 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9808 multiclass SIMDSt3Multiple<string asm> {
9809 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9812 multiclass SIMDLd4Multiple<string asm> {
9813 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9816 multiclass SIMDSt4Multiple<string asm> {
9817 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9821 // AdvSIMD Load/store single-element
9824 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
9825 string asm, string operands, string cst,
9826 dag oops, dag iops, list<dag> pattern>
9827 : I<oops, iops, asm, operands, cst, pattern> {
9831 let Inst{29-24} = 0b001101;
9834 let Inst{15-13} = opcode;
9839 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
9840 string asm, string operands, string cst,
9841 dag oops, dag iops, list<dag> pattern>
9842 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
9846 let Inst{29-24} = 0b001101;
9849 let Inst{15-13} = opcode;
9855 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9856 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
9857 DAGOperand listtype>
9858 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
9859 (outs listtype:$Vt), (ins GPR64sp:$Rn),
9863 let Inst{20-16} = 0b00000;
9865 let Inst{11-10} = size;
9867 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9868 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
9869 string asm, DAGOperand listtype, DAGOperand GPR64pi>
9870 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
9872 (outs GPR64sp:$wback, listtype:$Vt),
9873 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
9877 let Inst{20-16} = Xm;
9879 let Inst{11-10} = size;
9882 multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
9883 int Offset, int Size> {
9884 // E.g. "ld1r { v0.8b }, [x1], #1"
9885 // "ld1r.8b\t$Vt, [$Rn], #1"
9886 // may get mapped to
9887 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9888 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9889 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9891 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9894 // E.g. "ld1r.8b { v0 }, [x1], #1"
9895 // "ld1r.8b\t$Vt, [$Rn], #1"
9896 // may get mapped to
9897 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9898 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9899 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9901 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9904 // E.g. "ld1r.8b { v0 }, [x1]"
9905 // "ld1r.8b\t$Vt, [$Rn]"
9906 // may get mapped to
9907 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9908 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9909 (!cast<Instruction>(BaseName # "v" # layout)
9910 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9913 // E.g. "ld1r.8b { v0 }, [x1], x2"
9914 // "ld1r.8b\t$Vt, [$Rn], $Xm"
9915 // may get mapped to
9916 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9917 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9918 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9920 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9921 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9924 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
9925 int Offset1, int Offset2, int Offset4, int Offset8> {
9926 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
9927 !cast<DAGOperand>("VecList" # Count # "8b")>;
9928 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
9929 !cast<DAGOperand>("VecList" # Count #"16b")>;
9930 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
9931 !cast<DAGOperand>("VecList" # Count #"4h")>;
9932 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
9933 !cast<DAGOperand>("VecList" # Count #"8h")>;
9934 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
9935 !cast<DAGOperand>("VecList" # Count #"2s")>;
9936 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
9937 !cast<DAGOperand>("VecList" # Count #"4s")>;
9938 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
9939 !cast<DAGOperand>("VecList" # Count #"1d")>;
9940 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
9941 !cast<DAGOperand>("VecList" # Count #"2d")>;
9943 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
9944 !cast<DAGOperand>("VecList" # Count # "8b"),
9945 !cast<DAGOperand>("GPR64pi" # Offset1)>;
9946 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
9947 !cast<DAGOperand>("VecList" # Count # "16b"),
9948 !cast<DAGOperand>("GPR64pi" # Offset1)>;
9949 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
9950 !cast<DAGOperand>("VecList" # Count # "4h"),
9951 !cast<DAGOperand>("GPR64pi" # Offset2)>;
9952 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
9953 !cast<DAGOperand>("VecList" # Count # "8h"),
9954 !cast<DAGOperand>("GPR64pi" # Offset2)>;
9955 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
9956 !cast<DAGOperand>("VecList" # Count # "2s"),
9957 !cast<DAGOperand>("GPR64pi" # Offset4)>;
9958 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
9959 !cast<DAGOperand>("VecList" # Count # "4s"),
9960 !cast<DAGOperand>("GPR64pi" # Offset4)>;
9961 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
9962 !cast<DAGOperand>("VecList" # Count # "1d"),
9963 !cast<DAGOperand>("GPR64pi" # Offset8)>;
9964 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
9965 !cast<DAGOperand>("VecList" # Count # "2d"),
9966 !cast<DAGOperand>("GPR64pi" # Offset8)>;
9968 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>;
9969 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
9970 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>;
9971 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>;
9972 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>;
9973 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>;
9974 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>;
9975 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>;
9978 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
9979 dag oops, dag iops, list<dag> pattern>
9980 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9982 // idx encoded in Q:S:size fields.
9984 let Inst{30} = idx{3};
9986 let Inst{20-16} = 0b00000;
9987 let Inst{12} = idx{2};
9988 let Inst{11-10} = idx{1-0};
9990 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
9991 dag oops, dag iops, list<dag> pattern>
9992 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9993 oops, iops, pattern> {
9994 // idx encoded in Q:S:size fields.
9996 let Inst{30} = idx{3};
9998 let Inst{20-16} = 0b00000;
9999 let Inst{12} = idx{2};
10000 let Inst{11-10} = idx{1-0};
10002 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
10003 dag oops, dag iops>
10004 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10005 "$Rn = $wback", oops, iops, []> {
10006 // idx encoded in Q:S:size fields.
10009 let Inst{30} = idx{3};
10011 let Inst{20-16} = Xm;
10012 let Inst{12} = idx{2};
10013 let Inst{11-10} = idx{1-0};
10015 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
10016 dag oops, dag iops>
10017 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10018 "$Rn = $wback", oops, iops, []> {
10019 // idx encoded in Q:S:size fields.
10022 let Inst{30} = idx{3};
10024 let Inst{20-16} = Xm;
10025 let Inst{12} = idx{2};
10026 let Inst{11-10} = idx{1-0};
10029 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
10030 dag oops, dag iops, list<dag> pattern>
10031 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10033 // idx encoded in Q:S:size<1> fields.
10035 let Inst{30} = idx{2};
10037 let Inst{20-16} = 0b00000;
10038 let Inst{12} = idx{1};
10039 let Inst{11} = idx{0};
10040 let Inst{10} = size;
10042 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
10043 dag oops, dag iops, list<dag> pattern>
10044 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10045 oops, iops, pattern> {
10046 // idx encoded in Q:S:size<1> fields.
10048 let Inst{30} = idx{2};
10050 let Inst{20-16} = 0b00000;
10051 let Inst{12} = idx{1};
10052 let Inst{11} = idx{0};
10053 let Inst{10} = size;
10056 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10057 dag oops, dag iops>
10058 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10059 "$Rn = $wback", oops, iops, []> {
10060 // idx encoded in Q:S:size<1> fields.
10063 let Inst{30} = idx{2};
10065 let Inst{20-16} = Xm;
10066 let Inst{12} = idx{1};
10067 let Inst{11} = idx{0};
10068 let Inst{10} = size;
10070 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10071 dag oops, dag iops>
10072 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10073 "$Rn = $wback", oops, iops, []> {
10074 // idx encoded in Q:S:size<1> fields.
10077 let Inst{30} = idx{2};
10079 let Inst{20-16} = Xm;
10080 let Inst{12} = idx{1};
10081 let Inst{11} = idx{0};
10082 let Inst{10} = size;
10084 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10085 dag oops, dag iops, list<dag> pattern>
10086 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10088 // idx encoded in Q:S fields.
10090 let Inst{30} = idx{1};
10092 let Inst{20-16} = 0b00000;
10093 let Inst{12} = idx{0};
10094 let Inst{11-10} = size;
10096 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10097 dag oops, dag iops, list<dag> pattern>
10098 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10099 oops, iops, pattern> {
10100 // idx encoded in Q:S fields.
10102 let Inst{30} = idx{1};
10104 let Inst{20-16} = 0b00000;
10105 let Inst{12} = idx{0};
10106 let Inst{11-10} = size;
10108 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
10109 string asm, dag oops, dag iops>
10110 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10111 "$Rn = $wback", oops, iops, []> {
10112 // idx encoded in Q:S fields.
10115 let Inst{30} = idx{1};
10117 let Inst{20-16} = Xm;
10118 let Inst{12} = idx{0};
10119 let Inst{11-10} = size;
10121 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
10122 string asm, dag oops, dag iops>
10123 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10124 "$Rn = $wback", oops, iops, []> {
10125 // idx encoded in Q:S fields.
10128 let Inst{30} = idx{1};
10130 let Inst{20-16} = Xm;
10131 let Inst{12} = idx{0};
10132 let Inst{11-10} = size;
10134 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10135 dag oops, dag iops, list<dag> pattern>
10136 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10138 // idx encoded in Q field.
10140 let Inst{30} = idx;
10142 let Inst{20-16} = 0b00000;
10144 let Inst{11-10} = size;
10146 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10147 dag oops, dag iops, list<dag> pattern>
10148 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10149 oops, iops, pattern> {
10150 // idx encoded in Q field.
10152 let Inst{30} = idx;
10154 let Inst{20-16} = 0b00000;
10156 let Inst{11-10} = size;
10158 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
10159 string asm, dag oops, dag iops>
10160 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10161 "$Rn = $wback", oops, iops, []> {
10162 // idx encoded in Q field.
10165 let Inst{30} = idx;
10167 let Inst{20-16} = Xm;
10169 let Inst{11-10} = size;
10171 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
10172 string asm, dag oops, dag iops>
10173 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10174 "$Rn = $wback", oops, iops, []> {
10175 // idx encoded in Q field.
10178 let Inst{30} = idx;
10180 let Inst{20-16} = Xm;
10182 let Inst{11-10} = size;
10185 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10186 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
10187 RegisterOperand listtype,
10188 RegisterOperand GPR64pi> {
10189 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
10190 (outs listtype:$dst),
10191 (ins listtype:$Vt, VectorIndexB:$idx,
10194 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
10195 (outs GPR64sp:$wback, listtype:$dst),
10196 (ins listtype:$Vt, VectorIndexB:$idx,
10197 GPR64sp:$Rn, GPR64pi:$Xm)>;
10199 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10200 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
10201 RegisterOperand listtype,
10202 RegisterOperand GPR64pi> {
10203 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
10204 (outs listtype:$dst),
10205 (ins listtype:$Vt, VectorIndexH:$idx,
10208 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
10209 (outs GPR64sp:$wback, listtype:$dst),
10210 (ins listtype:$Vt, VectorIndexH:$idx,
10211 GPR64sp:$Rn, GPR64pi:$Xm)>;
10213 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10214 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
10215 RegisterOperand listtype,
10216 RegisterOperand GPR64pi> {
10217 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
10218 (outs listtype:$dst),
10219 (ins listtype:$Vt, VectorIndexS:$idx,
10222 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
10223 (outs GPR64sp:$wback, listtype:$dst),
10224 (ins listtype:$Vt, VectorIndexS:$idx,
10225 GPR64sp:$Rn, GPR64pi:$Xm)>;
10227 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10228 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
10229 RegisterOperand listtype, RegisterOperand GPR64pi> {
10230 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
10231 (outs listtype:$dst),
10232 (ins listtype:$Vt, VectorIndexD:$idx,
10235 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
10236 (outs GPR64sp:$wback, listtype:$dst),
10237 (ins listtype:$Vt, VectorIndexD:$idx,
10238 GPR64sp:$Rn, GPR64pi:$Xm)>;
10240 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10241 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
10242 RegisterOperand listtype, RegisterOperand GPR64pi> {
10243 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
10244 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
10247 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
10248 (outs GPR64sp:$wback),
10249 (ins listtype:$Vt, VectorIndexB:$idx,
10250 GPR64sp:$Rn, GPR64pi:$Xm)>;
10252 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10253 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
10254 RegisterOperand listtype, RegisterOperand GPR64pi> {
10255 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
10256 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
10259 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
10260 (outs GPR64sp:$wback),
10261 (ins listtype:$Vt, VectorIndexH:$idx,
10262 GPR64sp:$Rn, GPR64pi:$Xm)>;
10264 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10265 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
10266 RegisterOperand listtype, RegisterOperand GPR64pi> {
10267 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
10268 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
10271 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
10272 (outs GPR64sp:$wback),
10273 (ins listtype:$Vt, VectorIndexS:$idx,
10274 GPR64sp:$Rn, GPR64pi:$Xm)>;
10276 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10277 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
10278 RegisterOperand listtype, RegisterOperand GPR64pi> {
10279 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
10280 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
10283 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
10284 (outs GPR64sp:$wback),
10285 (ins listtype:$Vt, VectorIndexD:$idx,
10286 GPR64sp:$Rn, GPR64pi:$Xm)>;
10289 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
10290 string Count, int Offset, Operand idxtype> {
10291 // E.g. "ld1 { v0.8b }[0], [x1], #1"
10292 // "ld1\t$Vt, [$Rn], #1"
10293 // may get mapped to
10294 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
10295 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
10296 (!cast<Instruction>(NAME # Type # "_POST")
10298 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
10299 idxtype:$idx, XZR), 1>;
10301 // E.g. "ld1.8b { v0 }[0], [x1], #1"
10302 // "ld1.8b\t$Vt, [$Rn], #1"
10303 // may get mapped to
10304 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
10305 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
10306 (!cast<Instruction>(NAME # Type # "_POST")
10308 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10309 idxtype:$idx, XZR), 0>;
10311 // E.g. "ld1.8b { v0 }[0], [x1]"
10312 // "ld1.8b\t$Vt, [$Rn]"
10313 // may get mapped to
10314 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
10315 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
10316 (!cast<Instruction>(NAME # Type)
10317 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10318 idxtype:$idx, GPR64sp:$Rn), 0>;
10320 // E.g. "ld1.8b { v0 }[0], [x1], x2"
10321 // "ld1.8b\t$Vt, [$Rn], $Xm"
10322 // may get mapped to
10323 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
10324 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
10325 (!cast<Instruction>(NAME # Type # "_POST")
10327 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10329 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
10332 multiclass SIMDLdSt1SingleAliases<string asm> {
10333 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
10334 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
10335 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
10336 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
10339 multiclass SIMDLdSt2SingleAliases<string asm> {
10340 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
10341 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
10342 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
10343 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
10346 multiclass SIMDLdSt3SingleAliases<string asm> {
10347 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
10348 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
10349 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
10350 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
10353 multiclass SIMDLdSt4SingleAliases<string asm> {
10354 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
10355 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
10356 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
10357 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
10359 } // end of 'let Predicates = [HasNEON]'
10361 //----------------------------------------------------------------------------
10362 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
10363 //----------------------------------------------------------------------------
10365 let Predicates = [HasNEON, HasRDM] in {
10367 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
10368 RegisterOperand regtype, string asm,
10369 string kind, list<dag> pattern>
10370 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
10373 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
10374 SDPatternOperator Accum> {
10375 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
10376 [(set (v4i16 V64:$dst),
10377 (Accum (v4i16 V64:$Rd),
10378 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
10379 (v4i16 V64:$Rm)))))]>;
10380 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
10381 [(set (v8i16 V128:$dst),
10382 (Accum (v8i16 V128:$Rd),
10383 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
10384 (v8i16 V128:$Rm)))))]>;
10385 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
10386 [(set (v2i32 V64:$dst),
10387 (Accum (v2i32 V64:$Rd),
10388 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
10389 (v2i32 V64:$Rm)))))]>;
10390 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
10391 [(set (v4i32 V128:$dst),
10392 (Accum (v4i32 V128:$Rd),
10393 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
10394 (v4i32 V128:$Rm)))))]>;
10397 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
10398 SDPatternOperator Accum> {
10399 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
10400 V64, V64, V128_lo, VectorIndexH,
10401 asm, ".4h", ".4h", ".4h", ".h",
10402 [(set (v4i16 V64:$dst),
10403 (Accum (v4i16 V64:$Rd),
10404 (v4i16 (int_aarch64_neon_sqrdmulh
10406 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10407 VectorIndexH:$idx))))))]> {
10409 let Inst{11} = idx{2};
10410 let Inst{21} = idx{1};
10411 let Inst{20} = idx{0};
10414 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
10415 V128, V128, V128_lo, VectorIndexH,
10416 asm, ".8h", ".8h", ".8h", ".h",
10417 [(set (v8i16 V128:$dst),
10418 (Accum (v8i16 V128:$Rd),
10419 (v8i16 (int_aarch64_neon_sqrdmulh
10421 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10422 VectorIndexH:$idx))))))]> {
10424 let Inst{11} = idx{2};
10425 let Inst{21} = idx{1};
10426 let Inst{20} = idx{0};
10429 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
10430 V64, V64, V128, VectorIndexS,
10431 asm, ".2s", ".2s", ".2s", ".s",
10432 [(set (v2i32 V64:$dst),
10433 (Accum (v2i32 V64:$Rd),
10434 (v2i32 (int_aarch64_neon_sqrdmulh
10436 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
10437 VectorIndexS:$idx))))))]> {
10439 let Inst{11} = idx{1};
10440 let Inst{21} = idx{0};
10443 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10444 // an intermediate EXTRACT_SUBREG would be untyped.
10445 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
10446 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
10447 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10448 (i32 (vector_extract
10449 (v4i32 (insert_subvector
10451 (v2i32 (int_aarch64_neon_sqrdmulh
10453 (v2i32 (AArch64duplane32
10455 VectorIndexS:$idx)))),
10459 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
10460 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
10465 VectorIndexS:$idx)),
10468 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
10469 V128, V128, V128, VectorIndexS,
10470 asm, ".4s", ".4s", ".4s", ".s",
10471 [(set (v4i32 V128:$dst),
10472 (Accum (v4i32 V128:$Rd),
10473 (v4i32 (int_aarch64_neon_sqrdmulh
10475 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
10476 VectorIndexS:$idx))))))]> {
10478 let Inst{11} = idx{1};
10479 let Inst{21} = idx{0};
10482 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10483 // an intermediate EXTRACT_SUBREG would be untyped.
10484 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10485 (i32 (vector_extract
10486 (v4i32 (int_aarch64_neon_sqrdmulh
10488 (v4i32 (AArch64duplane32
10490 VectorIndexS:$idx)))),
10493 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
10494 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
10499 VectorIndexS:$idx)),
10502 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
10503 FPR16Op, FPR16Op, V128_lo,
10504 VectorIndexH, asm, ".h", "", "", ".h",
10507 let Inst{11} = idx{2};
10508 let Inst{21} = idx{1};
10509 let Inst{20} = idx{0};
10512 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
10513 FPR32Op, FPR32Op, V128, VectorIndexS,
10514 asm, ".s", "", "", ".s",
10515 [(set (i32 FPR32Op:$dst),
10516 (Accum (i32 FPR32Op:$Rd),
10517 (i32 (int_aarch64_neon_sqrdmulh
10519 (i32 (vector_extract (v4i32 V128:$Rm),
10520 VectorIndexS:$idx))))))]> {
10522 let Inst{11} = idx{1};
10523 let Inst{21} = idx{0};
10526 } // let Predicates = [HasNeon, HasRDM]
10528 //----------------------------------------------------------------------------
10529 // ARMv8.3 Complex ADD/MLA instructions
10530 //----------------------------------------------------------------------------
10532 class ComplexRotationOperand<int Angle, int Remainder, string Type>
10533 : AsmOperandClass {
10534 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
10535 let DiagnosticType = "InvalidComplexRotation" # Type;
10536 let Name = "ComplexRotation" # Type;
10538 def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],
10539 SDNodeXForm<imm, [{
10540 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32);
10542 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
10543 let PrintMethod = "printComplexRotationOp<90, 0>";
10545 def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],
10546 SDNodeXForm<imm, [{
10547 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32);
10549 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
10550 let PrintMethod = "printComplexRotationOp<180, 90>";
10552 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10553 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
10554 RegisterOperand regtype, Operand rottype,
10555 string asm, string kind, list<dag> pattern>
10556 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10557 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10558 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
10567 let Inst{28-24} = 0b01110;
10568 let Inst{23-22} = size;
10570 let Inst{20-16} = Rm;
10571 let Inst{15-13} = opcode;
10572 // Non-tied version (FCADD) only has one rotation bit
10573 let Inst{12} = rot;
10576 let Inst{9-5} = Rn;
10577 let Inst{4-0} = Rd;
10580 //8.3 CompNum - Floating-point complex number support
10581 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
10582 string asm, SDPatternOperator OpNode>{
10583 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10584 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
10586 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10589 (rottype i32:$rot)))]>;
10591 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
10593 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10596 (rottype i32:$rot)))]>;
10599 let Predicates = [HasComplxNum, HasNEON] in {
10600 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
10602 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10605 (rottype i32:$rot)))]>;
10607 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
10609 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10612 (rottype i32:$rot)))]>;
10614 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
10616 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10619 (rottype i32:$rot)))]>;
10623 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10624 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
10626 RegisterOperand regtype,
10627 Operand rottype, string asm,
10628 string kind, list<dag> pattern>
10629 : I<(outs regtype:$dst),
10630 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10631 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10632 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
10641 let Inst{28-24} = 0b01110;
10642 let Inst{23-22} = size;
10644 let Inst{20-16} = Rm;
10645 let Inst{15-13} = opcode;
10646 let Inst{12-11} = rot;
10648 let Inst{9-5} = Rn;
10649 let Inst{4-0} = Rd;
10652 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
10653 Operand rottype, string asm,
10654 SDPatternOperator OpNode> {
10655 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10656 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
10657 rottype, asm, ".4h",
10658 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10661 (rottype i32:$rot)))]>;
10663 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
10664 rottype, asm, ".8h",
10665 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10668 (rottype i32:$rot)))]>;
10671 let Predicates = [HasComplxNum, HasNEON] in {
10672 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
10673 rottype, asm, ".2s",
10674 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10677 (rottype i32:$rot)))]>;
10679 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
10680 rottype, asm, ".4s",
10681 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10684 (rottype i32:$rot)))]>;
10686 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
10687 rottype, asm, ".2d",
10688 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10691 (rottype i32:$rot)))]>;
10695 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10696 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
10697 bit opc1, bit opc2, RegisterOperand dst_reg,
10698 RegisterOperand lhs_reg,
10699 RegisterOperand rhs_reg, Operand vec_idx,
10700 Operand rottype, string asm, string apple_kind,
10701 string dst_kind, string lhs_kind,
10702 string rhs_kind, list<dag> pattern>
10703 : I<(outs dst_reg:$dst),
10704 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
10706 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
10707 "$idx, $rot" # "|" # apple_kind #
10708 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
10718 let Inst{28} = Scalar;
10719 let Inst{27-24} = 0b1111;
10720 let Inst{23-22} = size;
10721 // Bit 21 must be set by the derived class.
10722 let Inst{20-16} = Rm;
10723 let Inst{15} = opc1;
10724 let Inst{14-13} = rot;
10725 let Inst{12} = opc2;
10726 // Bit 11 must be set by the derived class.
10728 let Inst{9-5} = Rn;
10729 let Inst{4-0} = Rd;
10732 // The complex instructions index by pairs of elements, so the VectorIndexes
10733 // don't match the lane types, and the index bits are different to the other
10735 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
10736 string asm, SDPatternOperator OpNode> {
10737 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10738 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
10739 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
10743 let Inst{21} = idx{0};
10746 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
10747 V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
10748 ".8h", ".8h", ".h", []> {
10750 let Inst{11} = idx{1};
10751 let Inst{21} = idx{0};
10753 } // Predicates = HasComplxNum, HasNEON, HasFullFP16]
10755 let Predicates = [HasComplxNum, HasNEON] in {
10756 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
10757 V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
10758 ".4s", ".4s", ".s", []> {
10760 let Inst{11} = idx{0};
10763 } // Predicates = [HasComplxNum, HasNEON]
10766 //----------------------------------------------------------------------------
10767 // Crypto extensions
10768 //----------------------------------------------------------------------------
10770 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10771 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
10773 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
10777 let Inst{31-16} = 0b0100111000101000;
10778 let Inst{15-12} = opc;
10779 let Inst{11-10} = 0b10;
10780 let Inst{9-5} = Rn;
10781 let Inst{4-0} = Rd;
10784 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
10785 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
10786 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
10788 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
10789 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
10791 [(set (v16i8 V128:$dst),
10792 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
10794 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10795 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
10796 dag oops, dag iops, list<dag> pat>
10797 : I<oops, iops, asm,
10798 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
10799 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
10804 let Inst{31-21} = 0b01011110000;
10805 let Inst{20-16} = Rm;
10807 let Inst{14-12} = opc;
10808 let Inst{11-10} = 0b00;
10809 let Inst{9-5} = Rn;
10810 let Inst{4-0} = Rd;
10813 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
10814 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10815 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
10816 [(set (v4i32 FPR128:$dst),
10817 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
10818 (v4i32 V128:$Rm)))]>;
10820 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
10821 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
10822 (ins V128:$Rd, V128:$Rn, V128:$Rm),
10823 [(set (v4i32 V128:$dst),
10824 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
10825 (v4i32 V128:$Rm)))]>;
10827 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
10828 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10829 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
10830 [(set (v4i32 FPR128:$dst),
10831 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
10832 (v4i32 V128:$Rm)))]>;
10834 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10835 class SHA2OpInst<bits<4> opc, string asm, string kind,
10836 string cstr, dag oops, dag iops,
10838 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
10839 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
10843 let Inst{31-16} = 0b0101111000101000;
10844 let Inst{15-12} = opc;
10845 let Inst{11-10} = 0b10;
10846 let Inst{9-5} = Rn;
10847 let Inst{4-0} = Rd;
10850 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
10851 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
10852 (ins V128:$Rd, V128:$Rn),
10853 [(set (v4i32 V128:$dst),
10854 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
10856 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
10857 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
10858 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
10860 // Armv8.2-A Crypto extensions
10861 class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
10863 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> {
10866 let Inst{31-25} = 0b1100111;
10867 let Inst{9-5} = Vn;
10868 let Inst{4-0} = Vd;
10871 class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
10872 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops,
10874 let Inst{31-25} = 0b1100111;
10875 let Inst{24-21} = 0b0110;
10876 let Inst{20-15} = 0b000001;
10877 let Inst{14} = op0;
10878 let Inst{13-12} = 0b00;
10879 let Inst{11-10} = op1;
10881 class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
10882 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">;
10883 class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
10884 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">;
10886 class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
10887 string asmops, string cst>
10888 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
10890 let Inst{24-21} = 0b0011;
10891 let Inst{20-16} = Vm;
10892 let Inst{15} = 0b1;
10893 let Inst{14} = op0;
10894 let Inst{13-12} = 0b00;
10895 let Inst{11-10} = op1;
10897 class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
10898 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10899 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">;
10900 class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
10901 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10902 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10903 class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
10904 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10905 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">;
10906 class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
10907 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10908 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10909 class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
10910 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
10911 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10913 class CryptoRRRR<bits<2>op0, string asm, string asmops>
10914 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
10918 let Inst{24-23} = 0b00;
10919 let Inst{22-21} = op0;
10920 let Inst{20-16} = Vm;
10921 let Inst{15} = 0b0;
10922 let Inst{14-10} = Va;
10924 class CryptoRRRR_16B<bits<2>op0, string asm>
10925 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" #
10926 "|.16b\t$Vd, $Vn, $Vm, $Va}"> {
10928 class CryptoRRRR_4S<bits<2>op0, string asm>
10929 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" #
10930 "|.4s\t$Vd, $Vn, $Vm, $Va}"> {
10933 class CryptoRRRi6<string asm>
10934 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
10935 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" #
10936 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> {
10939 let Inst{24-21} = 0b0100;
10940 let Inst{20-16} = Vm;
10941 let Inst{15-10} = imm;
10942 let Inst{9-5} = Vn;
10943 let Inst{4-0} = Vd;
10946 class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
10947 : BaseCryptoV82<(outs V128:$Vdst),
10948 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
10949 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" #
10950 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> {
10953 let Inst{24-21} = 0b0010;
10954 let Inst{20-16} = Vm;
10955 let Inst{15} = 0b1;
10956 let Inst{14} = op0;
10957 let Inst{13-12} = imm;
10958 let Inst{11-10} = op1;
10961 //----------------------------------------------------------------------------
10962 // v8.1 atomic instructions extension:
10966 // * LDOPregister<OP>, and aliases STOPregister<OP>
10968 // Instruction encodings:
10970 // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
10971 // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
10972 // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
10973 // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
10974 // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
10975 // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
10977 // Instruction syntax:
10979 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10980 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
10981 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
10982 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
10983 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10984 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
10985 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10986 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
10987 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
10988 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
10990 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10991 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
10992 string cstr, list<dag> pattern>
10993 : I<oops, iops, asm, operands, cstr, pattern> {
11001 let Inst{31-30} = Sz;
11002 let Inst{29-24} = 0b001000;
11004 let Inst{22} = Acq;
11005 let Inst{21} = 0b1;
11006 let Inst{20-16} = Rs;
11007 let Inst{15} = Rel;
11008 let Inst{14-10} = 0b11111;
11009 let Inst{9-5} = Rn;
11010 let Inst{4-0} = Rt;
11011 let Predicates = [HasLSE];
11014 class BaseCAS<string order, string size, RegisterClass RC>
11015 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11016 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
11018 Sched<[WriteAtomic]> {
11022 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
11023 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
11024 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
11025 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
11026 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
11029 class BaseCASP<string order, string size, RegisterOperand RC>
11030 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11031 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
11033 Sched<[WriteAtomic]> {
11037 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
11038 let Sz = 0b00, Acq = Acq, Rel = Rel in
11039 def W : BaseCASP<order, "", WSeqPairClassOperand>;
11040 let Sz = 0b01, Acq = Acq, Rel = Rel in
11041 def X : BaseCASP<order, "", XSeqPairClassOperand>;
11044 let Predicates = [HasLSE] in
11045 class BaseSWP<string order, string size, RegisterClass RC>
11046 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
11047 "\t$Rs, $Rt, [$Rn]","",[]>,
11048 Sched<[WriteAtomic]> {
11053 bits<3> opc = 0b000;
11056 let Inst{31-30} = Sz;
11057 let Inst{29-24} = 0b111000;
11058 let Inst{23} = Acq;
11059 let Inst{22} = Rel;
11060 let Inst{21} = 0b1;
11061 let Inst{20-16} = Rs;
11062 let Inst{15} = 0b1;
11063 let Inst{14-12} = opc;
11064 let Inst{11-10} = 0b00;
11065 let Inst{9-5} = Rn;
11066 let Inst{4-0} = Rt;
11067 let Predicates = [HasLSE];
11070 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
11071 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
11072 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
11073 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
11074 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
11077 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
11078 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
11079 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
11080 "\t$Rs, $Rt, [$Rn]","",[]>,
11081 Sched<[WriteAtomic]> {
11089 let Inst{31-30} = Sz;
11090 let Inst{29-24} = 0b111000;
11091 let Inst{23} = Acq;
11092 let Inst{22} = Rel;
11093 let Inst{21} = 0b1;
11094 let Inst{20-16} = Rs;
11095 let Inst{15} = 0b0;
11096 let Inst{14-12} = opc;
11097 let Inst{11-10} = 0b00;
11098 let Inst{9-5} = Rn;
11099 let Inst{4-0} = Rt;
11100 let Predicates = [HasLSE];
11103 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
11105 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
11106 def B : BaseLDOPregister<op, order, "b", GPR32>;
11107 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
11108 def H : BaseLDOPregister<op, order, "h", GPR32>;
11109 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
11110 def W : BaseLDOPregister<op, order, "", GPR32>;
11111 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
11112 def X : BaseLDOPregister<op, order, "", GPR64>;
11115 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
11116 // complex DAG for DstRHS.
11117 let Predicates = [HasLSE] in
11118 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
11119 string size, dag SrcRHS, dag DstRHS> {
11120 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
11121 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
11122 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
11123 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
11124 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
11125 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
11126 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
11127 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11128 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
11129 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11132 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
11133 string size, dag RHS> {
11134 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
11137 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
11138 string size, dag LHS, dag RHS> {
11139 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
11142 multiclass LDOPregister_patterns<string inst, string op> {
11143 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
11144 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
11145 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
11146 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>;
11149 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
11150 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
11152 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
11153 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
11155 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11156 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
11158 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11159 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
11161 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11164 let Predicates = [HasLSE] in
11165 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
11166 string size, dag OLD, dag NEW> {
11167 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
11168 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
11169 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
11170 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11171 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
11172 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11173 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
11174 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11175 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
11176 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11179 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
11180 string size, dag OLD, dag NEW> {
11181 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
11184 multiclass CASregister_patterns<string inst, string op> {
11185 defm : CASregister_patterns_ord<inst, "X", op, "64",
11186 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
11187 defm : CASregister_patterns_ord<inst, "W", op, "32",
11188 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11189 defm : CASregister_patterns_ord<inst, "H", op, "16",
11190 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11191 defm : CASregister_patterns_ord<inst, "B", op, "8",
11192 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11195 let Predicates = [HasLSE] in
11196 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
11197 Instruction inst> :
11198 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
11200 multiclass STOPregister<string asm, string instr> {
11201 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
11202 !cast<Instruction>(instr # "LB")>;
11203 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
11204 !cast<Instruction>(instr # "LH")>;
11205 def : BaseSTOPregister<asm # "l", GPR32, WZR,
11206 !cast<Instruction>(instr # "LW")>;
11207 def : BaseSTOPregister<asm # "l", GPR64, XZR,
11208 !cast<Instruction>(instr # "LX")>;
11209 def : BaseSTOPregister<asm # "b", GPR32, WZR,
11210 !cast<Instruction>(instr # "B")>;
11211 def : BaseSTOPregister<asm # "h", GPR32, WZR,
11212 !cast<Instruction>(instr # "H")>;
11213 def : BaseSTOPregister<asm, GPR32, WZR,
11214 !cast<Instruction>(instr # "W")>;
11215 def : BaseSTOPregister<asm, GPR64, XZR,
11216 !cast<Instruction>(instr # "X")>;
11219 //----------------------------------------------------------------------------
11220 // Allow the size specifier tokens to be upper case, not just lower.
11221 def : TokenAlias<".4B", ".4b">; // Add dot product
11222 def : TokenAlias<".8B", ".8b">;
11223 def : TokenAlias<".4H", ".4h">;
11224 def : TokenAlias<".2S", ".2s">;
11225 def : TokenAlias<".1D", ".1d">;
11226 def : TokenAlias<".16B", ".16b">;
11227 def : TokenAlias<".8H", ".8h">;
11228 def : TokenAlias<".4S", ".4s">;
11229 def : TokenAlias<".2D", ".2d">;
11230 def : TokenAlias<".1Q", ".1q">;
11231 def : TokenAlias<".2H", ".2h">;
11232 def : TokenAlias<".B", ".b">;
11233 def : TokenAlias<".H", ".h">;
11234 def : TokenAlias<".S", ".s">;
11235 def : TokenAlias<".D", ".d">;
11236 def : TokenAlias<".Q", ".q">;