1 //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
10 // Describe AArch64 instructions format here
13 // Format specifies the encoding used by the instruction. This is part of the
14 // ad-hoc solution used to emit machine instruction encodings by our machine
16 class Format<bits<2> val> {
20 def PseudoFrm : Format<0>;
21 def NormalFrm : Format<1>; // Do we need any others?
23 // Enum describing whether an instruction is
24 // destructive in its first source operand.
25 class DestructiveInstTypeEnum<bits<4> val> {
28 def NotDestructive : DestructiveInstTypeEnum<0>;
29 // Destructive in its first operand and can be MOVPRFX'd, but has no other
30 // special properties.
31 def DestructiveOther : DestructiveInstTypeEnum<1>;
32 def DestructiveUnary : DestructiveInstTypeEnum<2>;
33 def DestructiveBinaryImm : DestructiveInstTypeEnum<3>;
34 def DestructiveBinaryShImmUnpred : DestructiveInstTypeEnum<4>;
35 def DestructiveBinary : DestructiveInstTypeEnum<5>;
36 def DestructiveBinaryComm : DestructiveInstTypeEnum<6>;
37 def DestructiveBinaryCommWithRev : DestructiveInstTypeEnum<7>;
38 def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>;
39 def DestructiveUnaryPassthru : DestructiveInstTypeEnum<9>;
41 class FalseLanesEnum<bits<2> val> {
44 def FalseLanesNone : FalseLanesEnum<0>;
45 def FalseLanesZero : FalseLanesEnum<1>;
46 def FalseLanesUndef : FalseLanesEnum<2>;
48 // AArch64 Instruction Format
49 class AArch64Inst<Format f, string cstr> : Instruction {
50 field bits<32> Inst; // Instruction encoding.
51 // Mask of bits that cause an encoding to be UNPREDICTABLE.
52 // If a bit is set, then if the corresponding bit in the
53 // target encoding differs from its value in the "Inst" field,
54 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
55 field bits<32> Unpredictable = 0;
56 // SoftFail is the generic name for this field, but we alias it so
57 // as to make it more obvious what it means in ARM-land.
58 field bits<32> SoftFail = Unpredictable;
59 let Namespace = "AArch64";
61 bits<2> Form = F.Value;
66 FalseLanesEnum FalseLanes = FalseLanesNone;
67 DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
68 ElementSizeEnum ElementSize = ElementSizeNone;
70 let TSFlags{10} = isPTestLike;
71 let TSFlags{9} = isWhile;
72 let TSFlags{8-7} = FalseLanes.Value;
73 let TSFlags{6-3} = DestructiveInstType.Value;
74 let TSFlags{2-0} = ElementSize.Value;
77 let Constraints = cstr;
80 class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
81 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
83 // Pseudo instructions (don't have encoding information)
84 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
85 : AArch64Inst<PseudoFrm, cstr> {
86 dag OutOperandList = oops;
87 dag InOperandList = iops;
88 let Pattern = pattern;
89 let isCodeGenOnly = 1;
93 // Real instructions (have encoding information)
94 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
95 let Pattern = pattern;
99 // Normal instructions
100 class I<dag oops, dag iops, string asm, string operands, string cstr,
102 : EncodedI<cstr, pattern> {
103 dag OutOperandList = oops;
104 dag InOperandList = iops;
105 let AsmString = !strconcat(asm, operands);
108 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
109 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
110 class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;
112 // Helper fragment for an extract of the high portion of a 128-bit vector.
113 def extract_high_v16i8 :
114 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
115 def extract_high_v8i16 :
116 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
117 def extract_high_v4i32 :
118 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
119 def extract_high_v2i64 :
120 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
122 //===----------------------------------------------------------------------===//
123 // Asm Operand Classes.
126 // Shifter operand for arithmetic shifted encodings.
127 def ShifterOperand : AsmOperandClass {
128 let Name = "Shifter";
131 // Shifter operand for mov immediate encodings.
132 def MovImm32ShifterOperand : AsmOperandClass {
133 let SuperClasses = [ShifterOperand];
134 let Name = "MovImm32Shifter";
135 let RenderMethod = "addShifterOperands";
136 let DiagnosticType = "InvalidMovImm32Shift";
138 def MovImm64ShifterOperand : AsmOperandClass {
139 let SuperClasses = [ShifterOperand];
140 let Name = "MovImm64Shifter";
141 let RenderMethod = "addShifterOperands";
142 let DiagnosticType = "InvalidMovImm64Shift";
145 // Shifter operand for arithmetic register shifted encodings.
146 class ArithmeticShifterOperand<int width> : AsmOperandClass {
147 let SuperClasses = [ShifterOperand];
148 let Name = "ArithmeticShifter" # width;
149 let PredicateMethod = "isArithmeticShifter<" # width # ">";
150 let RenderMethod = "addShifterOperands";
151 let DiagnosticType = "AddSubRegShift" # width;
154 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
155 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
157 // Shifter operand for logical register shifted encodings.
158 class LogicalShifterOperand<int width> : AsmOperandClass {
159 let SuperClasses = [ShifterOperand];
160 let Name = "LogicalShifter" # width;
161 let PredicateMethod = "isLogicalShifter<" # width # ">";
162 let RenderMethod = "addShifterOperands";
163 let DiagnosticType = "AddSubRegShift" # width;
166 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
167 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
169 // Shifter operand for logical vector 128/64-bit shifted encodings.
170 def LogicalVecShifterOperand : AsmOperandClass {
171 let SuperClasses = [ShifterOperand];
172 let Name = "LogicalVecShifter";
173 let RenderMethod = "addShifterOperands";
175 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
176 let SuperClasses = [LogicalVecShifterOperand];
177 let Name = "LogicalVecHalfWordShifter";
178 let RenderMethod = "addShifterOperands";
181 // The "MSL" shifter on the vector MOVI instruction.
182 def MoveVecShifterOperand : AsmOperandClass {
183 let SuperClasses = [ShifterOperand];
184 let Name = "MoveVecShifter";
185 let RenderMethod = "addShifterOperands";
188 // Extend operand for arithmetic encodings.
189 def ExtendOperand : AsmOperandClass {
191 let DiagnosticType = "AddSubRegExtendLarge";
193 def ExtendOperand64 : AsmOperandClass {
194 let SuperClasses = [ExtendOperand];
195 let Name = "Extend64";
196 let DiagnosticType = "AddSubRegExtendSmall";
198 // 'extend' that's a lsl of a 64-bit register.
199 def ExtendOperandLSL64 : AsmOperandClass {
200 let SuperClasses = [ExtendOperand];
201 let Name = "ExtendLSL64";
202 let RenderMethod = "addExtend64Operands";
203 let DiagnosticType = "AddSubRegExtendLarge";
206 // 8-bit floating-point immediate encodings.
207 def FPImmOperand : AsmOperandClass {
209 let ParserMethod = "tryParseFPImm<true>";
210 let DiagnosticType = "InvalidFPImm";
213 def CondCode : AsmOperandClass {
214 let Name = "CondCode";
215 let DiagnosticType = "InvalidCondCode";
218 // A 32-bit register pasrsed as 64-bit
219 def GPR32as64Operand : AsmOperandClass {
220 let Name = "GPR32as64";
222 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";
224 def GPR32as64 : RegisterOperand<GPR32> {
225 let ParserMatchClass = GPR32as64Operand;
228 // A 64-bit register pasrsed as 32-bit
229 def GPR64as32Operand : AsmOperandClass {
230 let Name = "GPR64as32";
232 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";
234 def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {
235 let ParserMatchClass = GPR64as32Operand;
238 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
239 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
240 // are encoded as the eight bit value 'abcdefgh'.
241 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
243 class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
244 let Name = "UImm" # Width # "s" # Scale;
245 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;
246 let RenderMethod = "addImmScaledOperands<" # Scale # ">";
247 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";
250 class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
251 let Name = "SImm" # Width # "s" # Scale;
252 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;
253 let RenderMethod = "addImmScaledOperands<" # Scale # ">";
254 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";
257 //===----------------------------------------------------------------------===//
258 // Operand Definitions.
261 // ADR[P] instruction labels.
262 def AdrpOperand : AsmOperandClass {
263 let Name = "AdrpLabel";
264 let ParserMethod = "tryParseAdrpLabel";
265 let DiagnosticType = "InvalidLabel";
267 def adrplabel : Operand<i64> {
268 let EncoderMethod = "getAdrLabelOpValue";
269 let PrintMethod = "printAdrpLabel";
270 let ParserMatchClass = AdrpOperand;
271 let OperandType = "OPERAND_PCREL";
274 def AdrOperand : AsmOperandClass {
275 let Name = "AdrLabel";
276 let ParserMethod = "tryParseAdrLabel";
277 let DiagnosticType = "InvalidLabel";
279 def adrlabel : Operand<i64> {
280 let EncoderMethod = "getAdrLabelOpValue";
281 let ParserMatchClass = AdrOperand;
284 class SImmOperand<int width> : AsmOperandClass {
285 let Name = "SImm" # width;
286 let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
287 let RenderMethod = "addImmOperands";
288 let PredicateMethod = "isSImm<" # width # ">";
292 class AsmImmRange<int Low, int High> : AsmOperandClass {
293 let Name = "Imm" # Low # "_" # High;
294 let DiagnosticType = "InvalidImm" # Low # "_" # High;
295 let RenderMethod = "addImmOperands";
296 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
299 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
300 def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;
301 def simm10Scaled : Operand<i64> {
302 let ParserMatchClass = SImm10s8Operand;
303 let DecoderMethod = "DecodeSImm<10>";
304 let PrintMethod = "printImmScale<8>";
307 def simm9s16 : Operand<i64> {
308 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;
309 let DecoderMethod = "DecodeSImm<9>";
310 let PrintMethod = "printImmScale<16>";
313 // uimm6 predicate - True if the immediate is in the range [0, 63].
314 def UImm6Operand : AsmOperandClass {
316 let DiagnosticType = "InvalidImm0_63";
319 def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
320 let ParserMatchClass = UImm6Operand;
323 def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
324 let ParserMatchClass = AsmImmRange<0, 65535>;
327 def SImm9Operand : SImmOperand<9>;
328 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
329 let ParserMatchClass = SImm9Operand;
330 let DecoderMethod = "DecodeSImm<9>";
333 def SImm8Operand : SImmOperand<8>;
334 def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> {
335 let ParserMatchClass = SImm8Operand;
336 let DecoderMethod = "DecodeSImm<8>";
339 def SImm6Operand : SImmOperand<6>;
340 def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
341 let ParserMatchClass = SImm6Operand;
342 let DecoderMethod = "DecodeSImm<6>";
345 def SImm5Operand : SImmOperand<5>;
346 def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
347 let ParserMatchClass = SImm5Operand;
348 let DecoderMethod = "DecodeSImm<5>";
351 def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
352 let ParserMatchClass = SImm5Operand;
353 let DecoderMethod = "DecodeSImm<5>";
356 def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {
357 let ParserMatchClass = SImm5Operand;
358 let DecoderMethod = "DecodeSImm<5>";
359 let PrintMethod = "printSImm<8>";
362 def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {
363 let ParserMatchClass = SImm5Operand;
364 let DecoderMethod = "DecodeSImm<5>";
365 let PrintMethod = "printSImm<16>";
368 // simm7sN predicate - True if the immediate is a multiple of N in the range
369 // [-64 * N, 63 * N].
371 def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;
372 def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;
373 def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
375 def simm7s4 : Operand<i32> {
376 let ParserMatchClass = SImm7s4Operand;
377 let PrintMethod = "printImmScale<4>";
380 def simm7s8 : Operand<i32> {
381 let ParserMatchClass = SImm7s8Operand;
382 let PrintMethod = "printImmScale<8>";
385 def simm7s16 : Operand<i32> {
386 let ParserMatchClass = SImm7s16Operand;
387 let PrintMethod = "printImmScale<16>";
390 def am_sve_fi : ComplexPattern<i64, 2, "SelectAddrModeFrameIndexSVE", []>;
392 def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
393 def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
394 def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
395 def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
396 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
398 def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>;
399 def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>;
401 def UImmS1XForm : SDNodeXForm<imm, [{
402 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64);
404 def UImmS2XForm : SDNodeXForm<imm, [{
405 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);
407 def UImmS4XForm : SDNodeXForm<imm, [{
408 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);
410 def UImmS8XForm : SDNodeXForm<imm, [{
411 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
414 // uimm5sN predicate - True if the immediate is a multiple of N in the range
416 def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
417 def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;
418 def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;
420 def uimm5s2 : Operand<i64>, ImmLeaf<i64,
421 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
423 let ParserMatchClass = UImm5s2Operand;
424 let PrintMethod = "printImmScale<2>";
426 def uimm5s4 : Operand<i64>, ImmLeaf<i64,
427 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
429 let ParserMatchClass = UImm5s4Operand;
430 let PrintMethod = "printImmScale<4>";
432 def uimm5s8 : Operand<i64>, ImmLeaf<i64,
433 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
435 let ParserMatchClass = UImm5s8Operand;
436 let PrintMethod = "printImmScale<8>";
439 // tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant)
440 // instead of ImmLeaf (Constant)
441 def tuimm5s2 : Operand<i64>, TImmLeaf<i64,
442 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
444 let ParserMatchClass = UImm5s2Operand;
445 let PrintMethod = "printImmScale<2>";
447 def tuimm5s4 : Operand<i64>, TImmLeaf<i64,
448 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
450 let ParserMatchClass = UImm5s4Operand;
451 let PrintMethod = "printImmScale<4>";
453 def tuimm5s8 : Operand<i64>, TImmLeaf<i64,
454 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
456 let ParserMatchClass = UImm5s8Operand;
457 let PrintMethod = "printImmScale<8>";
460 // uimm6sN predicate - True if the immediate is a multiple of N in the range
462 def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;
463 def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;
464 def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;
465 def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;
466 def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;
468 def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
469 let ParserMatchClass = UImm6s1Operand;
471 def uimm6s2 : Operand<i64>, ImmLeaf<i64,
472 [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
473 let PrintMethod = "printImmScale<2>";
474 let ParserMatchClass = UImm6s2Operand;
476 def uimm6s4 : Operand<i64>, ImmLeaf<i64,
477 [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
478 let PrintMethod = "printImmScale<4>";
479 let ParserMatchClass = UImm6s4Operand;
481 def uimm6s8 : Operand<i64>, ImmLeaf<i64,
482 [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
483 let PrintMethod = "printImmScale<8>";
484 let ParserMatchClass = UImm6s8Operand;
486 def uimm6s16 : Operand<i64>, ImmLeaf<i64,
487 [{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {
488 let PrintMethod = "printImmScale<16>";
489 let ParserMatchClass = UImm6s16Operand;
492 def SImmS2XForm : SDNodeXForm<imm, [{
493 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64);
495 def SImmS3XForm : SDNodeXForm<imm, [{
496 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64);
498 def SImmS4XForm : SDNodeXForm<imm, [{
499 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64);
501 def SImmS16XForm : SDNodeXForm<imm, [{
502 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64);
504 def SImmS32XForm : SDNodeXForm<imm, [{
505 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64);
508 // simm6sN predicate - True if the immediate is a multiple of N in the range
509 // [-32 * N, 31 * N].
510 def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
511 def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
512 let ParserMatchClass = SImm6s1Operand;
513 let DecoderMethod = "DecodeSImm<6>";
516 // simm4sN predicate - True if the immediate is a multiple of N in the range
518 def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>;
519 def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>;
520 def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>;
521 def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>;
522 def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
523 def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>;
525 def simm4s1 : Operand<i64>, ImmLeaf<i64,
526 [{ return Imm >=-8 && Imm <= 7; }]> {
527 let ParserMatchClass = SImm4s1Operand;
528 let DecoderMethod = "DecodeSImm<4>";
531 def simm4s2 : Operand<i64>, ImmLeaf<i64,
532 [{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> {
533 let PrintMethod = "printImmScale<2>";
534 let ParserMatchClass = SImm4s2Operand;
535 let DecoderMethod = "DecodeSImm<4>";
538 def simm4s3 : Operand<i64>, ImmLeaf<i64,
539 [{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> {
540 let PrintMethod = "printImmScale<3>";
541 let ParserMatchClass = SImm4s3Operand;
542 let DecoderMethod = "DecodeSImm<4>";
545 def simm4s4 : Operand<i64>, ImmLeaf<i64,
546 [{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> {
547 let PrintMethod = "printImmScale<4>";
548 let ParserMatchClass = SImm4s4Operand;
549 let DecoderMethod = "DecodeSImm<4>";
551 def simm4s16 : Operand<i64>, ImmLeaf<i64,
552 [{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> {
553 let PrintMethod = "printImmScale<16>";
554 let ParserMatchClass = SImm4s16Operand;
555 let DecoderMethod = "DecodeSImm<4>";
557 def simm4s32 : Operand<i64>, ImmLeaf<i64,
558 [{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> {
559 let PrintMethod = "printImmScale<32>";
560 let ParserMatchClass = SImm4s32Operand;
561 let DecoderMethod = "DecodeSImm<4>";
564 def Imm1_8Operand : AsmImmRange<1, 8>;
565 def Imm1_16Operand : AsmImmRange<1, 16>;
566 def Imm1_32Operand : AsmImmRange<1, 32>;
567 def Imm1_64Operand : AsmImmRange<1, 64>;
569 class BranchTarget<int N> : AsmOperandClass {
570 let Name = "BranchTarget" # N;
571 let DiagnosticType = "InvalidLabel";
572 let PredicateMethod = "isBranchTarget<" # N # ">";
575 class PCRelLabel<int N> : BranchTarget<N> {
576 let Name = "PCRelLabel" # N;
579 def BranchTarget14Operand : BranchTarget<14>;
580 def BranchTarget26Operand : BranchTarget<26>;
581 def PCRelLabel19Operand : PCRelLabel<19>;
583 def MovWSymbolG3AsmOperand : AsmOperandClass {
584 let Name = "MovWSymbolG3";
585 let RenderMethod = "addImmOperands";
588 def movw_symbol_g3 : Operand<i32> {
589 let ParserMatchClass = MovWSymbolG3AsmOperand;
592 def MovWSymbolG2AsmOperand : AsmOperandClass {
593 let Name = "MovWSymbolG2";
594 let RenderMethod = "addImmOperands";
597 def movw_symbol_g2 : Operand<i32> {
598 let ParserMatchClass = MovWSymbolG2AsmOperand;
601 def MovWSymbolG1AsmOperand : AsmOperandClass {
602 let Name = "MovWSymbolG1";
603 let RenderMethod = "addImmOperands";
606 def movw_symbol_g1 : Operand<i32> {
607 let ParserMatchClass = MovWSymbolG1AsmOperand;
610 def MovWSymbolG0AsmOperand : AsmOperandClass {
611 let Name = "MovWSymbolG0";
612 let RenderMethod = "addImmOperands";
615 def movw_symbol_g0 : Operand<i32> {
616 let ParserMatchClass = MovWSymbolG0AsmOperand;
619 class fixedpoint_i32<ValueType FloatVT>
621 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
622 let EncoderMethod = "getFixedPointScaleOpValue";
623 let DecoderMethod = "DecodeFixedPointScaleImm32";
624 let ParserMatchClass = Imm1_32Operand;
627 class fixedpoint_i64<ValueType FloatVT>
629 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
630 let EncoderMethod = "getFixedPointScaleOpValue";
631 let DecoderMethod = "DecodeFixedPointScaleImm64";
632 let ParserMatchClass = Imm1_64Operand;
635 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
636 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
637 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
639 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
640 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
641 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
643 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
644 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
646 let EncoderMethod = "getVecShiftR8OpValue";
647 let DecoderMethod = "DecodeVecShiftR8Imm";
648 let ParserMatchClass = Imm1_8Operand;
650 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
651 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
653 let EncoderMethod = "getVecShiftR16OpValue";
654 let DecoderMethod = "DecodeVecShiftR16Imm";
655 let ParserMatchClass = Imm1_16Operand;
657 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
658 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
660 let EncoderMethod = "getVecShiftR16OpValue";
661 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
662 let ParserMatchClass = Imm1_8Operand;
664 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
665 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
667 let EncoderMethod = "getVecShiftR32OpValue";
668 let DecoderMethod = "DecodeVecShiftR32Imm";
669 let ParserMatchClass = Imm1_32Operand;
671 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
672 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
674 let EncoderMethod = "getVecShiftR32OpValue";
675 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
676 let ParserMatchClass = Imm1_16Operand;
678 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
679 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
681 let EncoderMethod = "getVecShiftR64OpValue";
682 let DecoderMethod = "DecodeVecShiftR64Imm";
683 let ParserMatchClass = Imm1_64Operand;
685 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
686 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
688 let EncoderMethod = "getVecShiftR64OpValue";
689 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
690 let ParserMatchClass = Imm1_32Operand;
693 // Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant
695 def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
696 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
698 let EncoderMethod = "getVecShiftR8OpValue";
699 let DecoderMethod = "DecodeVecShiftR8Imm";
700 let ParserMatchClass = Imm1_8Operand;
702 def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
703 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
705 let EncoderMethod = "getVecShiftR16OpValue";
706 let DecoderMethod = "DecodeVecShiftR16Imm";
707 let ParserMatchClass = Imm1_16Operand;
709 def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
710 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
712 let EncoderMethod = "getVecShiftR32OpValue";
713 let DecoderMethod = "DecodeVecShiftR32Imm";
714 let ParserMatchClass = Imm1_32Operand;
716 def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{
717 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
719 let EncoderMethod = "getVecShiftR64OpValue";
720 let DecoderMethod = "DecodeVecShiftR64Imm";
721 let ParserMatchClass = Imm1_64Operand;
724 def Imm0_1Operand : AsmImmRange<0, 1>;
725 def Imm0_3Operand : AsmImmRange<0, 3>;
726 def Imm0_7Operand : AsmImmRange<0, 7>;
727 def Imm0_15Operand : AsmImmRange<0, 15>;
728 def Imm0_31Operand : AsmImmRange<0, 31>;
729 def Imm0_63Operand : AsmImmRange<0, 63>;
731 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
732 return (((uint32_t)Imm) < 8);
734 let EncoderMethod = "getVecShiftL8OpValue";
735 let DecoderMethod = "DecodeVecShiftL8Imm";
736 let ParserMatchClass = Imm0_7Operand;
738 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
739 return (((uint32_t)Imm) < 16);
741 let EncoderMethod = "getVecShiftL16OpValue";
742 let DecoderMethod = "DecodeVecShiftL16Imm";
743 let ParserMatchClass = Imm0_15Operand;
745 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
746 return (((uint32_t)Imm) < 32);
748 let EncoderMethod = "getVecShiftL32OpValue";
749 let DecoderMethod = "DecodeVecShiftL32Imm";
750 let ParserMatchClass = Imm0_31Operand;
752 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
753 return (((uint32_t)Imm) < 64);
755 let EncoderMethod = "getVecShiftL64OpValue";
756 let DecoderMethod = "DecodeVecShiftL64Imm";
757 let ParserMatchClass = Imm0_63Operand;
760 // Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant
762 def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{
763 return (((uint32_t)Imm) < 8);
765 let EncoderMethod = "getVecShiftL8OpValue";
766 let DecoderMethod = "DecodeVecShiftL8Imm";
767 let ParserMatchClass = Imm0_7Operand;
769 def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{
770 return (((uint32_t)Imm) < 16);
772 let EncoderMethod = "getVecShiftL16OpValue";
773 let DecoderMethod = "DecodeVecShiftL16Imm";
774 let ParserMatchClass = Imm0_15Operand;
776 def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{
777 return (((uint32_t)Imm) < 32);
779 let EncoderMethod = "getVecShiftL32OpValue";
780 let DecoderMethod = "DecodeVecShiftL32Imm";
781 let ParserMatchClass = Imm0_31Operand;
783 def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{
784 return (((uint32_t)Imm) < 64);
786 let EncoderMethod = "getVecShiftL64OpValue";
787 let DecoderMethod = "DecodeVecShiftL64Imm";
788 let ParserMatchClass = Imm0_63Operand;
791 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
792 // instructions for splatting repeating bit patterns across the immediate.
793 def logical_imm32_XFORM : SDNodeXForm<imm, [{
794 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
795 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
797 def logical_imm64_XFORM : SDNodeXForm<imm, [{
798 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
799 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
802 def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">,
803 GISDNodeXFormEquiv<logical_imm32_XFORM>;
804 def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">,
805 GISDNodeXFormEquiv<logical_imm64_XFORM>;
807 let DiagnosticType = "LogicalSecondSource" in {
808 def LogicalImm32Operand : AsmOperandClass {
809 let Name = "LogicalImm32";
810 let PredicateMethod = "isLogicalImm<int32_t>";
811 let RenderMethod = "addLogicalImmOperands<int32_t>";
813 def LogicalImm64Operand : AsmOperandClass {
814 let Name = "LogicalImm64";
815 let PredicateMethod = "isLogicalImm<int64_t>";
816 let RenderMethod = "addLogicalImmOperands<int64_t>";
818 def LogicalImm32NotOperand : AsmOperandClass {
819 let Name = "LogicalImm32Not";
820 let PredicateMethod = "isLogicalImm<int32_t>";
821 let RenderMethod = "addLogicalImmNotOperands<int32_t>";
823 def LogicalImm64NotOperand : AsmOperandClass {
824 let Name = "LogicalImm64Not";
825 let PredicateMethod = "isLogicalImm<int64_t>";
826 let RenderMethod = "addLogicalImmNotOperands<int64_t>";
829 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
830 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
831 }], logical_imm32_XFORM> {
832 let PrintMethod = "printLogicalImm<int32_t>";
833 let ParserMatchClass = LogicalImm32Operand;
835 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
836 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
837 }], logical_imm64_XFORM> {
838 let PrintMethod = "printLogicalImm<int64_t>";
839 let ParserMatchClass = LogicalImm64Operand;
841 def logical_imm32_not : Operand<i32> {
842 let ParserMatchClass = LogicalImm32NotOperand;
844 def logical_imm64_not : Operand<i64> {
845 let ParserMatchClass = LogicalImm64NotOperand;
848 // iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535].
849 let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in {
850 def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{
851 return ((uint32_t)Imm) < 65536;
854 def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{
855 return ((uint64_t)Imm) < 65536;
859 // imm0_255 predicate - True if the immediate is in the range [0,255].
860 def Imm0_255Operand : AsmImmRange<0,255>;
862 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
863 return ((uint32_t)Imm) < 256;
865 let ParserMatchClass = Imm0_255Operand;
866 let PrintMethod = "printImm";
869 // imm0_127 predicate - True if the immediate is in the range [0,127]
870 def Imm0_127Operand : AsmImmRange<0, 127>;
871 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
872 return ((uint32_t)Imm) < 128;
874 let ParserMatchClass = Imm0_127Operand;
875 let PrintMethod = "printImm";
878 def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{
879 return ((uint64_t)Imm) < 128;
881 let ParserMatchClass = Imm0_127Operand;
882 let PrintMethod = "printImm";
885 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
886 // for all shift-amounts.
888 // imm0_63 predicate - True if the immediate is in the range [0,63]
889 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
890 return ((uint64_t)Imm) < 64;
892 let ParserMatchClass = Imm0_63Operand;
895 def timm0_63 : Operand<i64>, TImmLeaf<i64, [{
896 return ((uint64_t)Imm) < 64;
898 let ParserMatchClass = Imm0_63Operand;
901 // imm0_31 predicate - True if the immediate is in the range [0,31]
902 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
903 return ((uint64_t)Imm) < 32;
905 let ParserMatchClass = Imm0_31Operand;
908 // timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf)
909 // instead of Constant (ImmLeaf)
910 def timm0_31 : Operand<i64>, TImmLeaf<i64, [{
911 return ((uint64_t)Imm) < 32;
913 let ParserMatchClass = Imm0_31Operand;
916 // True if the 32-bit immediate is in the range [0,31]
917 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
918 return ((uint64_t)Imm) < 32;
920 let ParserMatchClass = Imm0_31Operand;
923 // imm0_1 predicate - True if the immediate is in the range [0,1]
924 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
925 return ((uint64_t)Imm) < 2;
927 let ParserMatchClass = Imm0_1Operand;
930 // timm0_1 - as above, but use TargetConstant (TImmLeaf)
931 def timm0_1 : Operand<i64>, TImmLeaf<i64, [{
932 return ((uint64_t)Imm) < 2;
934 let ParserMatchClass = Imm0_1Operand;
937 // imm0_15 predicate - True if the immediate is in the range [0,15]
938 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
939 return ((uint64_t)Imm) < 16;
941 let ParserMatchClass = Imm0_15Operand;
944 // imm0_7 predicate - True if the immediate is in the range [0,7]
945 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
946 return ((uint64_t)Imm) < 8;
948 let ParserMatchClass = Imm0_7Operand;
951 // imm0_3 predicate - True if the immediate is in the range [0,3]
952 def imm0_3 : Operand<i64>, ImmLeaf<i64, [{
953 return ((uint64_t)Imm) < 4;
955 let ParserMatchClass = Imm0_3Operand;
958 // imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
959 def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{
960 return ((uint32_t)Imm) < 8;
962 let ParserMatchClass = Imm0_7Operand;
965 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
966 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
967 return ((uint32_t)Imm) < 16;
969 let ParserMatchClass = Imm0_15Operand;
972 // An arithmetic shifter operand:
973 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
975 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
976 let PrintMethod = "printShifter";
977 let ParserMatchClass = !cast<AsmOperandClass>(
978 "ArithmeticShifterOperand" # width);
981 def arith_shift32 : arith_shift<i32, 32>;
982 def arith_shift64 : arith_shift<i64, 64>;
984 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
986 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
987 let PrintMethod = "printShiftedRegister";
988 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
991 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
992 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
994 def gi_arith_shifted_reg32 :
995 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">,
996 GIComplexPatternEquiv<arith_shifted_reg32>;
998 def gi_arith_shifted_reg64 :
999 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">,
1000 GIComplexPatternEquiv<arith_shifted_reg64>;
1002 // An arithmetic shifter operand:
1003 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
1005 class logical_shift<int width> : Operand<i32> {
1006 let PrintMethod = "printShifter";
1007 let ParserMatchClass = !cast<AsmOperandClass>(
1008 "LogicalShifterOperand" # width);
1011 def logical_shift32 : logical_shift<32>;
1012 def logical_shift64 : logical_shift<64>;
1014 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
1016 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
1017 let PrintMethod = "printShiftedRegister";
1018 let MIOperandInfo = (ops regclass, shiftop);
1021 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
1022 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
1024 def gi_logical_shifted_reg32 :
1025 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">,
1026 GIComplexPatternEquiv<logical_shifted_reg32>;
1028 def gi_logical_shifted_reg64 :
1029 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">,
1030 GIComplexPatternEquiv<logical_shifted_reg64>;
1032 // A logical vector shifter operand:
1033 // {7-6} - shift type: 00 = lsl
1034 // {5-0} - imm6: #0, #8, #16, or #24
1035 def logical_vec_shift : Operand<i32> {
1036 let PrintMethod = "printShifter";
1037 let EncoderMethod = "getVecShifterOpValue";
1038 let ParserMatchClass = LogicalVecShifterOperand;
1041 // A logical vector half-word shifter operand:
1042 // {7-6} - shift type: 00 = lsl
1043 // {5-0} - imm6: #0 or #8
1044 def logical_vec_hw_shift : Operand<i32> {
1045 let PrintMethod = "printShifter";
1046 let EncoderMethod = "getVecShifterOpValue";
1047 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
1050 // A vector move shifter operand:
1051 // {0} - imm1: #8 or #16
1052 def move_vec_shift : Operand<i32> {
1053 let PrintMethod = "printShifter";
1054 let EncoderMethod = "getMoveVecShifterOpValue";
1055 let ParserMatchClass = MoveVecShifterOperand;
1058 let DiagnosticType = "AddSubSecondSource" in {
1059 def AddSubImmOperand : AsmOperandClass {
1060 let Name = "AddSubImm";
1061 let ParserMethod = "tryParseImmWithOptionalShift";
1062 let RenderMethod = "addImmWithOptionalShiftOperands<12>";
1064 def AddSubImmNegOperand : AsmOperandClass {
1065 let Name = "AddSubImmNeg";
1066 let ParserMethod = "tryParseImmWithOptionalShift";
1067 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
1070 // An ADD/SUB immediate shifter operand:
1072 // {7-6} - shift type: 00 = lsl
1073 // {5-0} - imm6: #0 or #12
1074 class addsub_shifted_imm<ValueType Ty>
1075 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
1076 let PrintMethod = "printAddSubImm";
1077 let EncoderMethod = "getAddSubImmOpValue";
1078 let ParserMatchClass = AddSubImmOperand;
1079 let MIOperandInfo = (ops i32imm, i32imm);
1082 class addsub_shifted_imm_neg<ValueType Ty>
1084 let EncoderMethod = "getAddSubImmOpValue";
1085 let ParserMatchClass = AddSubImmNegOperand;
1086 let MIOperandInfo = (ops i32imm, i32imm);
1089 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
1090 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
1091 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
1092 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
1094 def gi_addsub_shifted_imm32 :
1095 GIComplexOperandMatcher<s32, "selectArithImmed">,
1096 GIComplexPatternEquiv<addsub_shifted_imm32>;
1098 def gi_addsub_shifted_imm64 :
1099 GIComplexOperandMatcher<s64, "selectArithImmed">,
1100 GIComplexPatternEquiv<addsub_shifted_imm64>;
1102 class neg_addsub_shifted_imm<ValueType Ty>
1103 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
1104 let PrintMethod = "printAddSubImm";
1105 let EncoderMethod = "getAddSubImmOpValue";
1106 let ParserMatchClass = AddSubImmOperand;
1107 let MIOperandInfo = (ops i32imm, i32imm);
1110 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
1111 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
1113 def gi_neg_addsub_shifted_imm32 :
1114 GIComplexOperandMatcher<s32, "selectNegArithImmed">,
1115 GIComplexPatternEquiv<neg_addsub_shifted_imm32>;
1117 def gi_neg_addsub_shifted_imm64 :
1118 GIComplexOperandMatcher<s64, "selectNegArithImmed">,
1119 GIComplexPatternEquiv<neg_addsub_shifted_imm64>;
1121 // An extend operand:
1122 // {5-3} - extend type
1124 def arith_extend : Operand<i32> {
1125 let PrintMethod = "printArithExtend";
1126 let ParserMatchClass = ExtendOperand;
1128 def arith_extend64 : Operand<i32> {
1129 let PrintMethod = "printArithExtend";
1130 let ParserMatchClass = ExtendOperand64;
1133 // 'extend' that's a lsl of a 64-bit register.
1134 def arith_extendlsl64 : Operand<i32> {
1135 let PrintMethod = "printArithExtend";
1136 let ParserMatchClass = ExtendOperandLSL64;
1139 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
1140 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1141 let PrintMethod = "printExtendedRegister";
1142 let MIOperandInfo = (ops GPR32, arith_extend);
1145 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
1146 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
1147 let PrintMethod = "printExtendedRegister";
1148 let MIOperandInfo = (ops GPR32, arith_extend64);
1151 def arith_extended_reg32_i32 : arith_extended_reg32<i32>;
1152 def gi_arith_extended_reg32_i32 :
1153 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">,
1154 GIComplexPatternEquiv<arith_extended_reg32_i32>;
1156 def arith_extended_reg32_i64 : arith_extended_reg32<i64>;
1157 def gi_arith_extended_reg32_i64 :
1158 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1159 GIComplexPatternEquiv<arith_extended_reg32_i64>;
1161 def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>;
1162 def gi_arith_extended_reg32to64_i64 :
1163 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
1164 GIComplexPatternEquiv<arith_extended_reg32to64_i64>;
1166 // Floating-point immediate.
1168 def fpimm16XForm : SDNodeXForm<fpimm, [{
1169 APFloat InVal = N->getValueAPF();
1170 uint32_t enc = AArch64_AM::getFP16Imm(InVal);
1171 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1174 def fpimm32XForm : SDNodeXForm<fpimm, [{
1175 APFloat InVal = N->getValueAPF();
1176 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
1177 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1180 def fpimm64XForm : SDNodeXForm<fpimm, [{
1181 APFloat InVal = N->getValueAPF();
1182 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
1183 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1186 def fpimm16 : Operand<f16>,
1188 return AArch64_AM::getFP16Imm(Imm) != -1;
1190 let ParserMatchClass = FPImmOperand;
1191 let PrintMethod = "printFPImmOperand";
1194 def fpimm32 : Operand<f32>,
1196 return AArch64_AM::getFP32Imm(Imm) != -1;
1198 let ParserMatchClass = FPImmOperand;
1199 let PrintMethod = "printFPImmOperand";
1201 def fpimm64 : Operand<f64>,
1203 return AArch64_AM::getFP64Imm(Imm) != -1;
1205 let ParserMatchClass = FPImmOperand;
1206 let PrintMethod = "printFPImmOperand";
1209 def fpimm8 : Operand<i32> {
1210 let ParserMatchClass = FPImmOperand;
1211 let PrintMethod = "printFPImmOperand";
1214 def fpimm0 : FPImmLeaf<fAny, [{
1215 return Imm.isExactlyValue(+0.0);
1218 def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">,
1219 GISDNodeXFormEquiv<fpimm16XForm>;
1220 def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">,
1221 GISDNodeXFormEquiv<fpimm32XForm>;
1222 def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">,
1223 GISDNodeXFormEquiv<fpimm64XForm>;
1225 // Vector lane operands
1226 class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {
1227 let Name = NamePrefix # "IndexRange" # Min # "_" # Max;
1228 let DiagnosticType = "Invalid" # Name;
1229 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">";
1230 let RenderMethod = "addVectorIndexOperands";
1233 class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc>
1235 let ParserMatchClass = mc;
1236 let PrintMethod = "printVectorIndex";
1239 multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> {
1240 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>;
1241 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>;
1244 def VectorIndex1Operand : AsmVectorIndex<1, 1>;
1245 def VectorIndexBOperand : AsmVectorIndex<0, 15>;
1246 def VectorIndexHOperand : AsmVectorIndex<0, 7>;
1247 def VectorIndexSOperand : AsmVectorIndex<0, 3>;
1248 def VectorIndexDOperand : AsmVectorIndex<0, 1>;
1250 defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,
1251 [{ return ((uint64_t)Imm) == 1; }]>;
1252 defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand,
1253 [{ return ((uint64_t)Imm) < 16; }]>;
1254 defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand,
1255 [{ return ((uint64_t)Imm) < 8; }]>;
1256 defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand,
1257 [{ return ((uint64_t)Imm) < 4; }]>;
1258 defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand,
1259 [{ return ((uint64_t)Imm) < 2; }]>;
1261 defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand,
1262 [{ return ((uint64_t)Imm) == 1; }]>;
1263 defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand,
1264 [{ return ((uint64_t)Imm) < 16; }]>;
1265 defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand,
1266 [{ return ((uint64_t)Imm) < 8; }]>;
1267 defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand,
1268 [{ return ((uint64_t)Imm) < 4; }]>;
1269 defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand,
1270 [{ return ((uint64_t)Imm) < 2; }]>;
1272 def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
1273 def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
1274 def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
1275 def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
1276 def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
1278 defm sve_elm_idx_extdup_b
1279 : VectorIndex<i64, SVEVectorIndexExtDupBOperand,
1280 [{ return ((uint64_t)Imm) < 64; }]>;
1281 defm sve_elm_idx_extdup_h
1282 : VectorIndex<i64, SVEVectorIndexExtDupHOperand,
1283 [{ return ((uint64_t)Imm) < 32; }]>;
1284 defm sve_elm_idx_extdup_s
1285 : VectorIndex<i64, SVEVectorIndexExtDupSOperand,
1286 [{ return ((uint64_t)Imm) < 16; }]>;
1287 defm sve_elm_idx_extdup_d
1288 : VectorIndex<i64, SVEVectorIndexExtDupDOperand,
1289 [{ return ((uint64_t)Imm) < 8; }]>;
1290 defm sve_elm_idx_extdup_q
1291 : VectorIndex<i64, SVEVectorIndexExtDupQOperand,
1292 [{ return ((uint64_t)Imm) < 4; }]>;
1294 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
1295 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
1296 // are encoded as the eight bit value 'abcdefgh'.
1297 def simdimmtype10 : Operand<i32>,
1299 return AArch64_AM::isAdvSIMDModImmType10(
1300 Imm.bitcastToAPInt().getZExtValue());
1301 }], SDNodeXForm<fpimm, [{
1302 APFloat InVal = N->getValueAPF();
1303 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
1306 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1308 let ParserMatchClass = SIMDImmType10Operand;
1309 let PrintMethod = "printSIMDType10Operand";
1314 // System management
1317 // Base encoding for system instruction operands.
1318 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
1319 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
1320 list<dag> pattern = []>
1321 : I<oops, iops, asm, operands, "", pattern> {
1322 let Inst{31-22} = 0b1101010100;
1326 // System instructions which do not have an Rt register.
1327 class SimpleSystemI<bit L, dag iops, string asm, string operands,
1328 list<dag> pattern = []>
1329 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
1330 let Inst{4-0} = 0b11111;
1333 // System instructions which have an Rt register.
1334 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands,
1335 list<dag> pattern = []>
1336 : BaseSystemI<L, oops, iops, asm, operands, pattern>,
1342 // System instructions for transactional memory extension
1343 class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops,
1344 string asm, string operands, list<dag> pattern>
1345 : BaseSystemI<L, oops, iops, asm, operands, pattern>,
1347 let Inst{20-12} = 0b000110011;
1348 let Inst{11-8} = CRm;
1349 let Inst{7-5} = op2;
1350 let DecoderMethod = "";
1356 // System instructions for transactional memory - single input operand
1357 class TMSystemI<bits<4> CRm, string asm, list<dag> pattern>
1358 : TMBaseSystemI<0b1, CRm, 0b011,
1359 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> {
1364 // System instructions that pass a register argument
1365 // This class assumes the register is for input rather than output.
1366 class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm,
1367 list<dag> pattern = []>
1368 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> {
1369 let Inst{20-12} = 0b000110001;
1370 let Inst{11-8} = CRm;
1371 let Inst{7-5} = Op2;
1374 // System instructions for transactional memory - no operand
1375 class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern>
1376 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> {
1377 let Inst{4-0} = 0b11111;
1380 // System instructions for exit from transactions
1381 class TMSystemException<bits<3> op1, string asm, list<dag> pattern>
1382 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>,
1385 let Inst{31-24} = 0b11010100;
1386 let Inst{23-21} = op1;
1387 let Inst{20-5} = imm;
1388 let Inst{4-0} = 0b00000;
1391 // Hint instructions that take both a CRm and a 3-bit immediate.
1392 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
1393 // model patterns with sufficiently fine granularity
1394 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
1395 class HintI<string mnemonic>
1396 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
1397 [(int_aarch64_hint imm0_127:$imm)]>,
1398 Sched<[WriteHint]> {
1400 let Inst{20-12} = 0b000110010;
1401 let Inst{11-5} = imm;
1404 // System instructions taking a single literal operand which encodes into
1405 // CRm. op2 differentiates the opcodes.
1406 def BarrierAsmOperand : AsmOperandClass {
1407 let Name = "Barrier";
1408 let ParserMethod = "tryParseBarrierOperand";
1410 def barrier_op : Operand<i32> {
1411 let PrintMethod = "printBarrierOption";
1412 let ParserMatchClass = BarrierAsmOperand;
1414 def BarriernXSAsmOperand : AsmOperandClass {
1415 let Name = "BarriernXS";
1416 let ParserMethod = "tryParseBarriernXSOperand";
1418 def barrier_nxs_op : Operand<i32> {
1419 let PrintMethod = "printBarriernXSOption";
1420 let ParserMatchClass = BarriernXSAsmOperand;
1422 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
1423 list<dag> pattern = []>
1424 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
1425 Sched<[WriteBarrier]> {
1427 let Inst{20-12} = 0b000110011;
1428 let Inst{11-8} = CRm;
1429 let Inst{7-5} = opc;
1432 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
1433 : SimpleSystemI<0, (ins), asm, "", pattern>,
1437 let Inst{31-12} = 0b11010101000000110010;
1438 let Inst{11-8} = CRm;
1439 let Inst{7-5} = op2;
1440 let Inst{4-0} = 0b11111;
1443 // MRS/MSR system instructions. These have different operand classes because
1444 // a different subset of registers can be accessed through each instruction.
1445 def MRSSystemRegisterOperand : AsmOperandClass {
1446 let Name = "MRSSystemRegister";
1447 let ParserMethod = "tryParseSysReg";
1448 let DiagnosticType = "MRS";
1450 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
1451 def mrs_sysreg_op : Operand<i32> {
1452 let ParserMatchClass = MRSSystemRegisterOperand;
1453 let DecoderMethod = "DecodeMRSSystemRegister";
1454 let PrintMethod = "printMRSSystemRegister";
1457 def MSRSystemRegisterOperand : AsmOperandClass {
1458 let Name = "MSRSystemRegister";
1459 let ParserMethod = "tryParseSysReg";
1460 let DiagnosticType = "MSR";
1462 def msr_sysreg_op : Operand<i32> {
1463 let ParserMatchClass = MSRSystemRegisterOperand;
1464 let DecoderMethod = "DecodeMSRSystemRegister";
1465 let PrintMethod = "printMSRSystemRegister";
1468 def PSBHintOperand : AsmOperandClass {
1469 let Name = "PSBHint";
1470 let ParserMethod = "tryParsePSBHint";
1472 def psbhint_op : Operand<i32> {
1473 let ParserMatchClass = PSBHintOperand;
1474 let PrintMethod = "printPSBHintOp";
1475 let MCOperandPredicate = [{
1476 // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
1477 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
1480 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
1484 def BTIHintOperand : AsmOperandClass {
1485 let Name = "BTIHint";
1486 let ParserMethod = "tryParseBTIHint";
1488 def btihint_op : Operand<i32> {
1489 let ParserMatchClass = BTIHintOperand;
1490 let PrintMethod = "printBTIHintOp";
1491 let MCOperandPredicate = [{
1492 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.
1495 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr;
1499 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
1500 "mrs", "\t$Rt, $systemreg"> {
1502 let Inst{20-5} = systemreg;
1503 let DecoderNamespace = "Fallback";
1504 // The MRS is set as a NZCV setting instruction. Not all MRS instructions
1505 // require doing this. The alternative was to explicitly model each one, but
1506 // it feels like it is unnecessary because it seems there are no negative
1507 // consequences setting these flags for all.
1511 // FIXME: Some of these def NZCV, others don't. Best way to model that?
1512 // Explicitly modeling each of the system register as a register class
1513 // would do it, but feels like overkill at this point.
1514 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
1515 "msr", "\t$systemreg, $Rt"> {
1517 let Inst{20-5} = systemreg;
1518 let DecoderNamespace = "Fallback";
1521 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
1522 let Name = "SystemPStateFieldWithImm0_15";
1523 let ParserMethod = "tryParseSysReg";
1525 def pstatefield4_op : Operand<i32> {
1526 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
1527 let PrintMethod = "printSystemPStateField";
1530 // Instructions to modify PSTATE, no input reg
1531 let Defs = [NZCV] in
1532 class PstateWriteSimple<dag iops, string asm, string operands>
1533 : SimpleSystemI<0, iops, asm, operands> {
1535 let Inst{20-19} = 0b00;
1536 let Inst{15-12} = 0b0100;
1539 class MSRpstateImm0_15
1540 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr",
1541 "\t$pstatefield, $imm">,
1544 bits<6> pstatefield;
1546 let Inst{18-16} = pstatefield{5-3};
1547 let Inst{11-8} = imm;
1548 let Inst{7-5} = pstatefield{2-0};
1550 let DecoderMethod = "DecodeSystemPStateInstruction";
1551 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1552 // Fail the decoder should attempt to decode the instruction as MSRI.
1553 let hasCompleteDecoder = 0;
1556 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1557 let Name = "SystemPStateFieldWithImm0_1";
1558 let ParserMethod = "tryParseSysReg";
1560 def pstatefield1_op : Operand<i32> {
1561 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1562 let PrintMethod = "printSystemPStateField";
1565 class MSRpstateImm0_1
1566 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",
1567 "\t$pstatefield, $imm">,
1570 bits<6> pstatefield;
1572 let Inst{18-16} = pstatefield{5-3};
1573 let Inst{11-9} = 0b000;
1575 let Inst{7-5} = pstatefield{2-0};
1577 let DecoderMethod = "DecodeSystemPStateInstruction";
1578 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1579 // Fail the decoder should attempt to decode the instruction as MSRI.
1580 let hasCompleteDecoder = 0;
1583 // SYS and SYSL generic system instructions.
1584 def SysCRAsmOperand : AsmOperandClass {
1586 let ParserMethod = "tryParseSysCROperand";
1589 def sys_cr_op : Operand<i32> {
1590 let PrintMethod = "printSysCROperand";
1591 let ParserMatchClass = SysCRAsmOperand;
1594 class SystemXtI<bit L, string asm>
1595 : RtSystemI<L, (outs),
1596 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1597 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1602 let Inst{20-19} = 0b01;
1603 let Inst{18-16} = op1;
1604 let Inst{15-12} = Cn;
1605 let Inst{11-8} = Cm;
1606 let Inst{7-5} = op2;
1609 class SystemLXtI<bit L, string asm>
1610 : RtSystemI<L, (outs),
1611 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1612 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1617 let Inst{20-19} = 0b01;
1618 let Inst{18-16} = op1;
1619 let Inst{15-12} = Cn;
1620 let Inst{11-8} = Cm;
1621 let Inst{7-5} = op2;
1625 // Branch (register) instructions:
1633 // otherwise UNDEFINED
1634 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1635 string operands, list<dag> pattern>
1636 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1637 let Inst{31-25} = 0b1101011;
1638 let Inst{24-21} = opc;
1639 let Inst{20-16} = 0b11111;
1640 let Inst{15-10} = 0b000000;
1641 let Inst{4-0} = 0b00000;
1644 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1645 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1650 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1651 class SpecialReturn<bits<4> opc, string asm>
1652 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1653 let Inst{9-5} = 0b11111;
1657 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
1658 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
1662 let Inst{31-30} = sz;
1663 let Inst{29-10} = 0b11100010111111110000;
1668 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
1670 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
1671 let isAuthenticated = 1;
1672 let Inst{31-25} = 0b1101011;
1673 let Inst{20-11} = 0b1111100001;
1675 let Inst{4-0} = 0b11111;
1678 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
1679 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
1682 let Inst{24-22} = 0b100;
1688 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
1689 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
1692 let Inst{23-21} = opc;
1696 let Uses = [LR,SP] in
1697 class AuthReturn<bits<3> op, bits<1> M, string asm>
1698 : AuthBase<M, (outs), (ins), asm, "", []> {
1700 let Inst{23-21} = op;
1701 let Inst{9-0} = 0b1111111111;
1705 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
1706 string operands, string cstr, Operand opr>
1707 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
1711 let isAuthenticated = 1;
1712 let Inst{31-24} = 0b11111000;
1714 let Inst{22} = offset{9};
1716 let Inst{20-12} = offset{8-0};
1722 let DecoderMethod = "DecodeAuthLoadInstruction";
1725 multiclass AuthLoad<bit M, string asm, Operand opr> {
1726 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
1727 (ins GPR64sp:$Rn, opr:$offset),
1728 asm, "\t$Rt, [$Rn, $offset]", "", opr>;
1729 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
1730 (ins GPR64sp:$Rn, opr:$offset),
1731 asm, "\t$Rt, [$Rn, $offset]!",
1732 "$Rn = $wback,@earlyclobber $wback", opr>;
1734 def : InstAlias<asm # "\t$Rt, [$Rn]",
1735 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
1737 def : InstAlias<asm # "\t$Rt, [$wback]!",
1738 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>;
1742 // Conditional branch instruction.
1746 // 4-bit immediate. Pretty-printed as <cc>
1747 def ccode : Operand<i32> {
1748 let PrintMethod = "printCondCode";
1749 let ParserMatchClass = CondCode;
1751 def inv_ccode : Operand<i32> {
1752 // AL and NV are invalid in the aliases which use inv_ccode
1753 let PrintMethod = "printInverseCondCode";
1754 let ParserMatchClass = CondCode;
1755 let MCOperandPredicate = [{
1756 return MCOp.isImm() &&
1757 MCOp.getImm() != AArch64CC::AL &&
1758 MCOp.getImm() != AArch64CC::NV;
1762 // Conditional branch target. 19-bit immediate. The low two bits of the target
1763 // offset are implied zero and so are not part of the immediate.
1764 def am_brcond : Operand<OtherVT> {
1765 let EncoderMethod = "getCondBranchTargetOpValue";
1766 let DecoderMethod = "DecodePCRelLabel19";
1767 let PrintMethod = "printAlignedLabel";
1768 let ParserMatchClass = PCRelLabel19Operand;
1769 let OperandType = "OPERAND_PCREL";
1772 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1773 "b", ".$cond\t$target", "",
1774 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1777 let isTerminator = 1;
1782 let Inst{31-24} = 0b01010100;
1783 let Inst{23-5} = target;
1785 let Inst{3-0} = cond;
1789 // Compare-and-branch instructions.
1791 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1792 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1793 asm, "\t$Rt, $target", "",
1794 [(node regtype:$Rt, bb:$target)]>,
1797 let isTerminator = 1;
1801 let Inst{30-25} = 0b011010;
1803 let Inst{23-5} = target;
1807 multiclass CmpBranch<bit op, string asm, SDNode node> {
1808 def W : BaseCmpBranch<GPR32, op, asm, node> {
1811 def X : BaseCmpBranch<GPR64, op, asm, node> {
1817 // Test-bit-and-branch instructions.
1819 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1820 // the target offset are implied zero and so are not part of the immediate.
1821 def am_tbrcond : Operand<OtherVT> {
1822 let EncoderMethod = "getTestBranchTargetOpValue";
1823 let PrintMethod = "printAlignedLabel";
1824 let ParserMatchClass = BranchTarget14Operand;
1825 let OperandType = "OPERAND_PCREL";
1828 // AsmOperand classes to emit (or not) special diagnostics
1829 def TBZImm0_31Operand : AsmOperandClass {
1830 let Name = "TBZImm0_31";
1831 let PredicateMethod = "isImmInRange<0,31>";
1832 let RenderMethod = "addImmOperands";
1834 def TBZImm32_63Operand : AsmOperandClass {
1835 let Name = "Imm32_63";
1836 let PredicateMethod = "isImmInRange<32,63>";
1837 let DiagnosticType = "InvalidImm0_63";
1838 let RenderMethod = "addImmOperands";
1841 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1842 return (((uint32_t)Imm) < 32);
1844 let ParserMatchClass = matcher;
1847 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1848 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1850 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1851 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1853 let ParserMatchClass = TBZImm32_63Operand;
1856 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1857 bit op, string asm, SDNode node>
1858 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1859 asm, "\t$Rt, $bit_off, $target", "",
1860 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1863 let isTerminator = 1;
1869 let Inst{30-25} = 0b011011;
1871 let Inst{23-19} = bit_off{4-0};
1872 let Inst{18-5} = target;
1875 let DecoderMethod = "DecodeTestAndBranch";
1878 multiclass TestBranch<bit op, string asm, SDNode node> {
1879 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1883 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1887 // Alias X-reg with 0-31 imm to W-Reg.
1888 def : InstAlias<asm # "\t$Rd, $imm, $target",
1889 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1890 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1891 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1892 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1893 tbz_imm0_31_diag:$imm, bb:$target)>;
1897 // Unconditional branch (immediate) instructions.
1899 def am_b_target : Operand<OtherVT> {
1900 let EncoderMethod = "getBranchTargetOpValue";
1901 let PrintMethod = "printAlignedLabel";
1902 let ParserMatchClass = BranchTarget26Operand;
1903 let OperandType = "OPERAND_PCREL";
1905 def am_bl_target : Operand<i64> {
1906 let EncoderMethod = "getBranchTargetOpValue";
1907 let PrintMethod = "printAlignedLabel";
1908 let ParserMatchClass = BranchTarget26Operand;
1909 let OperandType = "OPERAND_PCREL";
1912 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1913 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1916 let Inst{30-26} = 0b00101;
1917 let Inst{25-0} = addr;
1919 let DecoderMethod = "DecodeUnconditionalBranch";
1922 class BranchImm<bit op, string asm, list<dag> pattern>
1923 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1924 class CallImm<bit op, string asm, list<dag> pattern>
1925 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1928 // Basic one-operand data processing instructions.
1931 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1932 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1933 SDPatternOperator node>
1934 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1935 [(set regtype:$Rd, (node regtype:$Rn))]>,
1936 Sched<[WriteI, ReadI]> {
1940 let Inst{30-13} = 0b101101011000000000;
1941 let Inst{12-10} = opc;
1946 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1947 multiclass OneOperandData<bits<3> opc, string asm,
1948 SDPatternOperator node = null_frag> {
1949 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1953 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1958 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1959 : BaseOneOperandData<opc, GPR32, asm, node> {
1963 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1964 : BaseOneOperandData<opc, GPR64, asm, node> {
1968 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
1969 : I<(outs GPR64:$Rd), (ins GPR64:$src, GPR64sp:$Rn), asm, "\t$Rd, $Rn",
1972 Sched<[WriteI, ReadI]> {
1975 let Inst{31-15} = 0b11011010110000010;
1976 let Inst{14-12} = opcode_prefix;
1977 let Inst{11-10} = opcode;
1982 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
1983 : I<(outs GPR64:$Rd), (ins GPR64:$src), asm, "\t$Rd", "$Rd = $src",
1986 let Inst{31-15} = 0b11011010110000010;
1987 let Inst{14-12} = opcode_prefix;
1988 let Inst{11-10} = opcode;
1989 let Inst{9-5} = 0b11111;
1993 class SignAuthTwoOperand<bits<4> opc, string asm,
1994 SDPatternOperator OpNode>
1995 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
1996 asm, "\t$Rd, $Rn, $Rm", "",
1997 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
1998 Sched<[WriteI, ReadI, ReadI]> {
2002 let Inst{31-21} = 0b10011010110;
2003 let Inst{20-16} = Rm;
2004 let Inst{15-14} = 0b00;
2005 let Inst{13-10} = opc;
2010 class ClearAuth<bits<1> data, string asm>
2011 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> {
2013 let Inst{31-11} = 0b110110101100000101000;
2014 let Inst{10} = data;
2015 let Inst{9-5} = 0b11111;
2019 // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
2020 class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
2021 : I<(outs), iops, asm, ops, "", []>,
2022 Sched<[WriteI, ReadI, ReadI]> {
2027 let Inst{30-15} = 0b0111010000000000;
2029 let Inst{13-10} = 0b0010;
2031 let Inst{4-0} = 0b01101;
2034 class FlagRotate<dag iops, string asm, string ops>
2035 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
2038 let Inst{20-15} = imm;
2039 let Inst{13-10} = 0b0001;
2041 let Inst{3-0} = mask;
2045 // Basic two-operand data processing instructions.
2047 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
2049 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2050 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2051 Sched<[WriteI, ReadI, ReadI]> {
2056 let Inst{30} = isSub;
2057 let Inst{28-21} = 0b11010000;
2058 let Inst{20-16} = Rm;
2059 let Inst{15-10} = 0;
2064 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
2066 : BaseBaseAddSubCarry<isSub, regtype, asm,
2067 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
2069 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
2071 : BaseBaseAddSubCarry<isSub, regtype, asm,
2072 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
2077 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
2078 SDNode OpNode, SDNode OpNode_setflags> {
2079 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
2083 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
2089 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
2094 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
2101 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
2102 SDPatternOperator OpNode,
2103 RegisterClass in1regtype = regtype,
2104 RegisterClass in2regtype = regtype>
2105 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm),
2106 asm, "\t$Rd, $Rn, $Rm", "",
2107 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> {
2111 let Inst{30-21} = 0b0011010110;
2112 let Inst{20-16} = Rm;
2113 let Inst{15-14} = 0b00;
2114 let Inst{13-10} = opc;
2119 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
2120 SDPatternOperator OpNode>
2121 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
2122 let Inst{10} = isSigned;
2125 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
2126 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
2127 Sched<[WriteID32, ReadID, ReadID]> {
2130 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
2131 Sched<[WriteID64, ReadID, ReadID]> {
2136 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
2137 SDPatternOperator OpNode = null_frag>
2138 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
2139 Sched<[WriteIS, ReadI]> {
2140 let Inst{11-10} = shift_type;
2143 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
2144 def Wr : BaseShift<shift_type, GPR32, asm> {
2148 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
2152 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
2153 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
2154 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
2156 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
2157 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2159 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
2160 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2162 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
2163 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
2165 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))),
2166 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2167 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2169 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))),
2170 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
2171 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
2174 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
2175 : InstAlias<asm#"\t$dst, $src1, $src2",
2176 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
2178 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
2179 RegisterClass addtype, string asm,
2181 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
2182 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
2187 let Inst{30-24} = 0b0011011;
2188 let Inst{23-21} = opc;
2189 let Inst{20-16} = Rm;
2190 let Inst{15} = isSub;
2191 let Inst{14-10} = Ra;
2196 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
2197 // MADD/MSUB generation is decided by MachineCombiner.cpp
2198 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
2199 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
2200 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2204 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
2205 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
2206 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
2211 class WideMulAccum<bit isSub, bits<3> opc, string asm,
2212 SDNode AccNode, SDNode ExtNode>
2213 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
2214 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
2215 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
2216 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
2220 class MulHi<bits<3> opc, string asm, SDNode OpNode>
2221 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
2222 asm, "\t$Rd, $Rn, $Rm", "",
2223 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
2224 Sched<[WriteIM64, ReadIM, ReadIM]> {
2228 let Inst{31-24} = 0b10011011;
2229 let Inst{23-21} = opc;
2230 let Inst{20-16} = Rm;
2235 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
2236 // (i.e. all bits 1) but is ignored by the processor.
2237 let PostEncoderMethod = "fixMulHigh";
2240 class MulAccumWAlias<string asm, Instruction inst>
2241 : InstAlias<asm#"\t$dst, $src1, $src2",
2242 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
2243 class MulAccumXAlias<string asm, Instruction inst>
2244 : InstAlias<asm#"\t$dst, $src1, $src2",
2245 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
2246 class WideMulAccumAlias<string asm, Instruction inst>
2247 : InstAlias<asm#"\t$dst, $src1, $src2",
2248 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
2250 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
2251 SDPatternOperator OpNode, string asm>
2252 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
2253 asm, "\t$Rd, $Rn, $Rm", "",
2254 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
2255 Sched<[WriteISReg, ReadI, ReadISReg]> {
2261 let Inst{30-21} = 0b0011010110;
2262 let Inst{20-16} = Rm;
2263 let Inst{15-13} = 0b010;
2265 let Inst{11-10} = sz;
2268 let Predicates = [HasCRC];
2272 // Address generation.
2275 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
2276 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
2281 let Inst{31} = page;
2282 let Inst{30-29} = label{1-0};
2283 let Inst{28-24} = 0b10000;
2284 let Inst{23-5} = label{20-2};
2287 let DecoderMethod = "DecodeAdrInstruction";
2294 def movimm32_imm : Operand<i32> {
2295 let ParserMatchClass = AsmImmRange<0, 65535>;
2296 let EncoderMethod = "getMoveWideImmOpValue";
2297 let PrintMethod = "printImm";
2299 def movimm32_shift : Operand<i32> {
2300 let PrintMethod = "printShifter";
2301 let ParserMatchClass = MovImm32ShifterOperand;
2303 def movimm64_shift : Operand<i32> {
2304 let PrintMethod = "printShifter";
2305 let ParserMatchClass = MovImm64ShifterOperand;
2308 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2309 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2311 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
2312 asm, "\t$Rd, $imm$shift", "", []>,
2317 let Inst{30-29} = opc;
2318 let Inst{28-23} = 0b100101;
2319 let Inst{22-21} = shift{5-4};
2320 let Inst{20-5} = imm;
2323 let DecoderMethod = "DecodeMoveImmInstruction";
2326 multiclass MoveImmediate<bits<2> opc, string asm> {
2327 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
2331 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
2336 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2337 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
2339 : I<(outs regtype:$Rd),
2340 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
2341 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
2342 Sched<[WriteI, ReadI]> {
2346 let Inst{30-29} = opc;
2347 let Inst{28-23} = 0b100101;
2348 let Inst{22-21} = shift{5-4};
2349 let Inst{20-5} = imm;
2352 let DecoderMethod = "DecodeMoveImmInstruction";
2355 multiclass InsertImmediate<bits<2> opc, string asm> {
2356 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
2360 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
2369 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
2370 string asm_inst, string asm_ops,
2371 dag inputs, dag pattern>
2372 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>,
2373 Sched<[WriteI, ReadI]> {
2376 let Inst{30} = isSub;
2377 let Inst{29} = setFlags;
2378 let Inst{28-24} = 0b10001;
2383 class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype,
2384 RegisterClass srcRegtype, addsub_shifted_imm immtype,
2385 string asm_inst, SDPatternOperator OpNode>
2386 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm",
2387 (ins srcRegtype:$Rn, immtype:$imm),
2388 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> {
2390 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
2391 let Inst{21-10} = imm{11-0};
2392 let DecoderMethod = "DecodeAddSubImmShift";
2395 class BaseAddSubRegPseudo<RegisterClass regtype,
2396 SDPatternOperator OpNode>
2397 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2398 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2399 Sched<[WriteI, ReadI, ReadI]>;
2401 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
2402 arith_shifted_reg shifted_regtype, string asm,
2403 SDPatternOperator OpNode>
2404 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2405 asm, "\t$Rd, $Rn, $Rm", "",
2406 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
2407 Sched<[WriteISReg, ReadI, ReadISReg]> {
2408 // The operands are in order to match the 'addr' MI operands, so we
2409 // don't need an encoder method and by-name matching. Just use the default
2410 // in-order handling. Since we're using by-order, make sure the names
2416 let Inst{30} = isSub;
2417 let Inst{29} = setFlags;
2418 let Inst{28-24} = 0b01011;
2419 let Inst{23-22} = shift{7-6};
2421 let Inst{20-16} = src2;
2422 let Inst{15-10} = shift{5-0};
2423 let Inst{9-5} = src1;
2424 let Inst{4-0} = dst;
2426 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2429 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
2430 RegisterClass src1Regtype, Operand src2Regtype,
2431 string asm, SDPatternOperator OpNode>
2432 : I<(outs dstRegtype:$R1),
2433 (ins src1Regtype:$R2, src2Regtype:$R3),
2434 asm, "\t$R1, $R2, $R3", "",
2435 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
2436 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2441 let Inst{30} = isSub;
2442 let Inst{29} = setFlags;
2443 let Inst{28-24} = 0b01011;
2444 let Inst{23-21} = 0b001;
2445 let Inst{20-16} = Rm;
2446 let Inst{15-13} = ext{5-3};
2447 let Inst{12-10} = ext{2-0};
2451 let DecoderMethod = "DecodeAddSubERegInstruction";
2454 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2455 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
2456 RegisterClass src1Regtype, RegisterClass src2Regtype,
2457 Operand ext_op, string asm>
2458 : I<(outs dstRegtype:$Rd),
2459 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
2460 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
2461 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2466 let Inst{30} = isSub;
2467 let Inst{29} = setFlags;
2468 let Inst{28-24} = 0b01011;
2469 let Inst{23-21} = 0b001;
2470 let Inst{20-16} = Rm;
2471 let Inst{15} = ext{5};
2472 let Inst{12-10} = ext{2-0};
2476 let DecoderMethod = "DecodeAddSubERegInstruction";
2479 // Aliases for register+register add/subtract.
2480 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
2481 RegisterClass src1Regtype, RegisterClass src2Regtype,
2483 : InstAlias<asm#"\t$dst, $src1, $src2",
2484 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
2487 multiclass AddSub<bit isSub, string mnemonic, string alias,
2488 SDPatternOperator OpNode = null_frag> {
2489 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2490 // Add/Subtract immediate
2491 // Increase the weight of the immediate variant to try to match it before
2492 // the extended register variant.
2493 // We used to match the register variant before the immediate when the
2494 // register argument could be implicitly zero-extended.
2495 let AddedComplexity = 6 in
2496 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
2500 let AddedComplexity = 6 in
2501 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
2506 // Add/Subtract register - Only used for CodeGen
2507 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2508 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2510 // Add/Subtract shifted register
2511 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
2515 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
2521 // Add/Subtract extended register
2522 let AddedComplexity = 1, hasSideEffects = 0 in {
2523 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
2524 arith_extended_reg32_i32, mnemonic, OpNode> {
2527 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
2528 arith_extended_reg32to64_i64, mnemonic, OpNode> {
2533 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
2534 arith_extendlsl64, mnemonic> {
2535 // UXTX and SXTX only.
2536 let Inst{14-13} = 0b11;
2540 // add Rd, Rb, -imm -> sub Rd, Rn, imm
2541 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2542 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
2543 addsub_shifted_imm32_neg:$imm), 0>;
2544 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2545 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
2546 addsub_shifted_imm64_neg:$imm), 0>;
2548 // Register/register aliases with no shift when SP is not used.
2549 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2550 GPR32, GPR32, GPR32, 0>;
2551 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2552 GPR64, GPR64, GPR64, 0>;
2554 // Register/register aliases with no shift when either the destination or
2555 // first source register is SP.
2556 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2557 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
2558 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2559 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
2560 def : AddSubRegAlias<mnemonic,
2561 !cast<Instruction>(NAME#"Xrx64"),
2562 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
2563 def : AddSubRegAlias<mnemonic,
2564 !cast<Instruction>(NAME#"Xrx64"),
2565 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
2568 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
2569 string alias, string cmpAlias> {
2570 let isCompare = 1, Defs = [NZCV] in {
2571 // Add/Subtract immediate
2572 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
2576 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
2581 // Add/Subtract register
2582 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2583 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2585 // Add/Subtract shifted register
2586 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
2590 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
2595 // Add/Subtract extended register
2596 let AddedComplexity = 1 in {
2597 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
2598 arith_extended_reg32_i32, mnemonic, OpNode> {
2601 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
2602 arith_extended_reg32_i64, mnemonic, OpNode> {
2607 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
2608 arith_extendlsl64, mnemonic> {
2609 // UXTX and SXTX only.
2610 let Inst{14-13} = 0b11;
2615 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
2616 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2617 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
2618 addsub_shifted_imm32_neg:$imm), 0>;
2619 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2620 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
2621 addsub_shifted_imm64_neg:$imm), 0>;
2624 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2625 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
2626 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2627 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
2628 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
2629 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2630 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
2631 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2632 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
2633 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
2634 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
2635 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
2636 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
2637 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
2639 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
2640 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2641 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
2642 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2643 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
2645 // Compare shorthands
2646 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
2647 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
2648 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
2649 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
2650 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
2651 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
2652 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
2653 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
2655 // Register/register aliases with no shift when SP is not used.
2656 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2657 GPR32, GPR32, GPR32, 0>;
2658 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2659 GPR64, GPR64, GPR64, 0>;
2661 // Register/register aliases with no shift when the first source register
2663 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2664 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
2665 def : AddSubRegAlias<mnemonic,
2666 !cast<Instruction>(NAME#"Xrx64"),
2667 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
2670 class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode>
2672 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4",
2673 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4),
2674 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> {
2678 let Inst{23-22} = 0b10;
2679 let Inst{21-16} = imm6;
2680 let Inst{15-14} = 0b00;
2681 let Inst{13-10} = imm4;
2682 let Unpredictable{15-14} = 0b11;
2685 class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode>
2686 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> {
2688 let Inst{29} = setsFlags;
2694 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2696 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
2698 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
2700 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
2701 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
2702 Sched<[WriteExtr, ReadExtrHi]> {
2708 let Inst{30-23} = 0b00100111;
2710 let Inst{20-16} = Rm;
2711 let Inst{15-10} = imm;
2716 multiclass ExtractImm<string asm> {
2717 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
2719 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
2722 // imm<5> must be zero.
2725 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
2727 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
2738 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2739 class BaseBitfieldImm<bits<2> opc,
2740 RegisterClass regtype, Operand imm_type, string asm>
2741 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
2742 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
2743 Sched<[WriteIS, ReadI]> {
2749 let Inst{30-29} = opc;
2750 let Inst{28-23} = 0b100110;
2751 let Inst{21-16} = immr;
2752 let Inst{15-10} = imms;
2757 multiclass BitfieldImm<bits<2> opc, string asm> {
2758 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2761 // imms<5> and immr<5> must be zero, else ReservedValue().
2765 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2771 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2772 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2773 RegisterClass regtype, Operand imm_type, string asm>
2774 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2776 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2777 Sched<[WriteIS, ReadI]> {
2783 let Inst{30-29} = opc;
2784 let Inst{28-23} = 0b100110;
2785 let Inst{21-16} = immr;
2786 let Inst{15-10} = imms;
2791 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2792 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2795 // imms<5> and immr<5> must be zero, else ReservedValue().
2799 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2809 // Logical (immediate)
2810 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2811 RegisterClass sregtype, Operand imm_type, string asm,
2813 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2814 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2815 Sched<[WriteI, ReadI]> {
2819 let Inst{30-29} = opc;
2820 let Inst{28-23} = 0b100100;
2821 let Inst{22} = imm{12};
2822 let Inst{21-16} = imm{11-6};
2823 let Inst{15-10} = imm{5-0};
2827 let DecoderMethod = "DecodeLogicalImmInstruction";
2830 // Logical (shifted register)
2831 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2832 logical_shifted_reg shifted_regtype, string asm,
2834 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2835 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2836 Sched<[WriteISReg, ReadI, ReadISReg]> {
2837 // The operands are in order to match the 'addr' MI operands, so we
2838 // don't need an encoder method and by-name matching. Just use the default
2839 // in-order handling. Since we're using by-order, make sure the names
2845 let Inst{30-29} = opc;
2846 let Inst{28-24} = 0b01010;
2847 let Inst{23-22} = shift{7-6};
2849 let Inst{20-16} = src2;
2850 let Inst{15-10} = shift{5-0};
2851 let Inst{9-5} = src1;
2852 let Inst{4-0} = dst;
2854 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2857 // Aliases for register+register logical instructions.
2858 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2859 : InstAlias<asm#"\t$dst, $src1, $src2",
2860 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2862 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2864 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2865 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2866 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2867 logical_imm32:$imm))]> {
2869 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2871 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2872 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2873 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2874 logical_imm64:$imm))]> {
2878 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2879 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2880 logical_imm32_not:$imm), 0>;
2881 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2882 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2883 logical_imm64_not:$imm), 0>;
2886 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2888 let isCompare = 1, Defs = [NZCV] in {
2889 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2890 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2892 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2894 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2895 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2898 } // end Defs = [NZCV]
2900 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2901 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2902 logical_imm32_not:$imm), 0>;
2903 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2904 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2905 logical_imm64_not:$imm), 0>;
2908 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2909 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2910 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2911 Sched<[WriteI, ReadI, ReadI]>;
2913 // Split from LogicalImm as not all instructions have both.
2914 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2915 SDPatternOperator OpNode> {
2916 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2917 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2918 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2921 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2922 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2923 logical_shifted_reg32:$Rm))]> {
2926 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2927 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2928 logical_shifted_reg64:$Rm))]> {
2932 def : LogicalRegAlias<mnemonic,
2933 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2934 def : LogicalRegAlias<mnemonic,
2935 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2938 // Split from LogicalReg to allow setting NZCV Defs
2939 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2940 SDPatternOperator OpNode = null_frag> {
2941 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2942 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2943 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2945 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2946 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2949 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2950 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2955 def : LogicalRegAlias<mnemonic,
2956 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2957 def : LogicalRegAlias<mnemonic,
2958 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2962 // Conditionally set flags
2965 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2966 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2967 string mnemonic, SDNode OpNode>
2968 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2969 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2970 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2971 (i32 imm:$cond), NZCV))]>,
2972 Sched<[WriteI, ReadI]> {
2982 let Inst{29-21} = 0b111010010;
2983 let Inst{20-16} = imm;
2984 let Inst{15-12} = cond;
2985 let Inst{11-10} = 0b10;
2988 let Inst{3-0} = nzcv;
2991 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2992 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2994 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2995 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2996 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2997 (i32 imm:$cond), NZCV))]>,
2998 Sched<[WriteI, ReadI, ReadI]> {
3008 let Inst{29-21} = 0b111010010;
3009 let Inst{20-16} = Rm;
3010 let Inst{15-12} = cond;
3011 let Inst{11-10} = 0b00;
3014 let Inst{3-0} = nzcv;
3017 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
3018 // immediate operand variants
3019 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
3022 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
3025 // register operand variants
3026 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
3029 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
3035 // Conditional select
3038 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
3039 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3040 asm, "\t$Rd, $Rn, $Rm, $cond", "",
3042 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
3043 Sched<[WriteI, ReadI, ReadI]> {
3052 let Inst{29-21} = 0b011010100;
3053 let Inst{20-16} = Rm;
3054 let Inst{15-12} = cond;
3055 let Inst{11-10} = op2;
3060 multiclass CondSelect<bit op, bits<2> op2, string asm> {
3061 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
3064 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
3069 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
3071 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3072 asm, "\t$Rd, $Rn, $Rm, $cond", "",
3074 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
3075 (i32 imm:$cond), NZCV))]>,
3076 Sched<[WriteI, ReadI, ReadI]> {
3085 let Inst{29-21} = 0b011010100;
3086 let Inst{20-16} = Rm;
3087 let Inst{15-12} = cond;
3088 let Inst{11-10} = op2;
3093 def inv_cond_XFORM : SDNodeXForm<imm, [{
3094 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
3095 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
3099 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
3100 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
3103 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
3107 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
3108 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
3109 (inv_cond_XFORM imm:$cond))>;
3111 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
3112 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
3113 (inv_cond_XFORM imm:$cond))>;
3117 // Special Mask Value
3119 def maski8_or_more : Operand<i32>,
3120 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
3122 def maski16_or_more : Operand<i32>,
3123 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
3131 // (unsigned immediate)
3132 // Indexed for 8-bit registers. offset is in range [0,4095].
3133 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
3134 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
3135 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
3136 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
3137 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
3139 // (unsigned immediate)
3140 // Indexed for 8-bit registers. offset is in range [0,63].
3141 def am_indexed8_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<1,63>", []>;
3142 def am_indexed16_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<2,63>", []>;
3143 def am_indexed32_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<4,63>", []>;
3144 def am_indexed64_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<8,63>", []>;
3146 def gi_am_indexed8 :
3147 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
3148 GIComplexPatternEquiv<am_indexed8>;
3149 def gi_am_indexed16 :
3150 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
3151 GIComplexPatternEquiv<am_indexed16>;
3152 def gi_am_indexed32 :
3153 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
3154 GIComplexPatternEquiv<am_indexed32>;
3155 def gi_am_indexed64 :
3156 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
3157 GIComplexPatternEquiv<am_indexed64>;
3158 def gi_am_indexed128 :
3159 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
3160 GIComplexPatternEquiv<am_indexed128>;
3162 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
3163 let Name = "UImm12Offset" # Scale;
3164 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
3165 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
3166 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
3169 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
3170 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
3171 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
3172 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
3173 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
3175 class uimm12_scaled<int Scale> : Operand<i64> {
3176 let ParserMatchClass
3177 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
3179 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
3180 let PrintMethod = "printUImm12Offset<" # Scale # ">";
3183 def uimm12s1 : uimm12_scaled<1>;
3184 def uimm12s2 : uimm12_scaled<2>;
3185 def uimm12s4 : uimm12_scaled<4>;
3186 def uimm12s8 : uimm12_scaled<8>;
3187 def uimm12s16 : uimm12_scaled<16>;
3189 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3190 string asm, list<dag> pattern>
3191 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3197 let Inst{31-30} = sz;
3198 let Inst{29-27} = 0b111;
3200 let Inst{25-24} = 0b01;
3201 let Inst{23-22} = opc;
3202 let Inst{21-10} = offset;
3206 let DecoderMethod = "DecodeUnsignedLdStInstruction";
3209 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3210 Operand indextype, string asm, list<dag> pattern> {
3211 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3212 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
3213 (ins GPR64sp:$Rn, indextype:$offset),
3217 def : InstAlias<asm # "\t$Rt, [$Rn]",
3218 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3221 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3222 Operand indextype, string asm, list<dag> pattern> {
3223 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3224 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3225 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3229 def : InstAlias<asm # "\t$Rt, [$Rn]",
3230 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3233 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
3234 // substitute zero-registers automatically.
3236 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
3238 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3239 Operand indextype, string asm, list<dag> pattern> {
3240 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3241 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
3242 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
3246 def : InstAlias<asm # "\t$Rt, [$Rn]",
3247 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
3250 def PrefetchOperand : AsmOperandClass {
3251 let Name = "Prefetch";
3252 let ParserMethod = "tryParsePrefetch";
3254 def prfop : Operand<i32> {
3255 let PrintMethod = "printPrefetchOp";
3256 let ParserMatchClass = PrefetchOperand;
3259 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3260 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
3261 : BaseLoadStoreUI<sz, V, opc,
3262 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
3270 // Load literal address: 19-bit immediate. The low two bits of the target
3271 // offset are implied zero and so are not part of the immediate.
3272 def am_ldrlit : Operand<iPTR> {
3273 let EncoderMethod = "getLoadLiteralOpValue";
3274 let DecoderMethod = "DecodePCRelLabel19";
3275 let PrintMethod = "printAlignedLabel";
3276 let ParserMatchClass = PCRelLabel19Operand;
3277 let OperandType = "OPERAND_PCREL";
3280 let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
3281 class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
3282 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
3283 asm, "\t$Rt, $label", "", pat>,
3287 let Inst{31-30} = opc;
3288 let Inst{29-27} = 0b011;
3290 let Inst{25-24} = 0b00;
3291 let Inst{23-5} = label;
3295 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3296 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
3297 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
3298 asm, "\t$Rt, $label", "", pat>,
3302 let Inst{31-30} = opc;
3303 let Inst{29-27} = 0b011;
3305 let Inst{25-24} = 0b00;
3306 let Inst{23-5} = label;
3311 // Load/store register offset
3314 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
3315 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
3316 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
3317 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
3318 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
3320 def gi_ro_Xindexed8 :
3321 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">,
3322 GIComplexPatternEquiv<ro_Xindexed8>;
3323 def gi_ro_Xindexed16 :
3324 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">,
3325 GIComplexPatternEquiv<ro_Xindexed16>;
3326 def gi_ro_Xindexed32 :
3327 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">,
3328 GIComplexPatternEquiv<ro_Xindexed32>;
3329 def gi_ro_Xindexed64 :
3330 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">,
3331 GIComplexPatternEquiv<ro_Xindexed64>;
3332 def gi_ro_Xindexed128 :
3333 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">,
3334 GIComplexPatternEquiv<ro_Xindexed128>;
3336 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
3337 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
3338 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
3339 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
3340 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
3342 def gi_ro_Windexed8 :
3343 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">,
3344 GIComplexPatternEquiv<ro_Windexed8>;
3345 def gi_ro_Windexed16 :
3346 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">,
3347 GIComplexPatternEquiv<ro_Windexed16>;
3348 def gi_ro_Windexed32 :
3349 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">,
3350 GIComplexPatternEquiv<ro_Windexed32>;
3351 def gi_ro_Windexed64 :
3352 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">,
3353 GIComplexPatternEquiv<ro_Windexed64>;
3354 def gi_ro_Windexed128 :
3355 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">,
3356 GIComplexPatternEquiv<ro_Windexed128>;
3358 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
3359 let Name = "Mem" # Reg # "Extend" # Width;
3360 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
3361 let RenderMethod = "addMemExtendOperands";
3362 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
3365 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
3366 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3367 // the trivial shift.
3368 let RenderMethod = "addMemExtend8Operands";
3370 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
3371 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
3372 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
3373 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
3375 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
3376 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
3377 // the trivial shift.
3378 let RenderMethod = "addMemExtend8Operands";
3380 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
3381 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
3382 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
3383 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
3385 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
3387 let ParserMatchClass = ParserClass;
3388 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
3389 let DecoderMethod = "DecodeMemExtend";
3390 let EncoderMethod = "getMemExtendOpValue";
3391 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
3394 def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
3395 def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
3396 def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
3397 def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
3398 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
3400 def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
3401 def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
3402 def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
3403 def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
3404 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
3406 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
3407 Operand wextend, Operand xextend> {
3408 // CodeGen-level pattern covering the entire addressing mode.
3409 ComplexPattern Wpat = windex;
3410 ComplexPattern Xpat = xindex;
3412 // Asm-level Operand covering the valid "uxtw #3" style syntax.
3413 Operand Wext = wextend;
3414 Operand Xext = xextend;
3417 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
3418 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
3419 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
3420 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
3421 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
3424 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3425 string asm, dag ins, dag outs, list<dag> pat>
3426 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3431 let Inst{31-30} = sz;
3432 let Inst{29-27} = 0b111;
3434 let Inst{25-24} = 0b00;
3435 let Inst{23-22} = opc;
3437 let Inst{20-16} = Rm;
3438 let Inst{15} = extend{1}; // sign extend Rm?
3440 let Inst{12} = extend{0}; // do shift?
3441 let Inst{11-10} = 0b10;
3446 class ROInstAlias<string asm, DAGOperand regtype, Instruction INST>
3447 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
3448 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3450 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3451 string asm, ValueType Ty, SDPatternOperator loadop> {
3452 let AddedComplexity = 10 in
3453 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
3455 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3456 [(set (Ty regtype:$Rt),
3457 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3458 ro_Wextend8:$extend)))]>,
3459 Sched<[WriteLDIdx, ReadAdrBase]> {
3463 let AddedComplexity = 10 in
3464 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
3466 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3467 [(set (Ty regtype:$Rt),
3468 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3469 ro_Xextend8:$extend)))]>,
3470 Sched<[WriteLDIdx, ReadAdrBase]> {
3474 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3477 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3478 string asm, ValueType Ty, SDPatternOperator storeop> {
3479 let AddedComplexity = 10 in
3480 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3481 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3482 [(storeop (Ty regtype:$Rt),
3483 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3484 ro_Wextend8:$extend))]>,
3485 Sched<[WriteSTIdx, ReadAdrBase]> {
3489 let AddedComplexity = 10 in
3490 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3491 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3492 [(storeop (Ty regtype:$Rt),
3493 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3494 ro_Xextend8:$extend))]>,
3495 Sched<[WriteSTIdx, ReadAdrBase]> {
3499 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3502 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3503 string asm, dag ins, dag outs, list<dag> pat>
3504 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3509 let Inst{31-30} = sz;
3510 let Inst{29-27} = 0b111;
3512 let Inst{25-24} = 0b00;
3513 let Inst{23-22} = opc;
3515 let Inst{20-16} = Rm;
3516 let Inst{15} = extend{1}; // sign extend Rm?
3518 let Inst{12} = extend{0}; // do shift?
3519 let Inst{11-10} = 0b10;
3524 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3525 string asm, ValueType Ty, SDPatternOperator loadop> {
3526 let AddedComplexity = 10 in
3527 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3528 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3529 [(set (Ty regtype:$Rt),
3530 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3531 ro_Wextend16:$extend)))]>,
3532 Sched<[WriteLDIdx, ReadAdrBase]> {
3536 let AddedComplexity = 10 in
3537 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3538 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3539 [(set (Ty regtype:$Rt),
3540 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3541 ro_Xextend16:$extend)))]>,
3542 Sched<[WriteLDIdx, ReadAdrBase]> {
3546 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3549 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3550 string asm, ValueType Ty, SDPatternOperator storeop> {
3551 let AddedComplexity = 10 in
3552 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3553 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3554 [(storeop (Ty regtype:$Rt),
3555 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3556 ro_Wextend16:$extend))]>,
3557 Sched<[WriteSTIdx, ReadAdrBase]> {
3561 let AddedComplexity = 10 in
3562 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3563 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3564 [(storeop (Ty regtype:$Rt),
3565 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3566 ro_Xextend16:$extend))]>,
3567 Sched<[WriteSTIdx, ReadAdrBase]> {
3571 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3574 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3575 string asm, dag ins, dag outs, list<dag> pat>
3576 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3581 let Inst{31-30} = sz;
3582 let Inst{29-27} = 0b111;
3584 let Inst{25-24} = 0b00;
3585 let Inst{23-22} = opc;
3587 let Inst{20-16} = Rm;
3588 let Inst{15} = extend{1}; // sign extend Rm?
3590 let Inst{12} = extend{0}; // do shift?
3591 let Inst{11-10} = 0b10;
3596 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3597 string asm, ValueType Ty, SDPatternOperator loadop> {
3598 let AddedComplexity = 10 in
3599 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3600 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3601 [(set (Ty regtype:$Rt),
3602 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3603 ro_Wextend32:$extend)))]>,
3604 Sched<[WriteLDIdx, ReadAdrBase]> {
3608 let AddedComplexity = 10 in
3609 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3610 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3611 [(set (Ty regtype:$Rt),
3612 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3613 ro_Xextend32:$extend)))]>,
3614 Sched<[WriteLDIdx, ReadAdrBase]> {
3618 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3621 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3622 string asm, ValueType Ty, SDPatternOperator storeop> {
3623 let AddedComplexity = 10 in
3624 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3625 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3626 [(storeop (Ty regtype:$Rt),
3627 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3628 ro_Wextend32:$extend))]>,
3629 Sched<[WriteSTIdx, ReadAdrBase]> {
3633 let AddedComplexity = 10 in
3634 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3635 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3636 [(storeop (Ty regtype:$Rt),
3637 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3638 ro_Xextend32:$extend))]>,
3639 Sched<[WriteSTIdx, ReadAdrBase]> {
3643 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3646 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3647 string asm, dag ins, dag outs, list<dag> pat>
3648 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3653 let Inst{31-30} = sz;
3654 let Inst{29-27} = 0b111;
3656 let Inst{25-24} = 0b00;
3657 let Inst{23-22} = opc;
3659 let Inst{20-16} = Rm;
3660 let Inst{15} = extend{1}; // sign extend Rm?
3662 let Inst{12} = extend{0}; // do shift?
3663 let Inst{11-10} = 0b10;
3668 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3669 string asm, ValueType Ty, SDPatternOperator loadop> {
3670 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3671 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3672 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3673 [(set (Ty regtype:$Rt),
3674 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3675 ro_Wextend64:$extend)))]>,
3676 Sched<[WriteLDIdx, ReadAdrBase]> {
3680 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3681 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3682 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3683 [(set (Ty regtype:$Rt),
3684 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3685 ro_Xextend64:$extend)))]>,
3686 Sched<[WriteLDIdx, ReadAdrBase]> {
3690 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3693 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3694 string asm, ValueType Ty, SDPatternOperator storeop> {
3695 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3696 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3697 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3698 [(storeop (Ty regtype:$Rt),
3699 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3700 ro_Wextend64:$extend))]>,
3701 Sched<[WriteSTIdx, ReadAdrBase]> {
3705 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3706 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3707 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3708 [(storeop (Ty regtype:$Rt),
3709 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3710 ro_Xextend64:$extend))]>,
3711 Sched<[WriteSTIdx, ReadAdrBase]> {
3715 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3718 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3719 string asm, dag ins, dag outs, list<dag> pat>
3720 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3725 let Inst{31-30} = sz;
3726 let Inst{29-27} = 0b111;
3728 let Inst{25-24} = 0b00;
3729 let Inst{23-22} = opc;
3731 let Inst{20-16} = Rm;
3732 let Inst{15} = extend{1}; // sign extend Rm?
3734 let Inst{12} = extend{0}; // do shift?
3735 let Inst{11-10} = 0b10;
3740 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3741 string asm, ValueType Ty, SDPatternOperator loadop> {
3742 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3743 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3744 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3745 [(set (Ty regtype:$Rt),
3746 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
3747 ro_Wextend128:$extend)))]>,
3748 Sched<[WriteLDIdx, ReadAdrBase]> {
3752 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3753 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3754 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3755 [(set (Ty regtype:$Rt),
3756 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
3757 ro_Xextend128:$extend)))]>,
3758 Sched<[WriteLDIdx, ReadAdrBase]> {
3762 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3765 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3766 string asm, ValueType Ty, SDPatternOperator storeop> {
3767 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3768 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3769 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3771 Sched<[WriteSTIdx, ReadAdrBase]> {
3775 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3776 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3777 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3779 Sched<[WriteSTIdx, ReadAdrBase]> {
3783 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3786 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3787 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
3788 string asm, list<dag> pat>
3789 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
3795 let Inst{31-30} = sz;
3796 let Inst{29-27} = 0b111;
3798 let Inst{25-24} = 0b00;
3799 let Inst{23-22} = opc;
3801 let Inst{20-16} = Rm;
3802 let Inst{15} = extend{1}; // sign extend Rm?
3804 let Inst{12} = extend{0}; // do shift?
3805 let Inst{11-10} = 0b10;
3810 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
3811 def roW : BasePrefetchRO<sz, V, opc, (outs),
3812 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3813 asm, [(AArch64Prefetch imm:$Rt,
3814 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3815 ro_Wextend64:$extend))]> {
3819 def roX : BasePrefetchRO<sz, V, opc, (outs),
3820 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3821 asm, [(AArch64Prefetch imm:$Rt,
3822 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3823 ro_Xextend64:$extend))]> {
3827 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3828 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3829 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3833 // Load/store unscaled immediate
3836 def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3837 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3838 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3839 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3840 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3842 def gi_am_unscaled8 :
3843 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
3844 GIComplexPatternEquiv<am_unscaled8>;
3845 def gi_am_unscaled16 :
3846 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
3847 GIComplexPatternEquiv<am_unscaled16>;
3848 def gi_am_unscaled32 :
3849 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
3850 GIComplexPatternEquiv<am_unscaled32>;
3851 def gi_am_unscaled64 :
3852 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
3853 GIComplexPatternEquiv<am_unscaled64>;
3854 def gi_am_unscaled128 :
3855 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
3856 GIComplexPatternEquiv<am_unscaled128>;
3859 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3860 string asm, list<dag> pattern>
3861 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3865 let Inst{31-30} = sz;
3866 let Inst{29-27} = 0b111;
3868 let Inst{25-24} = 0b00;
3869 let Inst{23-22} = opc;
3871 let Inst{20-12} = offset;
3872 let Inst{11-10} = 0b00;
3876 let DecoderMethod = "DecodeSignedLdStInstruction";
3879 // Armv8.4 LDAPR & STLR with Immediate Offset instruction
3880 multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3881 DAGOperand regtype > {
3882 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),
3883 (ins GPR64sp:$Rn, simm9:$offset), asm, []>,
3888 def : InstAlias<asm # "\t$Rt, [$Rn]",
3889 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3892 multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3893 DAGOperand regtype > {
3894 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),
3895 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3901 def : InstAlias<asm # "\t$Rt, [$Rn]",
3902 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3905 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3906 string asm, list<dag> pattern> {
3907 let AddedComplexity = 1 in // try this before LoadUI
3908 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3909 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3912 def : InstAlias<asm # "\t$Rt, [$Rn]",
3913 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3916 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
3917 string asm, list<dag> pattern> {
3918 let AddedComplexity = 1 in // try this before StoreUI
3919 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3920 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3924 def : InstAlias<asm # "\t$Rt, [$Rn]",
3925 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3928 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3930 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3931 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3932 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3936 def : InstAlias<asm # "\t$Rt, [$Rn]",
3937 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3941 // Load/store unscaled immediate, unprivileged
3944 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3945 dag oops, dag iops, string asm>
3946 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3950 let Inst{31-30} = sz;
3951 let Inst{29-27} = 0b111;
3953 let Inst{25-24} = 0b00;
3954 let Inst{23-22} = opc;
3956 let Inst{20-12} = offset;
3957 let Inst{11-10} = 0b10;
3961 let DecoderMethod = "DecodeSignedLdStInstruction";
3964 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3965 RegisterClass regtype, string asm> {
3966 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3967 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3968 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3971 def : InstAlias<asm # "\t$Rt, [$Rn]",
3972 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3975 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3976 RegisterClass regtype, string asm> {
3977 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3978 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3979 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3983 def : InstAlias<asm # "\t$Rt, [$Rn]",
3984 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3988 // Load/store pre-indexed
3991 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3992 string asm, string cstr, list<dag> pat>
3993 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3997 let Inst{31-30} = sz;
3998 let Inst{29-27} = 0b111;
4000 let Inst{25-24} = 0;
4001 let Inst{23-22} = opc;
4003 let Inst{20-12} = offset;
4004 let Inst{11-10} = 0b11;
4008 let DecoderMethod = "DecodeSignedLdStInstruction";
4011 let hasSideEffects = 0 in {
4012 let mayStore = 0, mayLoad = 1 in
4013 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4015 : BaseLoadStorePreIdx<sz, V, opc,
4016 (outs GPR64sp:$wback, regtype:$Rt),
4017 (ins GPR64sp:$Rn, simm9:$offset), asm,
4018 "$Rn = $wback,@earlyclobber $wback", []>,
4019 Sched<[WriteAdr, WriteLD]>;
4021 let mayStore = 1, mayLoad = 0 in
4022 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4023 string asm, SDPatternOperator storeop, ValueType Ty>
4024 : BaseLoadStorePreIdx<sz, V, opc,
4025 (outs GPR64sp:$wback),
4026 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
4027 asm, "$Rn = $wback,@earlyclobber $wback",
4028 [(set GPR64sp:$wback,
4029 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
4030 Sched<[WriteAdr, WriteST]>;
4031 } // hasSideEffects = 0
4034 // Load/store post-indexed
4037 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
4038 string asm, string cstr, list<dag> pat>
4039 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
4043 let Inst{31-30} = sz;
4044 let Inst{29-27} = 0b111;
4046 let Inst{25-24} = 0b00;
4047 let Inst{23-22} = opc;
4049 let Inst{20-12} = offset;
4050 let Inst{11-10} = 0b01;
4054 let DecoderMethod = "DecodeSignedLdStInstruction";
4057 let hasSideEffects = 0 in {
4058 let mayStore = 0, mayLoad = 1 in
4059 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4061 : BaseLoadStorePostIdx<sz, V, opc,
4062 (outs GPR64sp:$wback, regtype:$Rt),
4063 (ins GPR64sp:$Rn, simm9:$offset),
4064 asm, "$Rn = $wback,@earlyclobber $wback", []>,
4065 Sched<[WriteAdr, WriteLD]>;
4067 let mayStore = 1, mayLoad = 0 in
4068 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
4069 string asm, SDPatternOperator storeop, ValueType Ty>
4070 : BaseLoadStorePostIdx<sz, V, opc,
4071 (outs GPR64sp:$wback),
4072 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
4073 asm, "$Rn = $wback,@earlyclobber $wback",
4074 [(set GPR64sp:$wback,
4075 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
4076 Sched<[WriteAdr, WriteST]>;
4077 } // hasSideEffects = 0
4084 // (indexed, offset)
4086 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
4088 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4093 let Inst{31-30} = opc;
4094 let Inst{29-27} = 0b101;
4096 let Inst{25-23} = 0b010;
4098 let Inst{21-15} = offset;
4099 let Inst{14-10} = Rt2;
4103 let DecoderMethod = "DecodePairLdStInstruction";
4106 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4107 Operand indextype, string asm> {
4108 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4109 def i : BaseLoadStorePairOffset<opc, V, 1,
4110 (outs regtype:$Rt, regtype:$Rt2),
4111 (ins GPR64sp:$Rn, indextype:$offset), asm>,
4112 Sched<[WriteLD, WriteLDHi]>;
4114 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4115 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4120 multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
4121 Operand indextype, string asm> {
4122 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
4123 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
4124 (ins regtype:$Rt, regtype:$Rt2,
4125 GPR64sp:$Rn, indextype:$offset),
4129 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4130 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4135 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4137 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
4142 let Inst{31-30} = opc;
4143 let Inst{29-27} = 0b101;
4145 let Inst{25-23} = 0b011;
4147 let Inst{21-15} = offset;
4148 let Inst{14-10} = Rt2;
4152 let DecoderMethod = "DecodePairLdStInstruction";
4155 let hasSideEffects = 0 in {
4156 let mayStore = 0, mayLoad = 1 in
4157 class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4158 Operand indextype, string asm>
4159 : BaseLoadStorePairPreIdx<opc, V, 1,
4160 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4161 (ins GPR64sp:$Rn, indextype:$offset), asm>,
4162 Sched<[WriteAdr, WriteLD, WriteLDHi]>;
4164 let mayStore = 1, mayLoad = 0 in
4165 class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
4166 Operand indextype, string asm>
4167 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
4168 (ins regtype:$Rt, regtype:$Rt2,
4169 GPR64sp:$Rn, indextype:$offset),
4171 Sched<[WriteAdr, WriteSTP]>;
4172 } // hasSideEffects = 0
4176 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
4178 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
4183 let Inst{31-30} = opc;
4184 let Inst{29-27} = 0b101;
4186 let Inst{25-23} = 0b001;
4188 let Inst{21-15} = offset;
4189 let Inst{14-10} = Rt2;
4193 let DecoderMethod = "DecodePairLdStInstruction";
4196 let hasSideEffects = 0 in {
4197 let mayStore = 0, mayLoad = 1 in
4198 class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4199 Operand idxtype, string asm>
4200 : BaseLoadStorePairPostIdx<opc, V, 1,
4201 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
4202 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
4203 Sched<[WriteAdr, WriteLD, WriteLDHi]>;
4205 let mayStore = 1, mayLoad = 0 in
4206 class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
4207 Operand idxtype, string asm>
4208 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
4209 (ins regtype:$Rt, regtype:$Rt2,
4210 GPR64sp:$Rn, idxtype:$offset),
4212 Sched<[WriteAdr, WriteSTP]>;
4213 } // hasSideEffects = 0
4217 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
4219 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
4224 let Inst{31-30} = opc;
4225 let Inst{29-27} = 0b101;
4227 let Inst{25-23} = 0b000;
4229 let Inst{21-15} = offset;
4230 let Inst{14-10} = Rt2;
4234 let DecoderMethod = "DecodePairLdStInstruction";
4237 multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,
4238 Operand indextype, string asm> {
4239 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
4240 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
4241 (outs regtype:$Rt, regtype:$Rt2),
4242 (ins GPR64sp:$Rn, indextype:$offset), asm>,
4243 Sched<[WriteLD, WriteLDHi]>;
4246 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4247 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4251 multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,
4252 Operand indextype, string asm> {
4253 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
4254 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
4255 (ins regtype:$Rt, regtype:$Rt2,
4256 GPR64sp:$Rn, indextype:$offset),
4260 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
4261 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
4266 // Load/store exclusive
4269 // True exclusive operations write to and/or read from the system's exclusive
4270 // monitors, which as far as a compiler is concerned can be modelled as a
4271 // random shared memory address. Hence LoadExclusive mayStore.
4273 // Since these instructions have the undefined register bits set to 1 in
4274 // their canonical form, we need a post encoder method to set those bits
4275 // to 1 when encoding these instructions. We do this using the
4276 // fixLoadStoreExclusive function. This function has template parameters:
4278 // fixLoadStoreExclusive<int hasRs, int hasRt2>
4280 // hasRs indicates that the instruction uses the Rs field, so we won't set
4281 // it to 1 (and the same for Rt2). We don't need template parameters for
4282 // the other register fields since Rt and Rn are always used.
4284 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
4285 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4286 dag oops, dag iops, string asm, string operands>
4287 : I<oops, iops, asm, operands, "", []> {
4288 let Inst{31-30} = sz;
4289 let Inst{29-24} = 0b001000;
4295 let DecoderMethod = "DecodeExclusiveLdStInstruction";
4298 // Neither Rs nor Rt2 operands.
4299 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4300 dag oops, dag iops, string asm, string operands>
4301 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
4304 let Inst{20-16} = 0b11111;
4305 let Unpredictable{20-16} = 0b11111;
4306 let Inst{14-10} = 0b11111;
4307 let Unpredictable{14-10} = 0b11111;
4311 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
4314 // Simple load acquires don't set the exclusive monitor
4315 let mayLoad = 1, mayStore = 0 in
4316 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4317 RegisterClass regtype, string asm>
4318 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4319 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4322 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4323 RegisterClass regtype, string asm>
4324 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
4325 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
4328 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4329 RegisterClass regtype, string asm>
4330 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4331 (outs regtype:$Rt, regtype:$Rt2),
4332 (ins GPR64sp0:$Rn), asm,
4333 "\t$Rt, $Rt2, [$Rn]">,
4334 Sched<[WriteLD, WriteLDHi]> {
4338 let Inst{14-10} = Rt2;
4342 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
4345 // Simple store release operations do not check the exclusive monitor.
4346 let mayLoad = 0, mayStore = 1 in
4347 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4348 RegisterClass regtype, string asm>
4349 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
4350 (ins regtype:$Rt, GPR64sp0:$Rn),
4351 asm, "\t$Rt, [$Rn]">,
4354 let mayLoad = 1, mayStore = 1 in
4355 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4356 RegisterClass regtype, string asm>
4357 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
4358 (ins regtype:$Rt, GPR64sp0:$Rn),
4359 asm, "\t$Ws, $Rt, [$Rn]">,
4364 let Inst{20-16} = Ws;
4368 let Constraints = "@earlyclobber $Ws";
4369 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
4372 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
4373 RegisterClass regtype, string asm>
4374 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
4376 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
4377 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
4383 let Inst{20-16} = Ws;
4384 let Inst{14-10} = Rt2;
4388 let Constraints = "@earlyclobber $Ws";
4391 // Armv8.5-A Memory Tagging Extension
4392 class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn,
4393 string asm_opnds, string cstr, dag oops, dag iops>
4394 : I<oops, iops, asm_insn, asm_opnds, cstr, []>,
4398 let Inst{31-24} = 0b11011001;
4399 let Inst{23-22} = opc1;
4401 // Inst{20-12} defined by subclass
4402 let Inst{11-10} = opc2;
4404 // Inst{4-0} defined by subclass
4407 class MemTagVector<bit Load, string asm_insn, string asm_opnds,
4409 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,
4413 let Inst{20-12} = 0b000000000;
4419 class MemTagLoad<string asm_insn, string asm_opnds>
4420 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback",
4421 (outs GPR64:$wback),
4422 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> {
4426 let Inst{20-12} = offset;
4432 class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn,
4433 string asm_opnds, string cstr, dag oops, dag iops>
4434 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> {
4438 let Inst{20-12} = offset;
4444 multiclass MemTagStore<bits<2> opc1, string insn> {
4446 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",
4447 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4449 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",
4451 (outs GPR64sp:$wback),
4452 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4454 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",
4456 (outs GPR64sp:$wback),
4457 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
4459 def : InstAlias<insn # "\t$Rt, [$Rn]",
4460 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>;
4464 // Exception generation
4467 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
4468 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
4469 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>,
4472 let Inst{31-24} = 0b11010100;
4473 let Inst{23-21} = op1;
4474 let Inst{20-5} = imm;
4475 let Inst{4-2} = 0b000;
4480 // UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm.
4482 let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in {
4483 class UDFType<bits<16> opc, string asm>
4484 : I<(outs), (ins uimm16:$imm),
4485 asm, "\t$imm", "", []>,
4488 let Inst{31-16} = opc;
4489 let Inst{15-0} = imm;
4492 let Predicates = [HasFPARMv8] in {
4495 // Floating point to integer conversion
4498 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
4499 RegisterClass srcType, RegisterClass dstType,
4500 string asm, list<dag> pattern>
4501 : I<(outs dstType:$Rd), (ins srcType:$Rn),
4502 asm, "\t$Rd, $Rn", "", pattern>,
4503 Sched<[WriteFCvt]> {
4506 let Inst{30-29} = 0b00;
4507 let Inst{28-24} = 0b11110;
4508 let Inst{23-22} = type;
4510 let Inst{20-19} = rmode;
4511 let Inst{18-16} = opcode;
4512 let Inst{15-10} = 0;
4517 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4518 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
4519 RegisterClass srcType, RegisterClass dstType,
4520 Operand immType, string asm, list<dag> pattern>
4521 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4522 asm, "\t$Rd, $Rn, $scale", "", pattern>,
4523 Sched<[WriteFCvt]> {
4527 let Inst{30-29} = 0b00;
4528 let Inst{28-24} = 0b11110;
4529 let Inst{23-22} = type;
4531 let Inst{20-19} = rmode;
4532 let Inst{18-16} = opcode;
4533 let Inst{15-10} = scale;
4538 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
4539 SDPatternOperator OpN> {
4540 // Unscaled half-precision to 32-bit
4541 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
4542 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4543 let Inst{31} = 0; // 32-bit GPR flag
4544 let Predicates = [HasFullFP16];
4547 // Unscaled half-precision to 64-bit
4548 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
4549 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> {
4550 let Inst{31} = 1; // 64-bit GPR flag
4551 let Predicates = [HasFullFP16];
4554 // Unscaled single-precision to 32-bit
4555 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
4556 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
4557 let Inst{31} = 0; // 32-bit GPR flag
4560 // Unscaled single-precision to 64-bit
4561 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
4562 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
4563 let Inst{31} = 1; // 64-bit GPR flag
4566 // Unscaled double-precision to 32-bit
4567 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
4568 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4569 let Inst{31} = 0; // 32-bit GPR flag
4572 // Unscaled double-precision to 64-bit
4573 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
4574 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4575 let Inst{31} = 1; // 64-bit GPR flag
4579 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
4580 SDPatternOperator OpN> {
4581 // Scaled half-precision to 32-bit
4582 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
4583 fixedpoint_f16_i32, asm,
4584 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn),
4585 fixedpoint_f16_i32:$scale)))]> {
4586 let Inst{31} = 0; // 32-bit GPR flag
4588 let Predicates = [HasFullFP16];
4591 // Scaled half-precision to 64-bit
4592 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
4593 fixedpoint_f16_i64, asm,
4594 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn),
4595 fixedpoint_f16_i64:$scale)))]> {
4596 let Inst{31} = 1; // 64-bit GPR flag
4597 let Predicates = [HasFullFP16];
4600 // Scaled single-precision to 32-bit
4601 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
4602 fixedpoint_f32_i32, asm,
4603 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
4604 fixedpoint_f32_i32:$scale)))]> {
4605 let Inst{31} = 0; // 32-bit GPR flag
4609 // Scaled single-precision to 64-bit
4610 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
4611 fixedpoint_f32_i64, asm,
4612 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
4613 fixedpoint_f32_i64:$scale)))]> {
4614 let Inst{31} = 1; // 64-bit GPR flag
4617 // Scaled double-precision to 32-bit
4618 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
4619 fixedpoint_f64_i32, asm,
4620 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
4621 fixedpoint_f64_i32:$scale)))]> {
4622 let Inst{31} = 0; // 32-bit GPR flag
4626 // Scaled double-precision to 64-bit
4627 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
4628 fixedpoint_f64_i64, asm,
4629 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
4630 fixedpoint_f64_i64:$scale)))]> {
4631 let Inst{31} = 1; // 64-bit GPR flag
4636 // Integer to floating point conversion
4639 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
4640 class BaseIntegerToFP<bit isUnsigned,
4641 RegisterClass srcType, RegisterClass dstType,
4642 Operand immType, string asm, list<dag> pattern>
4643 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4644 asm, "\t$Rd, $Rn, $scale", "", pattern>,
4645 Sched<[WriteFCvt]> {
4649 let Inst{30-24} = 0b0011110;
4650 let Inst{21-17} = 0b00001;
4651 let Inst{16} = isUnsigned;
4652 let Inst{15-10} = scale;
4657 class BaseIntegerToFPUnscaled<bit isUnsigned,
4658 RegisterClass srcType, RegisterClass dstType,
4659 ValueType dvt, string asm, SDPatternOperator node>
4660 : I<(outs dstType:$Rd), (ins srcType:$Rn),
4661 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
4662 Sched<[WriteFCvt]> {
4666 let Inst{30-24} = 0b0011110;
4667 let Inst{21-17} = 0b10001;
4668 let Inst{16} = isUnsigned;
4669 let Inst{15-10} = 0b000000;
4674 multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> {
4676 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
4677 let Inst{31} = 0; // 32-bit GPR flag
4678 let Inst{23-22} = 0b11; // 16-bit FPR flag
4679 let Predicates = [HasFullFP16];
4682 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
4683 let Inst{31} = 0; // 32-bit GPR flag
4684 let Inst{23-22} = 0b00; // 32-bit FPR flag
4687 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
4688 let Inst{31} = 0; // 32-bit GPR flag
4689 let Inst{23-22} = 0b01; // 64-bit FPR flag
4692 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
4693 let Inst{31} = 1; // 64-bit GPR flag
4694 let Inst{23-22} = 0b11; // 16-bit FPR flag
4695 let Predicates = [HasFullFP16];
4698 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
4699 let Inst{31} = 1; // 64-bit GPR flag
4700 let Inst{23-22} = 0b00; // 32-bit FPR flag
4703 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
4704 let Inst{31} = 1; // 64-bit GPR flag
4705 let Inst{23-22} = 0b01; // 64-bit FPR flag
4709 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
4710 [(set (f16 FPR16:$Rd),
4711 (fdiv (node GPR32:$Rn),
4712 fixedpoint_f16_i32:$scale))]> {
4713 let Inst{31} = 0; // 32-bit GPR flag
4714 let Inst{23-22} = 0b11; // 16-bit FPR flag
4716 let Predicates = [HasFullFP16];
4719 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
4721 (fdiv (node GPR32:$Rn),
4722 fixedpoint_f32_i32:$scale))]> {
4723 let Inst{31} = 0; // 32-bit GPR flag
4724 let Inst{23-22} = 0b00; // 32-bit FPR flag
4728 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
4730 (fdiv (node GPR32:$Rn),
4731 fixedpoint_f64_i32:$scale))]> {
4732 let Inst{31} = 0; // 32-bit GPR flag
4733 let Inst{23-22} = 0b01; // 64-bit FPR flag
4737 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
4738 [(set (f16 FPR16:$Rd),
4739 (fdiv (node GPR64:$Rn),
4740 fixedpoint_f16_i64:$scale))]> {
4741 let Inst{31} = 1; // 64-bit GPR flag
4742 let Inst{23-22} = 0b11; // 16-bit FPR flag
4743 let Predicates = [HasFullFP16];
4746 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
4748 (fdiv (node GPR64:$Rn),
4749 fixedpoint_f32_i64:$scale))]> {
4750 let Inst{31} = 1; // 64-bit GPR flag
4751 let Inst{23-22} = 0b00; // 32-bit FPR flag
4754 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
4756 (fdiv (node GPR64:$Rn),
4757 fixedpoint_f64_i64:$scale))]> {
4758 let Inst{31} = 1; // 64-bit GPR flag
4759 let Inst{23-22} = 0b01; // 64-bit FPR flag
4764 // Unscaled integer <-> floating point conversion (i.e. FMOV)
4767 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4768 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
4769 RegisterClass srcType, RegisterClass dstType,
4771 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
4772 // We use COPY_TO_REGCLASS for these bitconvert operations.
4773 // copyPhysReg() expands the resultant COPY instructions after
4774 // regalloc is done. This gives greater freedom for the allocator
4775 // and related passes (coalescing, copy propagation, et. al.) to
4776 // be more effective.
4777 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
4778 Sched<[WriteFCopy]> {
4781 let Inst{30-24} = 0b0011110;
4783 let Inst{20-19} = rmode;
4784 let Inst{18-16} = opcode;
4785 let Inst{15-10} = 0b000000;
4790 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4791 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
4792 RegisterClass srcType, RegisterOperand dstType, string asm,
4794 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4795 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
4796 Sched<[WriteFCopy]> {
4799 let Inst{30-23} = 0b00111101;
4801 let Inst{20-19} = rmode;
4802 let Inst{18-16} = opcode;
4803 let Inst{15-10} = 0b000000;
4807 let DecoderMethod = "DecodeFMOVLaneInstruction";
4810 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4811 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
4812 RegisterOperand srcType, RegisterClass dstType, string asm,
4814 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4815 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
4816 Sched<[WriteFCopy]> {
4819 let Inst{30-23} = 0b00111101;
4821 let Inst{20-19} = rmode;
4822 let Inst{18-16} = opcode;
4823 let Inst{15-10} = 0b000000;
4827 let DecoderMethod = "DecodeFMOVLaneInstruction";
4831 multiclass UnscaledConversion<string asm> {
4832 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
4833 let Inst{31} = 0; // 32-bit GPR flag
4834 let Inst{23-22} = 0b11; // 16-bit FPR flag
4835 let Predicates = [HasFullFP16];
4838 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
4839 let Inst{31} = 1; // 64-bit GPR flag
4840 let Inst{23-22} = 0b11; // 16-bit FPR flag
4841 let Predicates = [HasFullFP16];
4844 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
4845 let Inst{31} = 0; // 32-bit GPR flag
4846 let Inst{23-22} = 0b00; // 32-bit FPR flag
4849 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
4850 let Inst{31} = 1; // 64-bit GPR flag
4851 let Inst{23-22} = 0b01; // 64-bit FPR flag
4854 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
4855 let Inst{31} = 0; // 32-bit GPR flag
4856 let Inst{23-22} = 0b11; // 16-bit FPR flag
4857 let Predicates = [HasFullFP16];
4860 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
4861 let Inst{31} = 1; // 64-bit GPR flag
4862 let Inst{23-22} = 0b11; // 16-bit FPR flag
4863 let Predicates = [HasFullFP16];
4866 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
4867 let Inst{31} = 0; // 32-bit GPR flag
4868 let Inst{23-22} = 0b00; // 32-bit FPR flag
4871 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
4872 let Inst{31} = 1; // 64-bit GPR flag
4873 let Inst{23-22} = 0b01; // 64-bit FPR flag
4876 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
4882 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
4890 // Floating point conversion
4893 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
4894 RegisterClass srcType, string asm, list<dag> pattern>
4895 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
4896 Sched<[WriteFCvt]> {
4899 let Inst{31-24} = 0b00011110;
4900 let Inst{23-22} = type;
4901 let Inst{21-17} = 0b10001;
4902 let Inst{16-15} = opcode;
4903 let Inst{14-10} = 0b10000;
4908 multiclass FPConversion<string asm> {
4909 // Double-precision to Half-precision
4910 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4911 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>;
4913 // Double-precision to Single-precision
4914 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4915 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;
4917 // Half-precision to Double-precision
4918 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
4919 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
4921 // Half-precision to Single-precision
4922 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
4923 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
4925 // Single-precision to Double-precision
4926 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
4927 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
4929 // Single-precision to Half-precision
4930 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4931 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>;
4935 // Single operand floating point data processing
4938 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4939 class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype,
4940 ValueType vt, string asm, SDPatternOperator node>
4941 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
4942 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
4946 let Inst{31-24} = 0b00011110;
4948 let Inst{20-15} = opcode;
4949 let Inst{14-10} = 0b10000;
4954 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4955 SDPatternOperator node = null_frag> {
4957 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> {
4958 let Inst{23-22} = 0b11; // 16-bit size flag
4959 let Predicates = [HasFullFP16];
4962 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {
4963 let Inst{23-22} = 0b00; // 32-bit size flag
4966 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {
4967 let Inst{23-22} = 0b01; // 64-bit size flag
4971 multiclass SingleOperandFPNo16<bits<6> opcode, string asm,
4972 SDPatternOperator node = null_frag>{
4974 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4975 let Inst{23-22} = 0b00; // 32-bit registers
4978 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4979 let Inst{23-22} = 0b01; // 64-bit registers
4983 // FRInt[32|64][Z|N] instructions
4984 multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> :
4985 SingleOperandFPNo16<{0b0100,opcode}, asm, node>;
4988 // Two operand floating point data processing
4991 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4992 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4993 string asm, list<dag> pat>
4994 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4995 asm, "\t$Rd, $Rn, $Rm", "", pat>,
5000 let Inst{31-24} = 0b00011110;
5002 let Inst{20-16} = Rm;
5003 let Inst{15-12} = opcode;
5004 let Inst{11-10} = 0b10;
5009 multiclass TwoOperandFPData<bits<4> opcode, string asm,
5010 SDPatternOperator node = null_frag> {
5011 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
5012 [(set (f16 FPR16:$Rd),
5013 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
5014 let Inst{23-22} = 0b11; // 16-bit size flag
5015 let Predicates = [HasFullFP16];
5018 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
5019 [(set (f32 FPR32:$Rd),
5020 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
5021 let Inst{23-22} = 0b00; // 32-bit size flag
5024 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
5025 [(set (f64 FPR64:$Rd),
5026 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
5027 let Inst{23-22} = 0b01; // 64-bit size flag
5031 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
5032 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
5033 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> {
5034 let Inst{23-22} = 0b11; // 16-bit size flag
5035 let Predicates = [HasFullFP16];
5038 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
5039 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
5040 let Inst{23-22} = 0b00; // 32-bit size flag
5043 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
5044 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
5045 let Inst{23-22} = 0b01; // 64-bit size flag
5051 // Three operand floating point data processing
5054 class BaseThreeOperandFPData<bit isNegated, bit isSub,
5055 RegisterClass regtype, string asm, list<dag> pat>
5056 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
5057 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
5058 Sched<[WriteFMul]> {
5063 let Inst{31-24} = 0b00011111;
5064 let Inst{21} = isNegated;
5065 let Inst{20-16} = Rm;
5066 let Inst{15} = isSub;
5067 let Inst{14-10} = Ra;
5072 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
5073 SDPatternOperator node> {
5074 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
5075 [(set (f16 FPR16:$Rd),
5076 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
5077 let Inst{23-22} = 0b11; // 16-bit size flag
5078 let Predicates = [HasFullFP16];
5081 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
5083 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
5084 let Inst{23-22} = 0b00; // 32-bit size flag
5087 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
5089 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
5090 let Inst{23-22} = 0b01; // 64-bit size flag
5095 // Floating point data comparisons
5098 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5099 class BaseOneOperandFPComparison<bit signalAllNans,
5100 RegisterClass regtype, string asm,
5102 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
5103 Sched<[WriteFCmp]> {
5105 let Inst{31-24} = 0b00011110;
5108 let Inst{15-10} = 0b001000;
5110 let Inst{4} = signalAllNans;
5111 let Inst{3-0} = 0b1000;
5113 // Rm should be 0b00000 canonically, but we need to accept any value.
5114 let PostEncoderMethod = "fixOneOperandFPComparison";
5117 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5118 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
5119 string asm, list<dag> pat>
5120 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
5121 Sched<[WriteFCmp]> {
5124 let Inst{31-24} = 0b00011110;
5126 let Inst{20-16} = Rm;
5127 let Inst{15-10} = 0b001000;
5129 let Inst{4} = signalAllNans;
5130 let Inst{3-0} = 0b0000;
5133 multiclass FPComparison<bit signalAllNans, string asm,
5134 SDPatternOperator OpNode = null_frag> {
5135 let Defs = [NZCV] in {
5136 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
5137 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> {
5138 let Inst{23-22} = 0b11;
5139 let Predicates = [HasFullFP16];
5142 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
5143 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
5144 let Inst{23-22} = 0b11;
5145 let Predicates = [HasFullFP16];
5148 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
5149 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
5150 let Inst{23-22} = 0b00;
5153 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
5154 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
5155 let Inst{23-22} = 0b00;
5158 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
5159 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
5160 let Inst{23-22} = 0b01;
5163 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
5164 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
5165 let Inst{23-22} = 0b01;
5171 // Floating point conditional comparisons
5174 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5175 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
5176 string mnemonic, list<dag> pat>
5177 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
5178 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
5179 Sched<[WriteFCmp]> {
5188 let Inst{31-24} = 0b00011110;
5190 let Inst{20-16} = Rm;
5191 let Inst{15-12} = cond;
5192 let Inst{11-10} = 0b01;
5194 let Inst{4} = signalAllNans;
5195 let Inst{3-0} = nzcv;
5198 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
5199 SDPatternOperator OpNode = null_frag> {
5200 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,
5201 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),
5202 (i32 imm:$cond), NZCV))]> {
5203 let Inst{23-22} = 0b11;
5204 let Predicates = [HasFullFP16];
5207 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
5208 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
5209 (i32 imm:$cond), NZCV))]> {
5210 let Inst{23-22} = 0b00;
5213 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
5214 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
5215 (i32 imm:$cond), NZCV))]> {
5216 let Inst{23-22} = 0b01;
5221 // Floating point conditional select
5224 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
5225 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
5226 asm, "\t$Rd, $Rn, $Rm, $cond", "",
5228 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
5229 (i32 imm:$cond), NZCV))]>,
5236 let Inst{31-24} = 0b00011110;
5238 let Inst{20-16} = Rm;
5239 let Inst{15-12} = cond;
5240 let Inst{11-10} = 0b11;
5245 multiclass FPCondSelect<string asm> {
5246 let Uses = [NZCV] in {
5247 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
5248 let Inst{23-22} = 0b11;
5249 let Predicates = [HasFullFP16];
5252 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
5253 let Inst{23-22} = 0b00;
5256 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
5257 let Inst{23-22} = 0b01;
5263 // Floating move immediate
5266 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
5267 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
5268 [(set regtype:$Rd, fpimmtype:$imm)]>,
5269 Sched<[WriteFImm]> {
5272 let Inst{31-24} = 0b00011110;
5274 let Inst{20-13} = imm;
5275 let Inst{12-5} = 0b10000000;
5279 multiclass FPMoveImmediate<string asm> {
5280 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
5281 let Inst{23-22} = 0b11;
5282 let Predicates = [HasFullFP16];
5285 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
5286 let Inst{23-22} = 0b00;
5289 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
5290 let Inst{23-22} = 0b01;
5293 } // end of 'let Predicates = [HasFPARMv8]'
5295 //----------------------------------------------------------------------------
5297 //----------------------------------------------------------------------------
5299 let Predicates = [HasNEON] in {
5301 //----------------------------------------------------------------------------
5302 // AdvSIMD three register vector instructions
5303 //----------------------------------------------------------------------------
5305 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5306 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
5307 RegisterOperand regtype, string asm, string kind,
5309 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5310 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5311 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
5319 let Inst{28-24} = 0b01110;
5320 let Inst{23-21} = size;
5321 let Inst{20-16} = Rm;
5322 let Inst{15-11} = opcode;
5328 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5329 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
5330 RegisterOperand regtype, string asm, string kind,
5332 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
5333 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5334 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5342 let Inst{28-24} = 0b01110;
5343 let Inst{23-21} = size;
5344 let Inst{20-16} = Rm;
5345 let Inst{15-11} = opcode;
5351 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5352 class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern>
5353 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>,
5356 multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> {
5357 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64,
5358 [(set (v8i8 V64:$dst),
5359 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5360 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128,
5361 [(set (v16i8 V128:$dst),
5362 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5363 (v16i8 V128:$Rm)))]>;
5365 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5367 (!cast<Instruction>(NAME#"v8i8")
5368 V64:$LHS, V64:$MHS, V64:$RHS)>;
5369 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5371 (!cast<Instruction>(NAME#"v8i8")
5372 V64:$LHS, V64:$MHS, V64:$RHS)>;
5373 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5375 (!cast<Instruction>(NAME#"v8i8")
5376 V64:$LHS, V64:$MHS, V64:$RHS)>;
5378 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5379 (v8i16 V128:$RHS))),
5380 (!cast<Instruction>(NAME#"v16i8")
5381 V128:$LHS, V128:$MHS, V128:$RHS)>;
5382 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5383 (v4i32 V128:$RHS))),
5384 (!cast<Instruction>(NAME#"v16i8")
5385 V128:$LHS, V128:$MHS, V128:$RHS)>;
5386 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5387 (v2i64 V128:$RHS))),
5388 (!cast<Instruction>(NAME#"v16i8")
5389 V128:$LHS, V128:$MHS, V128:$RHS)>;
5392 // All operand sizes distinguished in the encoding.
5393 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
5394 SDPatternOperator OpNode> {
5395 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5397 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5398 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5400 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5401 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5403 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5404 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5406 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5407 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5409 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5410 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5412 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5413 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
5415 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5418 multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> {
5419 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)),
5420 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>;
5421 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5422 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>;
5423 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5424 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>;
5426 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)),
5427 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>;
5428 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5429 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>;
5430 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5431 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>;
5432 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5433 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>;
5436 // As above, but D sized elements unsupported.
5437 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
5438 SDPatternOperator OpNode> {
5439 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5441 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
5442 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5444 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
5445 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5447 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
5448 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5450 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
5451 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5453 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
5454 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5456 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
5459 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
5460 SDPatternOperator OpNode> {
5461 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
5463 [(set (v8i8 V64:$dst),
5464 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5465 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
5467 [(set (v16i8 V128:$dst),
5468 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5469 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
5471 [(set (v4i16 V64:$dst),
5472 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5473 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
5475 [(set (v8i16 V128:$dst),
5476 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5477 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
5479 [(set (v2i32 V64:$dst),
5480 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5481 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
5483 [(set (v4i32 V128:$dst),
5484 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5487 // As above, but only B sized elements supported.
5488 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
5489 SDPatternOperator OpNode> {
5490 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
5492 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5493 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
5495 [(set (v16i8 V128:$Rd),
5496 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
5499 // As above, but only floating point elements supported.
5500 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
5501 string asm, SDPatternOperator OpNode> {
5502 let Predicates = [HasNEON, HasFullFP16] in {
5503 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5505 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5506 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5508 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5509 } // Predicates = [HasNEON, HasFullFP16]
5510 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5512 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5513 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5515 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5516 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5518 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5521 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
5523 SDPatternOperator OpNode> {
5524 let Predicates = [HasNEON, HasFullFP16] in {
5525 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
5527 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5528 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
5530 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5531 } // Predicates = [HasNEON, HasFullFP16]
5532 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
5534 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5535 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
5537 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5538 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
5540 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5543 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
5544 string asm, SDPatternOperator OpNode> {
5545 let Predicates = [HasNEON, HasFullFP16] in {
5546 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
5548 [(set (v4f16 V64:$dst),
5549 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
5550 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
5552 [(set (v8f16 V128:$dst),
5553 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
5554 } // Predicates = [HasNEON, HasFullFP16]
5555 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
5557 [(set (v2f32 V64:$dst),
5558 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
5559 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
5561 [(set (v4f32 V128:$dst),
5562 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
5563 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
5565 [(set (v2f64 V128:$dst),
5566 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
5569 // As above, but D and B sized elements unsupported.
5570 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
5571 SDPatternOperator OpNode> {
5572 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
5574 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5575 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
5577 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5578 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
5580 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5581 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
5583 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5586 // Logical three vector ops share opcode bits, and only use B sized elements.
5587 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
5588 SDPatternOperator OpNode = null_frag> {
5589 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
5591 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
5592 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
5594 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
5596 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
5597 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5598 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5599 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5600 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
5601 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5603 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5604 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5605 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5606 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5607 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5608 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5611 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
5612 string asm, SDPatternOperator OpNode = null_frag> {
5613 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
5615 [(set (v8i8 V64:$dst),
5616 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5617 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
5619 [(set (v16i8 V128:$dst),
5620 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5621 (v16i8 V128:$Rm)))]>;
5623 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5625 (!cast<Instruction>(NAME#"v8i8")
5626 V64:$LHS, V64:$MHS, V64:$RHS)>;
5627 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5629 (!cast<Instruction>(NAME#"v8i8")
5630 V64:$LHS, V64:$MHS, V64:$RHS)>;
5631 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5633 (!cast<Instruction>(NAME#"v8i8")
5634 V64:$LHS, V64:$MHS, V64:$RHS)>;
5636 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5637 (v8i16 V128:$RHS))),
5638 (!cast<Instruction>(NAME#"v16i8")
5639 V128:$LHS, V128:$MHS, V128:$RHS)>;
5640 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5641 (v4i32 V128:$RHS))),
5642 (!cast<Instruction>(NAME#"v16i8")
5643 V128:$LHS, V128:$MHS, V128:$RHS)>;
5644 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5645 (v2i64 V128:$RHS))),
5646 (!cast<Instruction>(NAME#"v16i8")
5647 V128:$LHS, V128:$MHS, V128:$RHS)>;
5650 // ARMv8.2-A Dot Product Instructions (Vector): These instructions extract
5651 // bytes from S-sized elements.
5652 class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1,
5653 string kind2, RegisterOperand RegType,
5654 ValueType AccumType, ValueType InputType,
5655 SDPatternOperator OpNode> :
5656 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1,
5657 [(set (AccumType RegType:$dst),
5658 (OpNode (AccumType RegType:$Rd),
5659 (InputType RegType:$Rn),
5660 (InputType RegType:$Rm)))]> {
5661 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5664 multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> {
5665 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64,
5666 v2i32, v8i8, OpNode>;
5667 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128,
5668 v4i32, v16i8, OpNode>;
5671 // ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions
5672 // select inputs from 4H vectors and accumulate outputs to a 2S vector (or from
5673 // 8H to 4S, when Q=1).
5674 class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1,
5675 string kind2, RegisterOperand RegType,
5676 ValueType AccumType, ValueType InputType,
5677 SDPatternOperator OpNode> :
5678 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1,
5679 [(set (AccumType RegType:$dst),
5680 (OpNode (AccumType RegType:$Rd),
5681 (InputType RegType:$Rn),
5682 (InputType RegType:$Rm)))]> {
5683 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
5687 multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,
5688 SDPatternOperator OpNode> {
5689 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64,
5690 v2f32, v4f16, OpNode>;
5691 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128,
5692 v4f32, v8f16, OpNode>;
5696 //----------------------------------------------------------------------------
5697 // AdvSIMD two register vector instructions.
5698 //----------------------------------------------------------------------------
5700 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5701 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5702 bits<2> size2, RegisterOperand regtype, string asm,
5703 string dstkind, string srckind, list<dag> pattern>
5704 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5705 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5706 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
5713 let Inst{28-24} = 0b01110;
5714 let Inst{23-22} = size;
5716 let Inst{20-19} = size2;
5717 let Inst{18-17} = 0b00;
5718 let Inst{16-12} = opcode;
5719 let Inst{11-10} = 0b10;
5724 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5725 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5726 bits<2> size2, RegisterOperand regtype,
5727 string asm, string dstkind, string srckind,
5729 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
5730 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5731 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5738 let Inst{28-24} = 0b01110;
5739 let Inst{23-22} = size;
5741 let Inst{20-19} = size2;
5742 let Inst{18-17} = 0b00;
5743 let Inst{16-12} = opcode;
5744 let Inst{11-10} = 0b10;
5749 // Supports B, H, and S element sizes.
5750 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
5751 SDPatternOperator OpNode> {
5752 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5754 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5755 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5756 asm, ".16b", ".16b",
5757 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5758 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5760 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5761 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5763 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5764 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5766 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5767 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5769 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5772 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
5773 RegisterOperand regtype, string asm, string dstkind,
5774 string srckind, string amount>
5775 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
5776 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
5777 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
5783 let Inst{29-24} = 0b101110;
5784 let Inst{23-22} = size;
5785 let Inst{21-10} = 0b100001001110;
5790 multiclass SIMDVectorLShiftLongBySizeBHS {
5791 let hasSideEffects = 0 in {
5792 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
5793 "shll", ".8h", ".8b", "8">;
5794 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
5795 "shll2", ".8h", ".16b", "8">;
5796 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
5797 "shll", ".4s", ".4h", "16">;
5798 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
5799 "shll2", ".4s", ".8h", "16">;
5800 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
5801 "shll", ".2d", ".2s", "32">;
5802 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
5803 "shll2", ".2d", ".4s", "32">;
5807 // Supports all element sizes.
5808 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
5809 SDPatternOperator OpNode> {
5810 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5812 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5813 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5815 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5816 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5818 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5819 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5821 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5822 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5824 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5825 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5827 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5830 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
5831 SDPatternOperator OpNode> {
5832 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5834 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
5836 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5838 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
5839 (v16i8 V128:$Rn)))]>;
5840 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5842 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
5843 (v4i16 V64:$Rn)))]>;
5844 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5846 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
5847 (v8i16 V128:$Rn)))]>;
5848 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5850 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
5851 (v2i32 V64:$Rn)))]>;
5852 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5854 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
5855 (v4i32 V128:$Rn)))]>;
5858 // Supports all element sizes, except 1xD.
5859 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
5860 SDPatternOperator OpNode> {
5861 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5863 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
5864 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5865 asm, ".16b", ".16b",
5866 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
5867 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5869 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
5870 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5872 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
5873 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5875 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
5876 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5878 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
5879 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
5881 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
5884 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
5885 SDPatternOperator OpNode = null_frag> {
5886 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5888 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5889 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5890 asm, ".16b", ".16b",
5891 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5892 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5894 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5895 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5897 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5898 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5900 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5901 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5903 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5904 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5906 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5910 // Supports only B element sizes.
5911 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5912 SDPatternOperator OpNode> {
5913 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5915 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5916 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5917 asm, ".16b", ".16b",
5918 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5922 // Supports only B and H element sizes.
5923 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5924 SDPatternOperator OpNode> {
5925 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5927 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5928 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5929 asm, ".16b", ".16b",
5930 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5931 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5933 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5934 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5936 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5939 // Supports H, S and D element sizes, uses high bit of the size field
5940 // as an extra opcode bit.
5941 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5942 SDPatternOperator OpNode> {
5943 let Predicates = [HasNEON, HasFullFP16] in {
5944 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5946 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5947 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5949 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5950 } // Predicates = [HasNEON, HasFullFP16]
5951 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5953 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5954 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5956 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5957 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5959 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5962 // Supports only S and D element sizes
5963 multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm,
5964 SDPatternOperator OpNode = null_frag> {
5966 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64,
5968 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5969 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,
5971 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5972 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,
5974 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5977 multiclass FRIntNNTVector<bit U, bit op, string asm,
5978 SDPatternOperator OpNode = null_frag> :
5979 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>;
5981 // Supports only S element size.
5982 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5983 SDPatternOperator OpNode> {
5984 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5986 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5987 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5989 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5993 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5994 SDPatternOperator OpNode> {
5995 let Predicates = [HasNEON, HasFullFP16] in {
5996 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5998 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5999 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6001 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
6002 } // Predicates = [HasNEON, HasFullFP16]
6003 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6005 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
6006 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6008 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
6009 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
6011 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6014 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
6015 SDPatternOperator OpNode> {
6016 let Predicates = [HasNEON, HasFullFP16] in {
6017 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
6019 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
6020 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
6022 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6023 } // Predicates = [HasNEON, HasFullFP16]
6024 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
6026 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
6027 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
6029 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6030 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
6032 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
6036 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
6037 RegisterOperand inreg, RegisterOperand outreg,
6038 string asm, string outkind, string inkind,
6040 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
6041 "{\t$Rd" # outkind # ", $Rn" # inkind #
6042 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
6049 let Inst{28-24} = 0b01110;
6050 let Inst{23-22} = size;
6051 let Inst{21-17} = 0b10000;
6052 let Inst{16-12} = opcode;
6053 let Inst{11-10} = 0b10;
6058 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
6059 RegisterOperand inreg, RegisterOperand outreg,
6060 string asm, string outkind, string inkind,
6062 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
6063 "{\t$Rd" # outkind # ", $Rn" # inkind #
6064 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
6071 let Inst{28-24} = 0b01110;
6072 let Inst{23-22} = size;
6073 let Inst{21-17} = 0b10000;
6074 let Inst{16-12} = opcode;
6075 let Inst{11-10} = 0b10;
6080 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
6081 SDPatternOperator OpNode> {
6082 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
6084 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
6085 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
6086 asm#"2", ".16b", ".8h", []>;
6087 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
6089 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
6090 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
6091 asm#"2", ".8h", ".4s", []>;
6092 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
6094 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
6095 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
6096 asm#"2", ".4s", ".2d", []>;
6098 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
6099 (!cast<Instruction>(NAME # "v16i8")
6100 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6101 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
6102 (!cast<Instruction>(NAME # "v8i16")
6103 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6104 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
6105 (!cast<Instruction>(NAME # "v4i32")
6106 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6109 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
6110 bits<5> opcode, RegisterOperand regtype, string asm,
6111 string kind, string zero, ValueType dty,
6112 ValueType sty, SDNode OpNode>
6113 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6114 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
6115 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
6116 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
6123 let Inst{28-24} = 0b01110;
6124 let Inst{23-22} = size;
6126 let Inst{20-19} = size2;
6127 let Inst{18-17} = 0b00;
6128 let Inst{16-12} = opcode;
6129 let Inst{11-10} = 0b10;
6134 // Comparisons support all element sizes, except 1xD.
6135 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
6137 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
6139 v8i8, v8i8, OpNode>;
6140 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
6142 v16i8, v16i8, OpNode>;
6143 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
6145 v4i16, v4i16, OpNode>;
6146 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
6148 v8i16, v8i16, OpNode>;
6149 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
6151 v2i32, v2i32, OpNode>;
6152 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
6154 v4i32, v4i32, OpNode>;
6155 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
6157 v2i64, v2i64, OpNode>;
6160 // FP Comparisons support only S and D element sizes (and H for v8.2a).
6161 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
6162 string asm, SDNode OpNode> {
6164 let Predicates = [HasNEON, HasFullFP16] in {
6165 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
6167 v4i16, v4f16, OpNode>;
6168 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
6170 v8i16, v8f16, OpNode>;
6171 } // Predicates = [HasNEON, HasFullFP16]
6172 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
6174 v2i32, v2f32, OpNode>;
6175 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
6177 v4i32, v4f32, OpNode>;
6178 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
6180 v2i64, v2f64, OpNode>;
6182 let Predicates = [HasNEON, HasFullFP16] in {
6183 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
6184 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6185 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
6186 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6188 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
6189 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6190 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
6191 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6192 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
6193 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6194 let Predicates = [HasNEON, HasFullFP16] in {
6195 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
6196 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
6197 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
6198 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
6200 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
6201 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
6202 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
6203 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
6204 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
6205 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
6208 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6209 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
6210 RegisterOperand outtype, RegisterOperand intype,
6211 string asm, string VdTy, string VnTy,
6213 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
6214 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
6221 let Inst{28-24} = 0b01110;
6222 let Inst{23-22} = size;
6223 let Inst{21-17} = 0b10000;
6224 let Inst{16-12} = opcode;
6225 let Inst{11-10} = 0b10;
6230 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
6231 RegisterOperand outtype, RegisterOperand intype,
6232 string asm, string VdTy, string VnTy,
6234 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
6235 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
6242 let Inst{28-24} = 0b01110;
6243 let Inst{23-22} = size;
6244 let Inst{21-17} = 0b10000;
6245 let Inst{16-12} = opcode;
6246 let Inst{11-10} = 0b10;
6251 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
6252 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
6253 asm, ".4s", ".4h", []>;
6254 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
6255 asm#"2", ".4s", ".8h", []>;
6256 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
6257 asm, ".2d", ".2s", []>;
6258 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
6259 asm#"2", ".2d", ".4s", []>;
6262 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
6263 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
6264 asm, ".4h", ".4s", []>;
6265 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
6266 asm#"2", ".8h", ".4s", []>;
6267 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6268 asm, ".2s", ".2d", []>;
6269 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6270 asm#"2", ".4s", ".2d", []>;
6273 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
6275 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
6277 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
6278 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
6279 asm#"2", ".4s", ".2d", []>;
6281 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
6282 (!cast<Instruction>(NAME # "v4f32")
6283 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
6286 //----------------------------------------------------------------------------
6287 // AdvSIMD three register different-size vector instructions.
6288 //----------------------------------------------------------------------------
6290 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6291 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
6292 RegisterOperand outtype, RegisterOperand intype1,
6293 RegisterOperand intype2, string asm,
6294 string outkind, string inkind1, string inkind2,
6296 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
6297 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6298 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
6304 let Inst{30} = size{0};
6306 let Inst{28-24} = 0b01110;
6307 let Inst{23-22} = size{2-1};
6309 let Inst{20-16} = Rm;
6310 let Inst{15-12} = opcode;
6311 let Inst{11-10} = 0b00;
6316 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6317 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
6318 RegisterOperand outtype, RegisterOperand intype1,
6319 RegisterOperand intype2, string asm,
6320 string outkind, string inkind1, string inkind2,
6322 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
6323 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
6324 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
6330 let Inst{30} = size{0};
6332 let Inst{28-24} = 0b01110;
6333 let Inst{23-22} = size{2-1};
6335 let Inst{20-16} = Rm;
6336 let Inst{15-12} = opcode;
6337 let Inst{11-10} = 0b00;
6342 // FIXME: TableGen doesn't know how to deal with expanded types that also
6343 // change the element count (in this case, placing the results in
6344 // the high elements of the result register rather than the low
6345 // elements). Until that's fixed, we can't code-gen those.
6346 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
6348 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6350 asm, ".8b", ".8h", ".8h",
6351 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
6352 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6354 asm#"2", ".16b", ".8h", ".8h",
6356 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6358 asm, ".4h", ".4s", ".4s",
6359 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
6360 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6362 asm#"2", ".8h", ".4s", ".4s",
6364 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6366 asm, ".2s", ".2d", ".2d",
6367 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
6368 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6370 asm#"2", ".4s", ".2d", ".2d",
6374 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
6375 // a version attached to an instruction.
6376 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
6378 (!cast<Instruction>(NAME # "v8i16_v16i8")
6379 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6380 V128:$Rn, V128:$Rm)>;
6381 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
6383 (!cast<Instruction>(NAME # "v4i32_v8i16")
6384 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6385 V128:$Rn, V128:$Rm)>;
6386 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
6388 (!cast<Instruction>(NAME # "v2i64_v4i32")
6389 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6390 V128:$Rn, V128:$Rm)>;
6393 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
6395 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6397 asm, ".8h", ".8b", ".8b",
6398 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6399 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6401 asm#"2", ".8h", ".16b", ".16b", []>;
6402 let Predicates = [HasAES] in {
6403 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
6405 asm, ".1q", ".1d", ".1d", []>;
6406 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
6408 asm#"2", ".1q", ".2d", ".2d", []>;
6411 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
6412 (v8i8 (extract_high_v16i8 V128:$Rm)))),
6413 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
6416 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
6417 SDPatternOperator OpNode> {
6418 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6420 asm, ".4s", ".4h", ".4h",
6421 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6422 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6424 asm#"2", ".4s", ".8h", ".8h",
6425 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6426 (extract_high_v8i16 V128:$Rm)))]>;
6427 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6429 asm, ".2d", ".2s", ".2s",
6430 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6431 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6433 asm#"2", ".2d", ".4s", ".4s",
6434 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6435 (extract_high_v4i32 V128:$Rm)))]>;
6438 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
6439 SDPatternOperator OpNode = null_frag> {
6440 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6442 asm, ".8h", ".8b", ".8b",
6443 [(set (v8i16 V128:$Rd),
6444 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
6445 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6447 asm#"2", ".8h", ".16b", ".16b",
6448 [(set (v8i16 V128:$Rd),
6449 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6450 (extract_high_v16i8 V128:$Rm)))))]>;
6451 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6453 asm, ".4s", ".4h", ".4h",
6454 [(set (v4i32 V128:$Rd),
6455 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
6456 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6458 asm#"2", ".4s", ".8h", ".8h",
6459 [(set (v4i32 V128:$Rd),
6460 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6461 (extract_high_v8i16 V128:$Rm)))))]>;
6462 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6464 asm, ".2d", ".2s", ".2s",
6465 [(set (v2i64 V128:$Rd),
6466 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
6467 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6469 asm#"2", ".2d", ".4s", ".4s",
6470 [(set (v2i64 V128:$Rd),
6471 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6472 (extract_high_v4i32 V128:$Rm)))))]>;
6475 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
6477 SDPatternOperator OpNode> {
6478 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6480 asm, ".8h", ".8b", ".8b",
6481 [(set (v8i16 V128:$dst),
6482 (add (v8i16 V128:$Rd),
6483 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
6484 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6486 asm#"2", ".8h", ".16b", ".16b",
6487 [(set (v8i16 V128:$dst),
6488 (add (v8i16 V128:$Rd),
6489 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
6490 (extract_high_v16i8 V128:$Rm))))))]>;
6491 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6493 asm, ".4s", ".4h", ".4h",
6494 [(set (v4i32 V128:$dst),
6495 (add (v4i32 V128:$Rd),
6496 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
6497 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6499 asm#"2", ".4s", ".8h", ".8h",
6500 [(set (v4i32 V128:$dst),
6501 (add (v4i32 V128:$Rd),
6502 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
6503 (extract_high_v8i16 V128:$Rm))))))]>;
6504 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6506 asm, ".2d", ".2s", ".2s",
6507 [(set (v2i64 V128:$dst),
6508 (add (v2i64 V128:$Rd),
6509 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
6510 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6512 asm#"2", ".2d", ".4s", ".4s",
6513 [(set (v2i64 V128:$dst),
6514 (add (v2i64 V128:$Rd),
6515 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
6516 (extract_high_v4i32 V128:$Rm))))))]>;
6519 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
6520 SDPatternOperator OpNode = null_frag> {
6521 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6523 asm, ".8h", ".8b", ".8b",
6524 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6525 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6527 asm#"2", ".8h", ".16b", ".16b",
6528 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
6529 (extract_high_v16i8 V128:$Rm)))]>;
6530 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6532 asm, ".4s", ".4h", ".4h",
6533 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6534 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6536 asm#"2", ".4s", ".8h", ".8h",
6537 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
6538 (extract_high_v8i16 V128:$Rm)))]>;
6539 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6541 asm, ".2d", ".2s", ".2s",
6542 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6543 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6545 asm#"2", ".2d", ".4s", ".4s",
6546 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
6547 (extract_high_v4i32 V128:$Rm)))]>;
6550 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
6552 SDPatternOperator OpNode> {
6553 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
6555 asm, ".8h", ".8b", ".8b",
6556 [(set (v8i16 V128:$dst),
6557 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
6558 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
6560 asm#"2", ".8h", ".16b", ".16b",
6561 [(set (v8i16 V128:$dst),
6562 (OpNode (v8i16 V128:$Rd),
6563 (extract_high_v16i8 V128:$Rn),
6564 (extract_high_v16i8 V128:$Rm)))]>;
6565 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6567 asm, ".4s", ".4h", ".4h",
6568 [(set (v4i32 V128:$dst),
6569 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
6570 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6572 asm#"2", ".4s", ".8h", ".8h",
6573 [(set (v4i32 V128:$dst),
6574 (OpNode (v4i32 V128:$Rd),
6575 (extract_high_v8i16 V128:$Rn),
6576 (extract_high_v8i16 V128:$Rm)))]>;
6577 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6579 asm, ".2d", ".2s", ".2s",
6580 [(set (v2i64 V128:$dst),
6581 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
6582 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6584 asm#"2", ".2d", ".4s", ".4s",
6585 [(set (v2i64 V128:$dst),
6586 (OpNode (v2i64 V128:$Rd),
6587 (extract_high_v4i32 V128:$Rn),
6588 (extract_high_v4i32 V128:$Rm)))]>;
6591 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
6592 SDPatternOperator Accum> {
6593 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
6595 asm, ".4s", ".4h", ".4h",
6596 [(set (v4i32 V128:$dst),
6597 (Accum (v4i32 V128:$Rd),
6598 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6599 (v4i16 V64:$Rm)))))]>;
6600 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
6602 asm#"2", ".4s", ".8h", ".8h",
6603 [(set (v4i32 V128:$dst),
6604 (Accum (v4i32 V128:$Rd),
6605 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
6606 (extract_high_v8i16 V128:$Rm)))))]>;
6607 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
6609 asm, ".2d", ".2s", ".2s",
6610 [(set (v2i64 V128:$dst),
6611 (Accum (v2i64 V128:$Rd),
6612 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
6613 (v2i32 V64:$Rm)))))]>;
6614 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
6616 asm#"2", ".2d", ".4s", ".4s",
6617 [(set (v2i64 V128:$dst),
6618 (Accum (v2i64 V128:$Rd),
6619 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
6620 (extract_high_v4i32 V128:$Rm)))))]>;
6623 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
6624 SDPatternOperator OpNode> {
6625 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
6627 asm, ".8h", ".8h", ".8b",
6628 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
6629 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
6631 asm#"2", ".8h", ".8h", ".16b",
6632 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
6633 (extract_high_v16i8 V128:$Rm)))]>;
6634 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
6636 asm, ".4s", ".4s", ".4h",
6637 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
6638 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
6640 asm#"2", ".4s", ".4s", ".8h",
6641 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
6642 (extract_high_v8i16 V128:$Rm)))]>;
6643 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
6645 asm, ".2d", ".2d", ".2s",
6646 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
6647 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
6649 asm#"2", ".2d", ".2d", ".4s",
6650 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
6651 (extract_high_v4i32 V128:$Rm)))]>;
6654 //----------------------------------------------------------------------------
6655 // AdvSIMD bitwise extract from vector
6656 //----------------------------------------------------------------------------
6658 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
6659 string asm, string kind>
6660 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
6661 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
6662 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
6663 [(set (vty regtype:$Rd),
6664 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
6671 let Inst{30} = size;
6672 let Inst{29-21} = 0b101110000;
6673 let Inst{20-16} = Rm;
6675 let Inst{14-11} = imm;
6682 multiclass SIMDBitwiseExtract<string asm> {
6683 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
6686 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
6689 //----------------------------------------------------------------------------
6690 // AdvSIMD zip vector
6691 //----------------------------------------------------------------------------
6693 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
6694 string asm, string kind, SDNode OpNode, ValueType valty>
6695 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6696 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
6697 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
6698 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
6704 let Inst{30} = size{0};
6705 let Inst{29-24} = 0b001110;
6706 let Inst{23-22} = size{2-1};
6708 let Inst{20-16} = Rm;
6710 let Inst{14-12} = opc;
6711 let Inst{11-10} = 0b10;
6716 multiclass SIMDZipVector<bits<3>opc, string asm,
6718 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
6719 asm, ".8b", OpNode, v8i8>;
6720 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
6721 asm, ".16b", OpNode, v16i8>;
6722 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
6723 asm, ".4h", OpNode, v4i16>;
6724 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
6725 asm, ".8h", OpNode, v8i16>;
6726 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
6727 asm, ".2s", OpNode, v2i32>;
6728 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
6729 asm, ".4s", OpNode, v4i32>;
6730 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
6731 asm, ".2d", OpNode, v2i64>;
6733 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
6734 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
6735 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
6736 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
6737 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
6738 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
6739 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
6740 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
6741 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
6742 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
6745 //----------------------------------------------------------------------------
6746 // AdvSIMD three register scalar instructions
6747 //----------------------------------------------------------------------------
6749 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6750 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
6751 RegisterClass regtype, string asm,
6753 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6754 "\t$Rd, $Rn, $Rm", "", pattern>,
6759 let Inst{31-30} = 0b01;
6761 let Inst{28-24} = 0b11110;
6762 let Inst{23-21} = size;
6763 let Inst{20-16} = Rm;
6764 let Inst{15-11} = opcode;
6770 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6771 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
6772 dag oops, dag iops, string asm,
6774 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
6779 let Inst{31-30} = 0b01;
6781 let Inst{28-24} = 0b11110;
6782 let Inst{23-22} = size;
6784 let Inst{20-16} = Rm;
6785 let Inst{15-11} = opcode;
6791 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
6792 SDPatternOperator OpNode> {
6793 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6794 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6797 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
6798 SDPatternOperator OpNode> {
6799 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6800 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6801 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
6802 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6803 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
6805 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
6806 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
6807 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
6808 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
6811 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
6812 SDPatternOperator OpNode> {
6813 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
6814 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6815 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6818 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
6819 SDPatternOperator OpNode = null_frag> {
6820 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
6821 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
6823 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
6824 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
6828 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
6829 SDPatternOperator OpNode = null_frag> {
6830 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6831 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6832 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6833 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6834 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6835 let Predicates = [HasNEON, HasFullFP16] in {
6836 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6837 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>;
6838 } // Predicates = [HasNEON, HasFullFP16]
6841 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6842 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6845 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
6846 SDPatternOperator OpNode = null_frag> {
6847 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6848 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6849 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6850 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6851 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
6852 let Predicates = [HasNEON, HasFullFP16] in {
6853 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6855 } // Predicates = [HasNEON, HasFullFP16]
6858 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6859 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6862 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
6863 dag oops, dag iops, string asm, string cstr, list<dag> pat>
6864 : I<oops, iops, asm,
6865 "\t$Rd, $Rn, $Rm", cstr, pat>,
6870 let Inst{31-30} = 0b01;
6872 let Inst{28-24} = 0b11110;
6873 let Inst{23-22} = size;
6875 let Inst{20-16} = Rm;
6876 let Inst{15-11} = opcode;
6882 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6883 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
6884 SDPatternOperator OpNode = null_frag> {
6885 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6887 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
6888 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6890 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
6891 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6894 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6895 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
6896 SDPatternOperator OpNode = null_frag> {
6897 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6899 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
6900 asm, "$Rd = $dst", []>;
6901 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6903 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
6905 [(set (i64 FPR64:$dst),
6906 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6909 //----------------------------------------------------------------------------
6910 // AdvSIMD two register scalar instructions
6911 //----------------------------------------------------------------------------
6913 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6914 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6915 RegisterClass regtype, RegisterClass regtype2,
6916 string asm, list<dag> pat>
6917 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6918 "\t$Rd, $Rn", "", pat>,
6922 let Inst{31-30} = 0b01;
6924 let Inst{28-24} = 0b11110;
6925 let Inst{23-22} = size;
6927 let Inst{20-19} = size2;
6928 let Inst{18-17} = 0b00;
6929 let Inst{16-12} = opcode;
6930 let Inst{11-10} = 0b10;
6935 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6936 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6937 RegisterClass regtype, RegisterClass regtype2,
6938 string asm, list<dag> pat>
6939 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6940 "\t$Rd, $Rn", "$Rd = $dst", pat>,
6944 let Inst{31-30} = 0b01;
6946 let Inst{28-24} = 0b11110;
6947 let Inst{23-22} = size;
6948 let Inst{21-17} = 0b10000;
6949 let Inst{16-12} = opcode;
6950 let Inst{11-10} = 0b10;
6956 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6957 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6958 RegisterClass regtype, string asm, string zero>
6959 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6960 "\t$Rd, $Rn, #" # zero, "", []>,
6964 let Inst{31-30} = 0b01;
6966 let Inst{28-24} = 0b11110;
6967 let Inst{23-22} = size;
6969 let Inst{20-19} = size2;
6970 let Inst{18-17} = 0b00;
6971 let Inst{16-12} = opcode;
6972 let Inst{11-10} = 0b10;
6977 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6978 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6979 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6983 let Inst{31-17} = 0b011111100110000;
6984 let Inst{16-12} = opcode;
6985 let Inst{11-10} = 0b10;
6990 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6991 SDPatternOperator OpNode> {
6992 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6994 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6995 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6998 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6999 SDPatternOperator OpNode> {
7000 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
7001 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
7002 let Predicates = [HasNEON, HasFullFP16] in {
7003 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
7006 def : InstAlias<asm # "\t$Rd, $Rn, #0",
7007 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
7008 def : InstAlias<asm # "\t$Rd, $Rn, #0",
7009 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
7010 let Predicates = [HasNEON, HasFullFP16] in {
7011 def : InstAlias<asm # "\t$Rd, $Rn, #0",
7012 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
7015 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
7016 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
7019 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
7020 SDPatternOperator OpNode = null_frag> {
7021 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
7022 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
7024 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
7025 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
7028 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
7029 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
7030 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
7031 let Predicates = [HasNEON, HasFullFP16] in {
7032 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
7036 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
7037 SDPatternOperator OpNode> {
7038 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
7039 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
7040 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
7041 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
7042 let Predicates = [HasNEON, HasFullFP16] in {
7043 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
7044 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>;
7048 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
7049 SDPatternOperator OpNode = null_frag> {
7050 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7051 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
7052 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
7053 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
7054 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
7055 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
7056 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
7059 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
7060 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
7063 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
7065 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7066 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
7067 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
7068 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
7069 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
7070 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
7071 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
7074 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
7075 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
7080 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7081 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
7082 SDPatternOperator OpNode = null_frag> {
7083 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
7084 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
7085 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
7086 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
7089 //----------------------------------------------------------------------------
7090 // AdvSIMD scalar pairwise instructions
7091 //----------------------------------------------------------------------------
7093 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7094 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
7095 RegisterOperand regtype, RegisterOperand vectype,
7096 string asm, string kind>
7097 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7098 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
7102 let Inst{31-30} = 0b01;
7104 let Inst{28-24} = 0b11110;
7105 let Inst{23-22} = size;
7106 let Inst{21-17} = 0b11000;
7107 let Inst{16-12} = opcode;
7108 let Inst{11-10} = 0b10;
7113 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
7114 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
7118 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
7119 let Predicates = [HasNEON, HasFullFP16] in {
7120 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
7123 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
7125 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
7129 //----------------------------------------------------------------------------
7130 // AdvSIMD across lanes instructions
7131 //----------------------------------------------------------------------------
7133 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7134 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
7135 RegisterClass regtype, RegisterOperand vectype,
7136 string asm, string kind, list<dag> pattern>
7137 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
7138 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
7145 let Inst{28-24} = 0b01110;
7146 let Inst{23-22} = size;
7147 let Inst{21-17} = 0b11000;
7148 let Inst{16-12} = opcode;
7149 let Inst{11-10} = 0b10;
7154 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
7156 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
7158 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
7160 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
7162 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
7164 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
7168 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
7169 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
7171 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
7173 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
7175 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
7177 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
7181 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
7183 let Predicates = [HasNEON, HasFullFP16] in {
7184 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
7186 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>;
7187 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
7189 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>;
7190 } // Predicates = [HasNEON, HasFullFP16]
7191 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
7193 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
7196 //----------------------------------------------------------------------------
7197 // AdvSIMD INS/DUP instructions
7198 //----------------------------------------------------------------------------
7200 // FIXME: There has got to be a better way to factor these. ugh.
7202 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
7203 string operands, string constraints, list<dag> pattern>
7204 : I<outs, ins, asm, operands, constraints, pattern>,
7211 let Inst{28-21} = 0b01110000;
7218 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
7219 RegisterOperand vecreg, RegisterClass regtype>
7220 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
7221 "{\t$Rd" # size # ", $Rn" #
7222 "|" # size # "\t$Rd, $Rn}", "",
7223 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
7224 let Inst{20-16} = imm5;
7225 let Inst{14-11} = 0b0001;
7228 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
7229 ValueType vectype, ValueType insreg,
7230 RegisterOperand vecreg, Operand idxtype,
7231 ValueType elttype, SDNode OpNode>
7232 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
7233 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
7234 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
7235 [(set (vectype vecreg:$Rd),
7236 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
7237 let Inst{14-11} = 0b0000;
7240 class SIMDDup64FromElement
7241 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
7242 VectorIndexD, i64, AArch64duplane64> {
7245 let Inst{19-16} = 0b1000;
7248 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
7249 RegisterOperand vecreg>
7250 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
7251 VectorIndexS, i64, AArch64duplane32> {
7253 let Inst{20-19} = idx;
7254 let Inst{18-16} = 0b100;
7257 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
7258 RegisterOperand vecreg>
7259 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
7260 VectorIndexH, i64, AArch64duplane16> {
7262 let Inst{20-18} = idx;
7263 let Inst{17-16} = 0b10;
7266 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
7267 RegisterOperand vecreg>
7268 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
7269 VectorIndexB, i64, AArch64duplane8> {
7271 let Inst{20-17} = idx;
7275 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
7276 Operand idxtype, string asm, list<dag> pattern>
7277 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
7278 "{\t$Rd, $Rn" # size # "$idx" #
7279 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
7280 let Inst{14-11} = imm4;
7283 class SIMDSMov<bit Q, string size, RegisterClass regtype,
7285 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
7286 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
7288 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
7289 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
7291 class SIMDMovAlias<string asm, string size, Instruction inst,
7292 RegisterClass regtype, Operand idxtype>
7293 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
7294 "|" # size # "\t$dst, $src$idx}",
7295 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
7298 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
7300 let Inst{20-17} = idx;
7303 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
7305 let Inst{20-17} = idx;
7308 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
7310 let Inst{20-18} = idx;
7311 let Inst{17-16} = 0b10;
7313 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
7315 let Inst{20-18} = idx;
7316 let Inst{17-16} = 0b10;
7318 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
7320 let Inst{20-19} = idx;
7321 let Inst{18-16} = 0b100;
7326 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
7328 let Inst{20-17} = idx;
7331 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
7333 let Inst{20-18} = idx;
7334 let Inst{17-16} = 0b10;
7336 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
7338 let Inst{20-19} = idx;
7339 let Inst{18-16} = 0b100;
7341 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
7344 let Inst{19-16} = 0b1000;
7346 def : SIMDMovAlias<"mov", ".s",
7347 !cast<Instruction>(NAME#"vi32"),
7348 GPR32, VectorIndexS>;
7349 def : SIMDMovAlias<"mov", ".d",
7350 !cast<Instruction>(NAME#"vi64"),
7351 GPR64, VectorIndexD>;
7354 class SIMDInsFromMain<string size, ValueType vectype,
7355 RegisterClass regtype, Operand idxtype>
7356 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
7357 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
7358 "{\t$Rd" # size # "$idx, $Rn" #
7359 "|" # size # "\t$Rd$idx, $Rn}",
7362 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
7363 let Inst{14-11} = 0b0011;
7366 class SIMDInsFromElement<string size, ValueType vectype,
7367 ValueType elttype, Operand idxtype>
7368 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
7369 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
7370 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
7371 "|" # size # "\t$Rd$idx, $Rn$idx2}",
7376 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
7379 class SIMDInsMainMovAlias<string size, Instruction inst,
7380 RegisterClass regtype, Operand idxtype>
7381 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
7382 "|" # size #"\t$dst$idx, $src}",
7383 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
7384 class SIMDInsElementMovAlias<string size, Instruction inst,
7386 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2"
7387 # "|" # size #"\t$dst$idx, $src$idx2}",
7388 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
7391 multiclass SIMDIns {
7392 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
7394 let Inst{20-17} = idx;
7397 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
7399 let Inst{20-18} = idx;
7400 let Inst{17-16} = 0b10;
7402 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
7404 let Inst{20-19} = idx;
7405 let Inst{18-16} = 0b100;
7407 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
7410 let Inst{19-16} = 0b1000;
7413 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
7416 let Inst{20-17} = idx;
7418 let Inst{14-11} = idx2;
7420 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
7423 let Inst{20-18} = idx;
7424 let Inst{17-16} = 0b10;
7425 let Inst{14-12} = idx2;
7428 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
7431 let Inst{20-19} = idx;
7432 let Inst{18-16} = 0b100;
7433 let Inst{14-13} = idx2;
7434 let Inst{12-11} = {?,?};
7436 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
7440 let Inst{19-16} = 0b1000;
7441 let Inst{14} = idx2;
7442 let Inst{13-11} = {?,?,?};
7445 // For all forms of the INS instruction, the "mov" mnemonic is the
7446 // preferred alias. Why they didn't just call the instruction "mov" in
7447 // the first place is a very good question indeed...
7448 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
7449 GPR32, VectorIndexB>;
7450 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
7451 GPR32, VectorIndexH>;
7452 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
7453 GPR32, VectorIndexS>;
7454 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
7455 GPR64, VectorIndexD>;
7457 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
7459 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
7461 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
7463 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
7467 //----------------------------------------------------------------------------
7469 //----------------------------------------------------------------------------
7471 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7472 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7473 RegisterOperand listtype, string asm, string kind>
7474 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
7475 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
7482 let Inst{29-21} = 0b001110000;
7483 let Inst{20-16} = Vm;
7485 let Inst{14-13} = len;
7487 let Inst{11-10} = 0b00;
7492 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7493 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
7494 RegisterOperand listtype, string asm, string kind>
7495 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
7496 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
7503 let Inst{29-21} = 0b001110000;
7504 let Inst{20-16} = Vm;
7506 let Inst{14-13} = len;
7508 let Inst{11-10} = 0b00;
7513 class SIMDTableLookupAlias<string asm, Instruction inst,
7514 RegisterOperand vectype, RegisterOperand listtype>
7515 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
7516 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
7518 multiclass SIMDTableLookup<bit op, string asm> {
7519 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
7521 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
7523 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
7525 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
7527 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
7529 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
7531 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
7533 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
7536 def : SIMDTableLookupAlias<asm # ".8b",
7537 !cast<Instruction>(NAME#"v8i8One"),
7538 V64, VecListOne128>;
7539 def : SIMDTableLookupAlias<asm # ".8b",
7540 !cast<Instruction>(NAME#"v8i8Two"),
7541 V64, VecListTwo128>;
7542 def : SIMDTableLookupAlias<asm # ".8b",
7543 !cast<Instruction>(NAME#"v8i8Three"),
7544 V64, VecListThree128>;
7545 def : SIMDTableLookupAlias<asm # ".8b",
7546 !cast<Instruction>(NAME#"v8i8Four"),
7547 V64, VecListFour128>;
7548 def : SIMDTableLookupAlias<asm # ".16b",
7549 !cast<Instruction>(NAME#"v16i8One"),
7550 V128, VecListOne128>;
7551 def : SIMDTableLookupAlias<asm # ".16b",
7552 !cast<Instruction>(NAME#"v16i8Two"),
7553 V128, VecListTwo128>;
7554 def : SIMDTableLookupAlias<asm # ".16b",
7555 !cast<Instruction>(NAME#"v16i8Three"),
7556 V128, VecListThree128>;
7557 def : SIMDTableLookupAlias<asm # ".16b",
7558 !cast<Instruction>(NAME#"v16i8Four"),
7559 V128, VecListFour128>;
7562 multiclass SIMDTableLookupTied<bit op, string asm> {
7563 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
7565 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
7567 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
7569 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
7571 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
7573 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
7575 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
7577 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
7580 def : SIMDTableLookupAlias<asm # ".8b",
7581 !cast<Instruction>(NAME#"v8i8One"),
7582 V64, VecListOne128>;
7583 def : SIMDTableLookupAlias<asm # ".8b",
7584 !cast<Instruction>(NAME#"v8i8Two"),
7585 V64, VecListTwo128>;
7586 def : SIMDTableLookupAlias<asm # ".8b",
7587 !cast<Instruction>(NAME#"v8i8Three"),
7588 V64, VecListThree128>;
7589 def : SIMDTableLookupAlias<asm # ".8b",
7590 !cast<Instruction>(NAME#"v8i8Four"),
7591 V64, VecListFour128>;
7592 def : SIMDTableLookupAlias<asm # ".16b",
7593 !cast<Instruction>(NAME#"v16i8One"),
7594 V128, VecListOne128>;
7595 def : SIMDTableLookupAlias<asm # ".16b",
7596 !cast<Instruction>(NAME#"v16i8Two"),
7597 V128, VecListTwo128>;
7598 def : SIMDTableLookupAlias<asm # ".16b",
7599 !cast<Instruction>(NAME#"v16i8Three"),
7600 V128, VecListThree128>;
7601 def : SIMDTableLookupAlias<asm # ".16b",
7602 !cast<Instruction>(NAME#"v16i8Four"),
7603 V128, VecListFour128>;
7607 //----------------------------------------------------------------------------
7608 // AdvSIMD scalar CPY
7609 //----------------------------------------------------------------------------
7610 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7611 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
7612 string kind, Operand idxtype>
7613 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
7614 "{\t$dst, $src" # kind # "$idx" #
7615 "|\t$dst, $src$idx}", "", []>,
7619 let Inst{31-21} = 0b01011110000;
7620 let Inst{15-10} = 0b000001;
7621 let Inst{9-5} = src;
7622 let Inst{4-0} = dst;
7625 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
7626 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
7627 : InstAlias<asm # "{\t$dst, $src" # size # "$index"
7628 # "|\t$dst, $src$index}",
7629 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
7632 multiclass SIMDScalarCPY<string asm> {
7633 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
7635 let Inst{20-17} = idx;
7638 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
7640 let Inst{20-18} = idx;
7641 let Inst{17-16} = 0b10;
7643 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
7645 let Inst{20-19} = idx;
7646 let Inst{18-16} = 0b100;
7648 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
7651 let Inst{19-16} = 0b1000;
7654 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
7655 VectorIndexD:$idx)))),
7656 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
7658 // 'DUP' mnemonic aliases.
7659 def : SIMDScalarCPYAlias<"dup", ".b",
7660 !cast<Instruction>(NAME#"i8"),
7661 FPR8, V128, VectorIndexB>;
7662 def : SIMDScalarCPYAlias<"dup", ".h",
7663 !cast<Instruction>(NAME#"i16"),
7664 FPR16, V128, VectorIndexH>;
7665 def : SIMDScalarCPYAlias<"dup", ".s",
7666 !cast<Instruction>(NAME#"i32"),
7667 FPR32, V128, VectorIndexS>;
7668 def : SIMDScalarCPYAlias<"dup", ".d",
7669 !cast<Instruction>(NAME#"i64"),
7670 FPR64, V128, VectorIndexD>;
7673 //----------------------------------------------------------------------------
7674 // AdvSIMD modified immediate instructions
7675 //----------------------------------------------------------------------------
7677 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
7678 string asm, string op_string,
7679 string cstr, list<dag> pattern>
7680 : I<oops, iops, asm, op_string, cstr, pattern>,
7687 let Inst{28-19} = 0b0111100000;
7688 let Inst{18-16} = imm8{7-5};
7691 let Inst{9-5} = imm8{4-0};
7695 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
7696 Operand immtype, dag opt_shift_iop,
7697 string opt_shift, string asm, string kind,
7699 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
7700 !con((ins immtype:$imm8), opt_shift_iop), asm,
7701 "{\t$Rd" # kind # ", $imm8" # opt_shift #
7702 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7704 let DecoderMethod = "DecodeModImmInstruction";
7707 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
7708 Operand immtype, dag opt_shift_iop,
7709 string opt_shift, string asm, string kind,
7711 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
7712 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
7713 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
7714 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7715 "$Rd = $dst", pattern> {
7716 let DecoderMethod = "DecodeModImmTiedInstruction";
7719 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
7720 RegisterOperand vectype, string asm,
7721 string kind, list<dag> pattern>
7722 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7723 (ins logical_vec_shift:$shift),
7724 "$shift", asm, kind, pattern> {
7726 let Inst{15} = b15_b12{1};
7727 let Inst{14-13} = shift;
7728 let Inst{12} = b15_b12{0};
7731 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
7732 RegisterOperand vectype, string asm,
7733 string kind, list<dag> pattern>
7734 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7735 (ins logical_vec_shift:$shift),
7736 "$shift", asm, kind, pattern> {
7738 let Inst{15} = b15_b12{1};
7739 let Inst{14-13} = shift;
7740 let Inst{12} = b15_b12{0};
7744 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
7745 RegisterOperand vectype, string asm,
7746 string kind, list<dag> pattern>
7747 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7748 (ins logical_vec_hw_shift:$shift),
7749 "$shift", asm, kind, pattern> {
7751 let Inst{15} = b15_b12{1};
7753 let Inst{13} = shift{0};
7754 let Inst{12} = b15_b12{0};
7757 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
7758 RegisterOperand vectype, string asm,
7759 string kind, list<dag> pattern>
7760 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7761 (ins logical_vec_hw_shift:$shift),
7762 "$shift", asm, kind, pattern> {
7764 let Inst{15} = b15_b12{1};
7766 let Inst{13} = shift{0};
7767 let Inst{12} = b15_b12{0};
7770 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
7772 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
7774 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
7777 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
7779 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
7783 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
7784 bits<2> w_cmode, string asm,
7786 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
7788 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
7790 (i32 imm:$shift)))]>;
7791 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
7793 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
7795 (i32 imm:$shift)))]>;
7797 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
7799 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
7801 (i32 imm:$shift)))]>;
7802 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
7804 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
7806 (i32 imm:$shift)))]>;
7809 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
7810 RegisterOperand vectype, string asm,
7811 string kind, list<dag> pattern>
7812 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7813 (ins move_vec_shift:$shift),
7814 "$shift", asm, kind, pattern> {
7816 let Inst{15-13} = cmode{3-1};
7817 let Inst{12} = shift;
7820 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
7821 RegisterOperand vectype,
7822 Operand imm_type, string asm,
7823 string kind, list<dag> pattern>
7824 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
7825 asm, kind, pattern> {
7826 let Inst{15-12} = cmode;
7829 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
7831 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
7832 "\t$Rd, $imm8", "", pattern> {
7833 let Inst{15-12} = cmode;
7834 let DecoderMethod = "DecodeModImmInstruction";
7837 //----------------------------------------------------------------------------
7838 // AdvSIMD indexed element
7839 //----------------------------------------------------------------------------
7841 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7842 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7843 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7844 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7845 string apple_kind, string dst_kind, string lhs_kind,
7846 string rhs_kind, list<dag> pattern>
7847 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
7849 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7850 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
7859 let Inst{28} = Scalar;
7860 let Inst{27-24} = 0b1111;
7861 let Inst{23-22} = size;
7862 // Bit 21 must be set by the derived class.
7863 let Inst{20-16} = Rm;
7864 let Inst{15-12} = opc;
7865 // Bit 11 must be set by the derived class.
7871 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7872 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7873 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7874 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7875 string apple_kind, string dst_kind, string lhs_kind,
7876 string rhs_kind, list<dag> pattern>
7877 : I<(outs dst_reg:$dst),
7878 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
7879 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7880 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
7889 let Inst{28} = Scalar;
7890 let Inst{27-24} = 0b1111;
7891 let Inst{23-22} = size;
7892 // Bit 21 must be set by the derived class.
7893 let Inst{20-16} = Rm;
7894 let Inst{15-12} = opc;
7895 // Bit 11 must be set by the derived class.
7902 //----------------------------------------------------------------------------
7903 // Armv8.6 BFloat16 Extension
7904 //----------------------------------------------------------------------------
7905 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in {
7907 class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1,
7908 string kind2, RegisterOperand RegType,
7909 ValueType AccumType, ValueType InputType>
7910 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst),
7911 (int_aarch64_neon_bfdot (AccumType RegType:$Rd),
7912 (InputType RegType:$Rn),
7913 (InputType RegType:$Rm)))]> {
7914 let AsmString = !strconcat(asm,
7915 "{\t$Rd" # kind1 # ", $Rn" # kind2 #
7916 ", $Rm" # kind2 # "}");
7919 multiclass SIMDThreeSameVectorBFDot<bit U, string asm> {
7920 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64,
7922 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,
7926 class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
7927 string dst_kind, string lhs_kind,
7929 RegisterOperand RegType,
7930 ValueType AccumType,
7931 ValueType InputType>
7932 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111,
7933 RegType, RegType, V128, VectorIndexS,
7934 asm, "", dst_kind, lhs_kind, rhs_kind,
7935 [(set (AccumType RegType:$dst),
7936 (AccumType (int_aarch64_neon_bfdot
7937 (AccumType RegType:$Rd),
7938 (InputType RegType:$Rn),
7939 (InputType (bitconvert (AccumType
7940 (AArch64duplane32 (v4f32 V128:$Rm),
7941 VectorIndexS:$idx)))))))]> {
7944 let Inst{21} = idx{0}; // L
7945 let Inst{11} = idx{1}; // H
7948 multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> {
7950 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h",
7951 ".2h", V64, v2f32, v4bf16>;
7952 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h",
7953 ".2h", V128, v4f32, v8bf16>;
7956 class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode>
7957 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s",
7958 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
7960 (v8bf16 V128:$Rm)))]> {
7961 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}");
7964 class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode>
7965 : I<(outs V128:$dst),
7966 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm,
7967 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst",
7968 [(set (v4f32 V128:$dst),
7969 (v4f32 (OpNode (v4f32 V128:$Rd),
7972 (AArch64duplane16 (v8bf16 V128_lo:$Rm),
7973 VectorIndexH:$idx)))))]>,
7982 let Inst{29-22} = 0b00111111;
7983 let Inst{21-20} = idx{1-0};
7984 let Inst{19-16} = Rm;
7985 let Inst{15-12} = 0b1111;
7986 let Inst{11} = idx{2}; // H
7992 class SIMDThreeSameVectorBF16MatrixMul<string asm>
7993 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101,
7995 [(set (v4f32 V128:$dst),
7996 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd),
7998 (v8bf16 V128:$Rm)))]> {
7999 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h",
8000 ", $Rm", ".8h", "}");
8004 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128,
8005 "bfcvtn", ".4h", ".4s",
8006 [(set (v8bf16 V128:$Rd),
8007 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>;
8010 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128,
8011 "bfcvtn2", ".8h", ".4s",
8012 [(set (v8bf16 V128:$dst),
8013 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>;
8015 class BF16ToSinglePrecision<string asm>
8016 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "",
8017 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>,
8018 Sched<[WriteFCvt]> {
8021 let Inst{31-10} = 0b0001111001100011010000;
8025 } // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0
8027 //----------------------------------------------------------------------------
8028 // Armv8.6 Matrix Multiply Extension
8029 //----------------------------------------------------------------------------
8031 class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode>
8032 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s",
8033 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
8035 (v16i8 V128:$Rm)))]> {
8036 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}";
8039 //----------------------------------------------------------------------------
8040 // ARMv8.2-A Dot Product Instructions (Indexed)
8041 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm,
8042 string dst_kind, string lhs_kind, string rhs_kind,
8043 RegisterOperand RegType,
8044 ValueType AccumType, ValueType InputType,
8045 SDPatternOperator OpNode> :
8046 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128,
8047 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
8048 [(set (AccumType RegType:$dst),
8049 (AccumType (OpNode (AccumType RegType:$Rd),
8050 (InputType RegType:$Rn),
8051 (InputType (bitconvert (AccumType
8052 (AArch64duplane32 (v4i32 V128:$Rm),
8053 VectorIndexS:$idx)))))))]> {
8055 let Inst{21} = idx{0}; // L
8056 let Inst{11} = idx{1}; // H
8059 multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm,
8060 SDPatternOperator OpNode> {
8061 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b",
8062 V64, v2i32, v8i8, OpNode>;
8063 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b",
8064 V128, v4i32, v16i8, OpNode>;
8067 // ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed)
8068 class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm,
8069 string dst_kind, string lhs_kind,
8070 string rhs_kind, RegisterOperand RegType,
8071 ValueType AccumType, ValueType InputType,
8072 SDPatternOperator OpNode> :
8073 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128,
8074 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind,
8075 [(set (AccumType RegType:$dst),
8076 (AccumType (OpNode (AccumType RegType:$Rd),
8077 (InputType RegType:$Rn),
8078 (InputType (AArch64duplane16 (v8f16 V128:$Rm),
8079 VectorIndexH:$idx)))))]> {
8082 let Inst{11} = idx{2}; // H
8083 let Inst{21} = idx{1}; // L
8084 let Inst{20} = idx{0}; // M
8087 multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm,
8088 SDPatternOperator OpNode> {
8089 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h",
8090 V64, v2f32, v4f16, OpNode>;
8091 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h",
8092 V128, v4f32, v8f16, OpNode>;
8095 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
8096 SDPatternOperator OpNode> {
8097 let Predicates = [HasNEON, HasFullFP16] in {
8098 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
8100 V128_lo, VectorIndexH,
8101 asm, ".4h", ".4h", ".4h", ".h",
8102 [(set (v4f16 V64:$Rd),
8103 (OpNode (v4f16 V64:$Rn),
8104 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8106 let Inst{11} = idx{2};
8107 let Inst{21} = idx{1};
8108 let Inst{20} = idx{0};
8111 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
8113 V128_lo, VectorIndexH,
8114 asm, ".8h", ".8h", ".8h", ".h",
8115 [(set (v8f16 V128:$Rd),
8116 (OpNode (v8f16 V128:$Rn),
8117 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8119 let Inst{11} = idx{2};
8120 let Inst{21} = idx{1};
8121 let Inst{20} = idx{0};
8123 } // Predicates = [HasNEON, HasFullFP16]
8125 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8128 asm, ".2s", ".2s", ".2s", ".s",
8129 [(set (v2f32 V64:$Rd),
8130 (OpNode (v2f32 V64:$Rn),
8131 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8133 let Inst{11} = idx{1};
8134 let Inst{21} = idx{0};
8137 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8140 asm, ".4s", ".4s", ".4s", ".s",
8141 [(set (v4f32 V128:$Rd),
8142 (OpNode (v4f32 V128:$Rn),
8143 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
8145 let Inst{11} = idx{1};
8146 let Inst{21} = idx{0};
8149 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
8152 asm, ".2d", ".2d", ".2d", ".d",
8153 [(set (v2f64 V128:$Rd),
8154 (OpNode (v2f64 V128:$Rn),
8155 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
8157 let Inst{11} = idx{0};
8161 let Predicates = [HasNEON, HasFullFP16] in {
8162 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
8163 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8164 asm, ".h", "", "", ".h",
8165 [(set (f16 FPR16Op:$Rd),
8166 (OpNode (f16 FPR16Op:$Rn),
8167 (f16 (vector_extract (v8f16 V128_lo:$Rm),
8168 VectorIndexH:$idx))))]> {
8170 let Inst{11} = idx{2};
8171 let Inst{21} = idx{1};
8172 let Inst{20} = idx{0};
8174 } // Predicates = [HasNEON, HasFullFP16]
8176 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8177 FPR32Op, FPR32Op, V128, VectorIndexS,
8178 asm, ".s", "", "", ".s",
8179 [(set (f32 FPR32Op:$Rd),
8180 (OpNode (f32 FPR32Op:$Rn),
8181 (f32 (vector_extract (v4f32 V128:$Rm),
8182 VectorIndexS:$idx))))]> {
8184 let Inst{11} = idx{1};
8185 let Inst{21} = idx{0};
8188 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
8189 FPR64Op, FPR64Op, V128, VectorIndexD,
8190 asm, ".d", "", "", ".d",
8191 [(set (f64 FPR64Op:$Rd),
8192 (OpNode (f64 FPR64Op:$Rn),
8193 (f64 (vector_extract (v2f64 V128:$Rm),
8194 VectorIndexD:$idx))))]> {
8196 let Inst{11} = idx{0};
8201 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
8202 let Predicates = [HasNEON, HasFullFP16] in {
8203 // Patterns for f16: DUPLANE, DUP scalar and vector_extract.
8204 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8205 (AArch64duplane16 (v8f16 V128_lo:$Rm),
8206 VectorIndexH:$idx))),
8207 (!cast<Instruction>(INST # "v8i16_indexed")
8208 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8209 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
8210 (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8211 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn,
8212 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8214 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8215 (AArch64duplane16 (v8f16 V128_lo:$Rm),
8216 VectorIndexH:$idx))),
8217 (!cast<Instruction>(INST # "v4i16_indexed")
8218 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
8219 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
8220 (AArch64dup (f16 FPR16Op_lo:$Rm)))),
8221 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn,
8222 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
8224 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn),
8225 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))),
8226 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn,
8227 V128_lo:$Rm, VectorIndexH:$idx)>;
8228 } // Predicates = [HasNEON, HasFullFP16]
8230 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
8231 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8232 (AArch64duplane32 (v4f32 V128:$Rm),
8233 VectorIndexS:$idx))),
8234 (!cast<Instruction>(INST # v2i32_indexed)
8235 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8236 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
8237 (AArch64dup (f32 FPR32Op:$Rm)))),
8238 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
8239 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8242 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
8243 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8244 (AArch64duplane32 (v4f32 V128:$Rm),
8245 VectorIndexS:$idx))),
8246 (!cast<Instruction>(INST # "v4i32_indexed")
8247 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8248 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
8249 (AArch64dup (f32 FPR32Op:$Rm)))),
8250 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
8251 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
8253 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
8254 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
8255 (AArch64duplane64 (v2f64 V128:$Rm),
8256 VectorIndexD:$idx))),
8257 (!cast<Instruction>(INST # "v2i64_indexed")
8258 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
8259 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
8260 (AArch64dup (f64 FPR64Op:$Rm)))),
8261 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
8262 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
8264 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s
8265 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
8266 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
8267 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
8268 V128:$Rm, VectorIndexS:$idx)>;
8270 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
8271 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
8272 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
8273 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
8274 V128:$Rm, VectorIndexD:$idx)>;
8277 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
8278 let Predicates = [HasNEON, HasFullFP16] in {
8279 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
8280 V128_lo, VectorIndexH,
8281 asm, ".4h", ".4h", ".4h", ".h", []> {
8283 let Inst{11} = idx{2};
8284 let Inst{21} = idx{1};
8285 let Inst{20} = idx{0};
8288 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
8290 V128_lo, VectorIndexH,
8291 asm, ".8h", ".8h", ".8h", ".h", []> {
8293 let Inst{11} = idx{2};
8294 let Inst{21} = idx{1};
8295 let Inst{20} = idx{0};
8297 } // Predicates = [HasNEON, HasFullFP16]
8299 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
8301 asm, ".2s", ".2s", ".2s", ".s", []> {
8303 let Inst{11} = idx{1};
8304 let Inst{21} = idx{0};
8307 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8310 asm, ".4s", ".4s", ".4s", ".s", []> {
8312 let Inst{11} = idx{1};
8313 let Inst{21} = idx{0};
8316 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
8319 asm, ".2d", ".2d", ".2d", ".d", []> {
8321 let Inst{11} = idx{0};
8325 let Predicates = [HasNEON, HasFullFP16] in {
8326 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
8327 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8328 asm, ".h", "", "", ".h", []> {
8330 let Inst{11} = idx{2};
8331 let Inst{21} = idx{1};
8332 let Inst{20} = idx{0};
8334 } // Predicates = [HasNEON, HasFullFP16]
8336 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8337 FPR32Op, FPR32Op, V128, VectorIndexS,
8338 asm, ".s", "", "", ".s", []> {
8340 let Inst{11} = idx{1};
8341 let Inst{21} = idx{0};
8344 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
8345 FPR64Op, FPR64Op, V128, VectorIndexD,
8346 asm, ".d", "", "", ".d", []> {
8348 let Inst{11} = idx{0};
8353 multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane,
8354 SDPatternOperator OpNodeLaneQ> {
8356 def : Pat<(v4i16 (OpNodeLane
8357 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm),
8358 VectorIndexS32b:$idx)),
8359 (!cast<Instruction>(NAME # v4i16_indexed) $Rn,
8360 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub),
8361 (UImmS1XForm $idx))>;
8363 def : Pat<(v4i16 (OpNodeLaneQ
8364 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm),
8365 VectorIndexH32b:$idx)),
8366 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm,
8367 (UImmS1XForm $idx))>;
8369 def : Pat<(v8i16 (OpNodeLane
8370 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm),
8371 VectorIndexS32b:$idx)),
8372 (!cast<Instruction>(NAME # v8i16_indexed) $Rn,
8373 (SUBREG_TO_REG (i32 0), $Rm, dsub),
8374 (UImmS1XForm $idx))>;
8376 def : Pat<(v8i16 (OpNodeLaneQ
8377 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm),
8378 VectorIndexH32b:$idx)),
8379 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm,
8380 (UImmS1XForm $idx))>;
8382 def : Pat<(v2i32 (OpNodeLane
8383 (v2i32 V64:$Rn), (v2i32 V64:$Rm),
8384 VectorIndexD32b:$idx)),
8385 (!cast<Instruction>(NAME # v2i32_indexed) $Rn,
8386 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub),
8387 (UImmS1XForm $idx))>;
8389 def : Pat<(v2i32 (OpNodeLaneQ
8390 (v2i32 V64:$Rn), (v4i32 V128:$Rm),
8391 VectorIndexS32b:$idx)),
8392 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm,
8393 (UImmS1XForm $idx))>;
8395 def : Pat<(v4i32 (OpNodeLane
8396 (v4i32 V128:$Rn), (v2i32 V64:$Rm),
8397 VectorIndexD32b:$idx)),
8398 (!cast<Instruction>(NAME # v4i32_indexed) $Rn,
8399 (SUBREG_TO_REG (i32 0), $Rm, dsub),
8400 (UImmS1XForm $idx))>;
8402 def : Pat<(v4i32 (OpNodeLaneQ
8405 VectorIndexS32b:$idx)),
8406 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm,
8407 (UImmS1XForm $idx))>;
8411 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
8412 SDPatternOperator OpNode> {
8413 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
8414 V128_lo, VectorIndexH,
8415 asm, ".4h", ".4h", ".4h", ".h",
8416 [(set (v4i16 V64:$Rd),
8417 (OpNode (v4i16 V64:$Rn),
8418 (v4i16 (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 v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8427 V128_lo, VectorIndexH,
8428 asm, ".8h", ".8h", ".8h", ".h",
8429 [(set (v8i16 V128:$Rd),
8430 (OpNode (v8i16 V128:$Rn),
8431 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8433 let Inst{11} = idx{2};
8434 let Inst{21} = idx{1};
8435 let Inst{20} = idx{0};
8438 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8441 asm, ".2s", ".2s", ".2s", ".s",
8442 [(set (v2i32 V64:$Rd),
8443 (OpNode (v2i32 V64:$Rn),
8444 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8446 let Inst{11} = idx{1};
8447 let Inst{21} = idx{0};
8450 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8453 asm, ".4s", ".4s", ".4s", ".s",
8454 [(set (v4i32 V128:$Rd),
8455 (OpNode (v4i32 V128:$Rn),
8456 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8458 let Inst{11} = idx{1};
8459 let Inst{21} = idx{0};
8462 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
8463 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
8464 asm, ".h", "", "", ".h", []> {
8466 let Inst{11} = idx{2};
8467 let Inst{21} = idx{1};
8468 let Inst{20} = idx{0};
8471 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8472 FPR32Op, FPR32Op, V128, VectorIndexS,
8473 asm, ".s", "", "", ".s",
8474 [(set (i32 FPR32Op:$Rd),
8475 (OpNode FPR32Op:$Rn,
8476 (i32 (vector_extract (v4i32 V128:$Rm),
8477 VectorIndexS:$idx))))]> {
8479 let Inst{11} = idx{1};
8480 let Inst{21} = idx{0};
8484 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
8485 SDPatternOperator OpNode> {
8486 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8488 V128_lo, VectorIndexH,
8489 asm, ".4h", ".4h", ".4h", ".h",
8490 [(set (v4i16 V64:$Rd),
8491 (OpNode (v4i16 V64:$Rn),
8492 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8494 let Inst{11} = idx{2};
8495 let Inst{21} = idx{1};
8496 let Inst{20} = idx{0};
8499 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8501 V128_lo, VectorIndexH,
8502 asm, ".8h", ".8h", ".8h", ".h",
8503 [(set (v8i16 V128:$Rd),
8504 (OpNode (v8i16 V128:$Rn),
8505 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8507 let Inst{11} = idx{2};
8508 let Inst{21} = idx{1};
8509 let Inst{20} = idx{0};
8512 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8515 asm, ".2s", ".2s", ".2s", ".s",
8516 [(set (v2i32 V64:$Rd),
8517 (OpNode (v2i32 V64:$Rn),
8518 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8520 let Inst{11} = idx{1};
8521 let Inst{21} = idx{0};
8524 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8527 asm, ".4s", ".4s", ".4s", ".s",
8528 [(set (v4i32 V128:$Rd),
8529 (OpNode (v4i32 V128:$Rn),
8530 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8532 let Inst{11} = idx{1};
8533 let Inst{21} = idx{0};
8537 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
8538 SDPatternOperator OpNode> {
8539 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
8540 V128_lo, VectorIndexH,
8541 asm, ".4h", ".4h", ".4h", ".h",
8542 [(set (v4i16 V64:$dst),
8543 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
8544 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8546 let Inst{11} = idx{2};
8547 let Inst{21} = idx{1};
8548 let Inst{20} = idx{0};
8551 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8553 V128_lo, VectorIndexH,
8554 asm, ".8h", ".8h", ".8h", ".h",
8555 [(set (v8i16 V128:$dst),
8556 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8557 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8559 let Inst{11} = idx{2};
8560 let Inst{21} = idx{1};
8561 let Inst{20} = idx{0};
8564 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8567 asm, ".2s", ".2s", ".2s", ".s",
8568 [(set (v2i32 V64:$dst),
8569 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8570 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8572 let Inst{11} = idx{1};
8573 let Inst{21} = idx{0};
8576 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8579 asm, ".4s", ".4s", ".4s", ".s",
8580 [(set (v4i32 V128:$dst),
8581 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8582 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8584 let Inst{11} = idx{1};
8585 let Inst{21} = idx{0};
8589 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
8590 SDPatternOperator OpNode> {
8591 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8593 V128_lo, VectorIndexH,
8594 asm, ".4s", ".4s", ".4h", ".h",
8595 [(set (v4i32 V128:$Rd),
8596 (OpNode (v4i16 V64:$Rn),
8597 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8599 let Inst{11} = idx{2};
8600 let Inst{21} = idx{1};
8601 let Inst{20} = idx{0};
8604 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8606 V128_lo, VectorIndexH,
8607 asm#"2", ".4s", ".4s", ".8h", ".h",
8608 [(set (v4i32 V128:$Rd),
8609 (OpNode (extract_high_v8i16 V128:$Rn),
8610 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8611 VectorIndexH:$idx))))]> {
8614 let Inst{11} = idx{2};
8615 let Inst{21} = idx{1};
8616 let Inst{20} = idx{0};
8619 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8622 asm, ".2d", ".2d", ".2s", ".s",
8623 [(set (v2i64 V128:$Rd),
8624 (OpNode (v2i32 V64:$Rn),
8625 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8627 let Inst{11} = idx{1};
8628 let Inst{21} = idx{0};
8631 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8634 asm#"2", ".2d", ".2d", ".4s", ".s",
8635 [(set (v2i64 V128:$Rd),
8636 (OpNode (extract_high_v4i32 V128:$Rn),
8637 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8638 VectorIndexS:$idx))))]> {
8640 let Inst{11} = idx{1};
8641 let Inst{21} = idx{0};
8644 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
8645 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8646 asm, ".h", "", "", ".h", []> {
8648 let Inst{11} = idx{2};
8649 let Inst{21} = idx{1};
8650 let Inst{20} = idx{0};
8653 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
8654 FPR64Op, FPR32Op, V128, VectorIndexS,
8655 asm, ".s", "", "", ".s", []> {
8657 let Inst{11} = idx{1};
8658 let Inst{21} = idx{0};
8662 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
8663 SDPatternOperator Accum> {
8664 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8666 V128_lo, VectorIndexH,
8667 asm, ".4s", ".4s", ".4h", ".h",
8668 [(set (v4i32 V128:$dst),
8669 (Accum (v4i32 V128:$Rd),
8670 (v4i32 (int_aarch64_neon_sqdmull
8672 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8673 VectorIndexH:$idx))))))]> {
8675 let Inst{11} = idx{2};
8676 let Inst{21} = idx{1};
8677 let Inst{20} = idx{0};
8680 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
8681 // intermediate EXTRACT_SUBREG would be untyped.
8682 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8683 (i32 (vector_extract (v4i32
8684 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
8685 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8686 VectorIndexH:$idx)))),
8689 (!cast<Instruction>(NAME # v4i16_indexed)
8690 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
8691 V128_lo:$Rm, VectorIndexH:$idx),
8694 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8696 V128_lo, VectorIndexH,
8697 asm#"2", ".4s", ".4s", ".8h", ".h",
8698 [(set (v4i32 V128:$dst),
8699 (Accum (v4i32 V128:$Rd),
8700 (v4i32 (int_aarch64_neon_sqdmull
8701 (extract_high_v8i16 V128:$Rn),
8703 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8704 VectorIndexH:$idx))))))]> {
8706 let Inst{11} = idx{2};
8707 let Inst{21} = idx{1};
8708 let Inst{20} = idx{0};
8711 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8714 asm, ".2d", ".2d", ".2s", ".s",
8715 [(set (v2i64 V128:$dst),
8716 (Accum (v2i64 V128:$Rd),
8717 (v2i64 (int_aarch64_neon_sqdmull
8719 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8720 VectorIndexS:$idx))))))]> {
8722 let Inst{11} = idx{1};
8723 let Inst{21} = idx{0};
8726 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8729 asm#"2", ".2d", ".2d", ".4s", ".s",
8730 [(set (v2i64 V128:$dst),
8731 (Accum (v2i64 V128:$Rd),
8732 (v2i64 (int_aarch64_neon_sqdmull
8733 (extract_high_v4i32 V128:$Rn),
8735 (AArch64duplane32 (v4i32 V128:$Rm),
8736 VectorIndexS:$idx))))))]> {
8738 let Inst{11} = idx{1};
8739 let Inst{21} = idx{0};
8742 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8743 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
8744 asm, ".h", "", "", ".h", []> {
8746 let Inst{11} = idx{2};
8747 let Inst{21} = idx{1};
8748 let Inst{20} = idx{0};
8752 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8753 FPR64Op, FPR32Op, V128, VectorIndexS,
8754 asm, ".s", "", "", ".s",
8755 [(set (i64 FPR64Op:$dst),
8756 (Accum (i64 FPR64Op:$Rd),
8757 (i64 (int_aarch64_neon_sqdmulls_scalar
8759 (i32 (vector_extract (v4i32 V128:$Rm),
8760 VectorIndexS:$idx))))))]> {
8763 let Inst{11} = idx{1};
8764 let Inst{21} = idx{0};
8768 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
8769 SDPatternOperator OpNode> {
8770 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8771 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
8773 V128_lo, VectorIndexH,
8774 asm, ".4s", ".4s", ".4h", ".h",
8775 [(set (v4i32 V128:$Rd),
8776 (OpNode (v4i16 V64:$Rn),
8777 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8779 let Inst{11} = idx{2};
8780 let Inst{21} = idx{1};
8781 let Inst{20} = idx{0};
8784 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
8786 V128_lo, VectorIndexH,
8787 asm#"2", ".4s", ".4s", ".8h", ".h",
8788 [(set (v4i32 V128:$Rd),
8789 (OpNode (extract_high_v8i16 V128:$Rn),
8790 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8791 VectorIndexH:$idx))))]> {
8794 let Inst{11} = idx{2};
8795 let Inst{21} = idx{1};
8796 let Inst{20} = idx{0};
8799 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
8802 asm, ".2d", ".2d", ".2s", ".s",
8803 [(set (v2i64 V128:$Rd),
8804 (OpNode (v2i32 V64:$Rn),
8805 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8807 let Inst{11} = idx{1};
8808 let Inst{21} = idx{0};
8811 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
8814 asm#"2", ".2d", ".2d", ".4s", ".s",
8815 [(set (v2i64 V128:$Rd),
8816 (OpNode (extract_high_v4i32 V128:$Rn),
8817 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8818 VectorIndexS:$idx))))]> {
8820 let Inst{11} = idx{1};
8821 let Inst{21} = idx{0};
8826 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
8827 SDPatternOperator OpNode> {
8828 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
8829 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8831 V128_lo, VectorIndexH,
8832 asm, ".4s", ".4s", ".4h", ".h",
8833 [(set (v4i32 V128:$dst),
8834 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
8835 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
8837 let Inst{11} = idx{2};
8838 let Inst{21} = idx{1};
8839 let Inst{20} = idx{0};
8842 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8844 V128_lo, VectorIndexH,
8845 asm#"2", ".4s", ".4s", ".8h", ".h",
8846 [(set (v4i32 V128:$dst),
8847 (OpNode (v4i32 V128:$Rd),
8848 (extract_high_v8i16 V128:$Rn),
8849 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8850 VectorIndexH:$idx))))]> {
8852 let Inst{11} = idx{2};
8853 let Inst{21} = idx{1};
8854 let Inst{20} = idx{0};
8857 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8860 asm, ".2d", ".2d", ".2s", ".s",
8861 [(set (v2i64 V128:$dst),
8862 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
8863 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
8865 let Inst{11} = idx{1};
8866 let Inst{21} = idx{0};
8869 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8872 asm#"2", ".2d", ".2d", ".4s", ".s",
8873 [(set (v2i64 V128:$dst),
8874 (OpNode (v2i64 V128:$Rd),
8875 (extract_high_v4i32 V128:$Rn),
8876 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8877 VectorIndexS:$idx))))]> {
8879 let Inst{11} = idx{1};
8880 let Inst{21} = idx{0};
8885 //----------------------------------------------------------------------------
8886 // AdvSIMD scalar shift by immediate
8887 //----------------------------------------------------------------------------
8889 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8890 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
8891 RegisterClass regtype1, RegisterClass regtype2,
8892 Operand immtype, string asm, list<dag> pattern>
8893 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
8894 asm, "\t$Rd, $Rn, $imm", "", pattern>,
8899 let Inst{31-30} = 0b01;
8901 let Inst{28-23} = 0b111110;
8902 let Inst{22-16} = fixed_imm;
8903 let Inst{15-11} = opc;
8909 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8910 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
8911 RegisterClass regtype1, RegisterClass regtype2,
8912 Operand immtype, string asm, list<dag> pattern>
8913 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
8914 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
8919 let Inst{31-30} = 0b01;
8921 let Inst{28-23} = 0b111110;
8922 let Inst{22-16} = fixed_imm;
8923 let Inst{15-11} = opc;
8930 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
8931 let Predicates = [HasNEON, HasFullFP16] in {
8932 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8933 FPR16, FPR16, vecshiftR16, asm, []> {
8934 let Inst{19-16} = imm{3-0};
8936 } // Predicates = [HasNEON, HasFullFP16]
8937 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8938 FPR32, FPR32, vecshiftR32, asm, []> {
8939 let Inst{20-16} = imm{4-0};
8941 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8942 FPR64, FPR64, vecshiftR64, asm, []> {
8943 let Inst{21-16} = imm{5-0};
8947 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
8948 SDPatternOperator OpNode> {
8949 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8950 FPR64, FPR64, vecshiftR64, asm,
8951 [(set (i64 FPR64:$Rd),
8952 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
8953 let Inst{21-16} = imm{5-0};
8956 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
8957 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
8960 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
8961 SDPatternOperator OpNode = null_frag> {
8962 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8963 FPR64, FPR64, vecshiftR64, asm,
8964 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
8965 (i32 vecshiftR64:$imm)))]> {
8966 let Inst{21-16} = imm{5-0};
8969 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
8970 (i32 vecshiftR64:$imm))),
8971 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
8975 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
8976 SDPatternOperator OpNode> {
8977 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8978 FPR64, FPR64, vecshiftL64, asm,
8979 [(set (i64 FPR64:$Rd),
8980 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8981 let Inst{21-16} = imm{5-0};
8984 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
8985 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
8988 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8989 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
8990 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8991 FPR64, FPR64, vecshiftL64, asm, []> {
8992 let Inst{21-16} = imm{5-0};
8996 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8997 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
8998 SDPatternOperator OpNode = null_frag> {
8999 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
9000 FPR8, FPR16, vecshiftR8, asm, []> {
9001 let Inst{18-16} = imm{2-0};
9004 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9005 FPR16, FPR32, vecshiftR16, asm, []> {
9006 let Inst{19-16} = imm{3-0};
9009 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9010 FPR32, FPR64, vecshiftR32, asm,
9011 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
9012 let Inst{20-16} = imm{4-0};
9016 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
9017 SDPatternOperator OpNode> {
9018 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
9019 FPR8, FPR8, vecshiftL8, asm, []> {
9020 let Inst{18-16} = imm{2-0};
9023 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9024 FPR16, FPR16, vecshiftL16, asm, []> {
9025 let Inst{19-16} = imm{3-0};
9028 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9029 FPR32, FPR32, vecshiftL32, asm,
9030 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
9031 let Inst{20-16} = imm{4-0};
9034 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9035 FPR64, FPR64, vecshiftL64, asm,
9036 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
9037 let Inst{21-16} = imm{5-0};
9040 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
9041 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
9044 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
9045 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
9046 FPR8, FPR8, vecshiftR8, asm, []> {
9047 let Inst{18-16} = imm{2-0};
9050 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
9051 FPR16, FPR16, vecshiftR16, asm, []> {
9052 let Inst{19-16} = imm{3-0};
9055 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
9056 FPR32, FPR32, vecshiftR32, asm, []> {
9057 let Inst{20-16} = imm{4-0};
9060 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
9061 FPR64, FPR64, vecshiftR64, asm, []> {
9062 let Inst{21-16} = imm{5-0};
9066 //----------------------------------------------------------------------------
9067 // AdvSIMD vector x indexed element
9068 //----------------------------------------------------------------------------
9070 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9071 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
9072 RegisterOperand dst_reg, RegisterOperand src_reg,
9074 string asm, string dst_kind, string src_kind,
9076 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
9077 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
9078 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
9085 let Inst{28-23} = 0b011110;
9086 let Inst{22-16} = fixed_imm;
9087 let Inst{15-11} = opc;
9093 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
9094 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
9095 RegisterOperand vectype1, RegisterOperand vectype2,
9097 string asm, string dst_kind, string src_kind,
9099 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
9100 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
9101 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
9108 let Inst{28-23} = 0b011110;
9109 let Inst{22-16} = fixed_imm;
9110 let Inst{15-11} = opc;
9116 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
9118 let Predicates = [HasNEON, HasFullFP16] in {
9119 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9120 V64, V64, vecshiftR16,
9122 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
9124 let Inst{19-16} = imm;
9127 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9128 V128, V128, vecshiftR16,
9130 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
9132 let Inst{19-16} = imm;
9134 } // Predicates = [HasNEON, HasFullFP16]
9135 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9136 V64, V64, vecshiftR32,
9138 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
9140 let Inst{20-16} = imm;
9143 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9144 V128, V128, vecshiftR32,
9146 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
9148 let Inst{20-16} = imm;
9151 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9152 V128, V128, vecshiftR64,
9154 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
9156 let Inst{21-16} = imm;
9160 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
9162 let Predicates = [HasNEON, HasFullFP16] in {
9163 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9164 V64, V64, vecshiftR16,
9166 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
9168 let Inst{19-16} = imm;
9171 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9172 V128, V128, vecshiftR16,
9174 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
9176 let Inst{19-16} = imm;
9178 } // Predicates = [HasNEON, HasFullFP16]
9180 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9181 V64, V64, vecshiftR32,
9183 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
9185 let Inst{20-16} = imm;
9188 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9189 V128, V128, vecshiftR32,
9191 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
9193 let Inst{20-16} = imm;
9196 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9197 V128, V128, vecshiftR64,
9199 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
9201 let Inst{21-16} = imm;
9205 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
9206 SDPatternOperator OpNode> {
9207 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9208 V64, V128, vecshiftR16Narrow,
9210 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
9212 let Inst{18-16} = imm;
9215 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9216 V128, V128, vecshiftR16Narrow,
9217 asm#"2", ".16b", ".8h", []> {
9219 let Inst{18-16} = imm;
9220 let hasSideEffects = 0;
9223 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9224 V64, V128, vecshiftR32Narrow,
9226 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
9228 let Inst{19-16} = imm;
9231 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9232 V128, V128, vecshiftR32Narrow,
9233 asm#"2", ".8h", ".4s", []> {
9235 let Inst{19-16} = imm;
9236 let hasSideEffects = 0;
9239 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9240 V64, V128, vecshiftR64Narrow,
9242 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
9244 let Inst{20-16} = imm;
9247 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9248 V128, V128, vecshiftR64Narrow,
9249 asm#"2", ".4s", ".2d", []> {
9251 let Inst{20-16} = imm;
9252 let hasSideEffects = 0;
9255 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
9256 // themselves, so put them here instead.
9258 // Patterns involving what's effectively an insert high and a normal
9259 // intrinsic, represented by CONCAT_VECTORS.
9260 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
9261 vecshiftR16Narrow:$imm)),
9262 (!cast<Instruction>(NAME # "v16i8_shift")
9263 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9264 V128:$Rn, vecshiftR16Narrow:$imm)>;
9265 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
9266 vecshiftR32Narrow:$imm)),
9267 (!cast<Instruction>(NAME # "v8i16_shift")
9268 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9269 V128:$Rn, vecshiftR32Narrow:$imm)>;
9270 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
9271 vecshiftR64Narrow:$imm)),
9272 (!cast<Instruction>(NAME # "v4i32_shift")
9273 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
9274 V128:$Rn, vecshiftR64Narrow:$imm)>;
9277 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
9278 SDPatternOperator OpNode> {
9279 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9280 V64, V64, vecshiftL8,
9282 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
9283 (i32 vecshiftL8:$imm)))]> {
9285 let Inst{18-16} = imm;
9288 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9289 V128, V128, vecshiftL8,
9290 asm, ".16b", ".16b",
9291 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
9292 (i32 vecshiftL8:$imm)))]> {
9294 let Inst{18-16} = imm;
9297 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9298 V64, V64, vecshiftL16,
9300 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
9301 (i32 vecshiftL16:$imm)))]> {
9303 let Inst{19-16} = imm;
9306 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9307 V128, V128, vecshiftL16,
9309 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
9310 (i32 vecshiftL16:$imm)))]> {
9312 let Inst{19-16} = imm;
9315 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9316 V64, V64, vecshiftL32,
9318 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
9319 (i32 vecshiftL32:$imm)))]> {
9321 let Inst{20-16} = imm;
9324 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9325 V128, V128, vecshiftL32,
9327 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
9328 (i32 vecshiftL32:$imm)))]> {
9330 let Inst{20-16} = imm;
9333 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9334 V128, V128, vecshiftL64,
9336 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
9337 (i32 vecshiftL64:$imm)))]> {
9339 let Inst{21-16} = imm;
9343 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
9344 SDPatternOperator OpNode> {
9345 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9346 V64, V64, vecshiftR8,
9348 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
9349 (i32 vecshiftR8:$imm)))]> {
9351 let Inst{18-16} = imm;
9354 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9355 V128, V128, vecshiftR8,
9356 asm, ".16b", ".16b",
9357 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
9358 (i32 vecshiftR8:$imm)))]> {
9360 let Inst{18-16} = imm;
9363 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9364 V64, V64, vecshiftR16,
9366 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
9367 (i32 vecshiftR16:$imm)))]> {
9369 let Inst{19-16} = imm;
9372 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9373 V128, V128, vecshiftR16,
9375 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
9376 (i32 vecshiftR16:$imm)))]> {
9378 let Inst{19-16} = imm;
9381 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9382 V64, V64, vecshiftR32,
9384 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
9385 (i32 vecshiftR32:$imm)))]> {
9387 let Inst{20-16} = imm;
9390 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9391 V128, V128, vecshiftR32,
9393 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
9394 (i32 vecshiftR32:$imm)))]> {
9396 let Inst{20-16} = imm;
9399 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
9400 V128, V128, vecshiftR64,
9402 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
9403 (i32 vecshiftR64:$imm)))]> {
9405 let Inst{21-16} = imm;
9409 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9410 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
9411 SDPatternOperator OpNode = null_frag> {
9412 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
9413 V64, V64, vecshiftR8, asm, ".8b", ".8b",
9414 [(set (v8i8 V64:$dst),
9415 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
9416 (i32 vecshiftR8:$imm)))]> {
9418 let Inst{18-16} = imm;
9421 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9422 V128, V128, vecshiftR8, asm, ".16b", ".16b",
9423 [(set (v16i8 V128:$dst),
9424 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
9425 (i32 vecshiftR8:$imm)))]> {
9427 let Inst{18-16} = imm;
9430 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
9431 V64, V64, vecshiftR16, asm, ".4h", ".4h",
9432 [(set (v4i16 V64:$dst),
9433 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
9434 (i32 vecshiftR16:$imm)))]> {
9436 let Inst{19-16} = imm;
9439 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9440 V128, V128, vecshiftR16, asm, ".8h", ".8h",
9441 [(set (v8i16 V128:$dst),
9442 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9443 (i32 vecshiftR16:$imm)))]> {
9445 let Inst{19-16} = imm;
9448 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
9449 V64, V64, vecshiftR32, asm, ".2s", ".2s",
9450 [(set (v2i32 V64:$dst),
9451 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9452 (i32 vecshiftR32:$imm)))]> {
9454 let Inst{20-16} = imm;
9457 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9458 V128, V128, vecshiftR32, asm, ".4s", ".4s",
9459 [(set (v4i32 V128:$dst),
9460 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9461 (i32 vecshiftR32:$imm)))]> {
9463 let Inst{20-16} = imm;
9466 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
9467 V128, V128, vecshiftR64,
9468 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
9469 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
9470 (i32 vecshiftR64:$imm)))]> {
9472 let Inst{21-16} = imm;
9476 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
9477 SDPatternOperator OpNode = null_frag> {
9478 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
9479 V64, V64, vecshiftL8,
9481 [(set (v8i8 V64:$dst),
9482 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
9483 (i32 vecshiftL8:$imm)))]> {
9485 let Inst{18-16} = imm;
9488 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
9489 V128, V128, vecshiftL8,
9490 asm, ".16b", ".16b",
9491 [(set (v16i8 V128:$dst),
9492 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
9493 (i32 vecshiftL8:$imm)))]> {
9495 let Inst{18-16} = imm;
9498 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
9499 V64, V64, vecshiftL16,
9501 [(set (v4i16 V64:$dst),
9502 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
9503 (i32 vecshiftL16:$imm)))]> {
9505 let Inst{19-16} = imm;
9508 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
9509 V128, V128, vecshiftL16,
9511 [(set (v8i16 V128:$dst),
9512 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
9513 (i32 vecshiftL16:$imm)))]> {
9515 let Inst{19-16} = imm;
9518 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
9519 V64, V64, vecshiftL32,
9521 [(set (v2i32 V64:$dst),
9522 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
9523 (i32 vecshiftL32:$imm)))]> {
9525 let Inst{20-16} = imm;
9528 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
9529 V128, V128, vecshiftL32,
9531 [(set (v4i32 V128:$dst),
9532 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9533 (i32 vecshiftL32:$imm)))]> {
9535 let Inst{20-16} = imm;
9538 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
9539 V128, V128, vecshiftL64,
9541 [(set (v2i64 V128:$dst),
9542 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
9543 (i32 vecshiftL64:$imm)))]> {
9545 let Inst{21-16} = imm;
9549 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
9550 SDPatternOperator OpNode> {
9551 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
9552 V128, V64, vecshiftL8, asm, ".8h", ".8b",
9553 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
9555 let Inst{18-16} = imm;
9558 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
9559 V128, V128, vecshiftL8,
9560 asm#"2", ".8h", ".16b",
9561 [(set (v8i16 V128:$Rd),
9562 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
9564 let Inst{18-16} = imm;
9567 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
9568 V128, V64, vecshiftL16, asm, ".4s", ".4h",
9569 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
9571 let Inst{19-16} = imm;
9574 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
9575 V128, V128, vecshiftL16,
9576 asm#"2", ".4s", ".8h",
9577 [(set (v4i32 V128:$Rd),
9578 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
9581 let Inst{19-16} = imm;
9584 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
9585 V128, V64, vecshiftL32, asm, ".2d", ".2s",
9586 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
9588 let Inst{20-16} = imm;
9591 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
9592 V128, V128, vecshiftL32,
9593 asm#"2", ".2d", ".4s",
9594 [(set (v2i64 V128:$Rd),
9595 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
9597 let Inst{20-16} = imm;
9603 // Vector load/store
9605 // SIMD ldX/stX no-index memory references don't allow the optional
9606 // ", #0" constant and handle post-indexing explicitly, so we use
9607 // a more specialized parse method for them. Otherwise, it's the same as
9608 // the general GPR64sp handling.
9610 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
9611 string asm, dag oops, dag iops, list<dag> pattern>
9612 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
9617 let Inst{29-23} = 0b0011000;
9619 let Inst{21-16} = 0b000000;
9620 let Inst{15-12} = opcode;
9621 let Inst{11-10} = size;
9626 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
9627 string asm, dag oops, dag iops>
9628 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
9634 let Inst{29-23} = 0b0011001;
9637 let Inst{20-16} = Xm;
9638 let Inst{15-12} = opcode;
9639 let Inst{11-10} = size;
9644 // The immediate form of AdvSIMD post-indexed addressing is encoded with
9645 // register post-index addressing from the zero register.
9646 multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
9647 int Offset, int Size> {
9648 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
9649 // "ld1\t$Vt, [$Rn], #16"
9650 // may get mapped to
9651 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
9652 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9653 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9655 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9658 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
9659 // "ld1.8b\t$Vt, [$Rn], #16"
9660 // may get mapped to
9661 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
9662 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9663 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9665 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9668 // E.g. "ld1.8b { v0, v1 }, [x1]"
9669 // "ld1\t$Vt, [$Rn]"
9670 // may get mapped to
9671 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
9672 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9673 (!cast<Instruction>(BaseName # Count # "v" # layout)
9674 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9677 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
9678 // "ld1\t$Vt, [$Rn], $Xm"
9679 // may get mapped to
9680 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
9681 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9682 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
9684 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9685 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9688 multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
9689 int Offset128, int Offset64, bits<4> opcode> {
9690 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9691 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
9692 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
9693 (ins GPR64sp:$Rn), []>;
9694 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
9695 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
9696 (ins GPR64sp:$Rn), []>;
9697 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
9698 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
9699 (ins GPR64sp:$Rn), []>;
9700 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
9701 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
9702 (ins GPR64sp:$Rn), []>;
9703 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
9704 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
9705 (ins GPR64sp:$Rn), []>;
9706 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
9707 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
9708 (ins GPR64sp:$Rn), []>;
9709 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
9710 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
9711 (ins GPR64sp:$Rn), []>;
9714 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
9715 (outs GPR64sp:$wback,
9716 !cast<RegisterOperand>(veclist # "16b"):$Vt),
9718 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9719 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
9720 (outs GPR64sp:$wback,
9721 !cast<RegisterOperand>(veclist # "8h"):$Vt),
9723 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9724 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
9725 (outs GPR64sp:$wback,
9726 !cast<RegisterOperand>(veclist # "4s"):$Vt),
9728 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9729 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
9730 (outs GPR64sp:$wback,
9731 !cast<RegisterOperand>(veclist # "2d"):$Vt),
9733 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9734 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
9735 (outs GPR64sp:$wback,
9736 !cast<RegisterOperand>(veclist # "8b"):$Vt),
9738 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9739 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
9740 (outs GPR64sp:$wback,
9741 !cast<RegisterOperand>(veclist # "4h"):$Vt),
9743 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9744 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
9745 (outs GPR64sp:$wback,
9746 !cast<RegisterOperand>(veclist # "2s"):$Vt),
9748 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9751 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9752 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9753 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9754 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9755 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9756 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9757 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9760 // Only ld1/st1 has a v1d version.
9761 multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
9762 int Offset128, int Offset64, bits<4> opcode> {
9763 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
9764 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
9765 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9767 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
9768 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9770 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
9771 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9773 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
9774 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9776 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
9777 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9779 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
9780 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9782 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
9783 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9786 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
9787 (outs GPR64sp:$wback),
9788 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
9790 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9791 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
9792 (outs GPR64sp:$wback),
9793 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
9795 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9796 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
9797 (outs GPR64sp:$wback),
9798 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
9800 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9801 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
9802 (outs GPR64sp:$wback),
9803 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
9805 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
9806 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
9807 (outs GPR64sp:$wback),
9808 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
9810 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9811 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
9812 (outs GPR64sp:$wback),
9813 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
9815 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9816 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
9817 (outs GPR64sp:$wback),
9818 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
9820 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9823 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
9824 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
9825 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
9826 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
9827 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
9828 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
9829 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
9832 multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
9833 int Offset128, int Offset64, bits<4> opcode>
9834 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9836 // LD1 instructions have extra "1d" variants.
9837 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
9838 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
9839 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
9840 (ins GPR64sp:$Rn), []>;
9842 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
9843 (outs GPR64sp:$wback,
9844 !cast<RegisterOperand>(veclist # "1d"):$Vt),
9846 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9849 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9852 multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
9853 int Offset128, int Offset64, bits<4> opcode>
9854 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
9856 // ST1 instructions have extra "1d" variants.
9857 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
9858 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
9859 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9862 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
9863 (outs GPR64sp:$wback),
9864 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
9866 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
9869 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
9872 multiclass SIMDLd1Multiple<string asm> {
9873 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
9874 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9875 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9876 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9879 multiclass SIMDSt1Multiple<string asm> {
9880 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
9881 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
9882 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
9883 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
9886 multiclass SIMDLd2Multiple<string asm> {
9887 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9890 multiclass SIMDSt2Multiple<string asm> {
9891 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
9894 multiclass SIMDLd3Multiple<string asm> {
9895 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9898 multiclass SIMDSt3Multiple<string asm> {
9899 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
9902 multiclass SIMDLd4Multiple<string asm> {
9903 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9906 multiclass SIMDSt4Multiple<string asm> {
9907 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
9911 // AdvSIMD Load/store single-element
9914 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
9915 string asm, string operands, string cst,
9916 dag oops, dag iops, list<dag> pattern>
9917 : I<oops, iops, asm, operands, cst, pattern> {
9921 let Inst{29-24} = 0b001101;
9924 let Inst{15-13} = opcode;
9929 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
9930 string asm, string operands, string cst,
9931 dag oops, dag iops, list<dag> pattern>
9932 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
9936 let Inst{29-24} = 0b001101;
9939 let Inst{15-13} = opcode;
9945 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9946 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
9947 DAGOperand listtype>
9948 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
9949 (outs listtype:$Vt), (ins GPR64sp:$Rn),
9953 let Inst{20-16} = 0b00000;
9955 let Inst{11-10} = size;
9957 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9958 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
9959 string asm, DAGOperand listtype, DAGOperand GPR64pi>
9960 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
9962 (outs GPR64sp:$wback, listtype:$Vt),
9963 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
9967 let Inst{20-16} = Xm;
9969 let Inst{11-10} = size;
9972 multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
9973 int Offset, int Size> {
9974 // E.g. "ld1r { v0.8b }, [x1], #1"
9975 // "ld1r.8b\t$Vt, [$Rn], #1"
9976 // may get mapped to
9977 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9978 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9979 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9981 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9984 // E.g. "ld1r.8b { v0 }, [x1], #1"
9985 // "ld1r.8b\t$Vt, [$Rn], #1"
9986 // may get mapped to
9987 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9988 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9989 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9991 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9994 // E.g. "ld1r.8b { v0 }, [x1]"
9995 // "ld1r.8b\t$Vt, [$Rn]"
9996 // may get mapped to
9997 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9998 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9999 (!cast<Instruction>(BaseName # "v" # layout)
10000 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10003 // E.g. "ld1r.8b { v0 }, [x1], x2"
10004 // "ld1r.8b\t$Vt, [$Rn], $Xm"
10005 // may get mapped to
10006 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
10007 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
10008 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
10010 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
10011 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
10014 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
10015 int Offset1, int Offset2, int Offset4, int Offset8> {
10016 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
10017 !cast<DAGOperand>("VecList" # Count # "8b")>;
10018 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
10019 !cast<DAGOperand>("VecList" # Count #"16b")>;
10020 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
10021 !cast<DAGOperand>("VecList" # Count #"4h")>;
10022 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
10023 !cast<DAGOperand>("VecList" # Count #"8h")>;
10024 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
10025 !cast<DAGOperand>("VecList" # Count #"2s")>;
10026 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
10027 !cast<DAGOperand>("VecList" # Count #"4s")>;
10028 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
10029 !cast<DAGOperand>("VecList" # Count #"1d")>;
10030 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
10031 !cast<DAGOperand>("VecList" # Count #"2d")>;
10033 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
10034 !cast<DAGOperand>("VecList" # Count # "8b"),
10035 !cast<DAGOperand>("GPR64pi" # Offset1)>;
10036 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
10037 !cast<DAGOperand>("VecList" # Count # "16b"),
10038 !cast<DAGOperand>("GPR64pi" # Offset1)>;
10039 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
10040 !cast<DAGOperand>("VecList" # Count # "4h"),
10041 !cast<DAGOperand>("GPR64pi" # Offset2)>;
10042 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
10043 !cast<DAGOperand>("VecList" # Count # "8h"),
10044 !cast<DAGOperand>("GPR64pi" # Offset2)>;
10045 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
10046 !cast<DAGOperand>("VecList" # Count # "2s"),
10047 !cast<DAGOperand>("GPR64pi" # Offset4)>;
10048 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
10049 !cast<DAGOperand>("VecList" # Count # "4s"),
10050 !cast<DAGOperand>("GPR64pi" # Offset4)>;
10051 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
10052 !cast<DAGOperand>("VecList" # Count # "1d"),
10053 !cast<DAGOperand>("GPR64pi" # Offset8)>;
10054 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
10055 !cast<DAGOperand>("VecList" # Count # "2d"),
10056 !cast<DAGOperand>("GPR64pi" # Offset8)>;
10058 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>;
10059 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
10060 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>;
10061 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>;
10062 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>;
10063 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>;
10064 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>;
10065 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>;
10068 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
10069 dag oops, dag iops, list<dag> pattern>
10070 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10072 // idx encoded in Q:S:size fields.
10074 let Inst{30} = idx{3};
10076 let Inst{20-16} = 0b00000;
10077 let Inst{12} = idx{2};
10078 let Inst{11-10} = idx{1-0};
10080 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
10081 dag oops, dag iops, list<dag> pattern>
10082 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10083 oops, iops, pattern> {
10084 // idx encoded in Q:S:size fields.
10086 let Inst{30} = idx{3};
10088 let Inst{20-16} = 0b00000;
10089 let Inst{12} = idx{2};
10090 let Inst{11-10} = idx{1-0};
10092 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
10093 dag oops, dag iops>
10094 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10095 "$Rn = $wback", oops, iops, []> {
10096 // idx encoded in Q:S:size fields.
10099 let Inst{30} = idx{3};
10101 let Inst{20-16} = Xm;
10102 let Inst{12} = idx{2};
10103 let Inst{11-10} = idx{1-0};
10105 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
10106 dag oops, dag iops>
10107 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10108 "$Rn = $wback", oops, iops, []> {
10109 // idx encoded in Q:S:size fields.
10112 let Inst{30} = idx{3};
10114 let Inst{20-16} = Xm;
10115 let Inst{12} = idx{2};
10116 let Inst{11-10} = idx{1-0};
10119 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
10120 dag oops, dag iops, list<dag> pattern>
10121 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10123 // idx encoded in Q:S:size<1> fields.
10125 let Inst{30} = idx{2};
10127 let Inst{20-16} = 0b00000;
10128 let Inst{12} = idx{1};
10129 let Inst{11} = idx{0};
10130 let Inst{10} = size;
10132 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
10133 dag oops, dag iops, list<dag> pattern>
10134 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10135 oops, iops, pattern> {
10136 // idx encoded in Q:S:size<1> fields.
10138 let Inst{30} = idx{2};
10140 let Inst{20-16} = 0b00000;
10141 let Inst{12} = idx{1};
10142 let Inst{11} = idx{0};
10143 let Inst{10} = size;
10146 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10147 dag oops, dag iops>
10148 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10149 "$Rn = $wback", oops, iops, []> {
10150 // idx encoded in Q:S:size<1> fields.
10153 let Inst{30} = idx{2};
10155 let Inst{20-16} = Xm;
10156 let Inst{12} = idx{1};
10157 let Inst{11} = idx{0};
10158 let Inst{10} = size;
10160 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
10161 dag oops, dag iops>
10162 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10163 "$Rn = $wback", oops, iops, []> {
10164 // idx encoded in Q:S:size<1> fields.
10167 let Inst{30} = idx{2};
10169 let Inst{20-16} = Xm;
10170 let Inst{12} = idx{1};
10171 let Inst{11} = idx{0};
10172 let Inst{10} = size;
10174 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10175 dag oops, dag iops, list<dag> pattern>
10176 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10178 // idx encoded in Q:S fields.
10180 let Inst{30} = idx{1};
10182 let Inst{20-16} = 0b00000;
10183 let Inst{12} = idx{0};
10184 let Inst{11-10} = size;
10186 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10187 dag oops, dag iops, list<dag> pattern>
10188 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10189 oops, iops, pattern> {
10190 // idx encoded in Q:S fields.
10192 let Inst{30} = idx{1};
10194 let Inst{20-16} = 0b00000;
10195 let Inst{12} = idx{0};
10196 let Inst{11-10} = size;
10198 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
10199 string asm, dag oops, dag iops>
10200 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10201 "$Rn = $wback", oops, iops, []> {
10202 // idx encoded in Q:S fields.
10205 let Inst{30} = idx{1};
10207 let Inst{20-16} = Xm;
10208 let Inst{12} = idx{0};
10209 let Inst{11-10} = size;
10211 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
10212 string asm, dag oops, dag iops>
10213 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10214 "$Rn = $wback", oops, iops, []> {
10215 // idx encoded in Q:S fields.
10218 let Inst{30} = idx{1};
10220 let Inst{20-16} = Xm;
10221 let Inst{12} = idx{0};
10222 let Inst{11-10} = size;
10224 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10225 dag oops, dag iops, list<dag> pattern>
10226 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
10228 // idx encoded in Q field.
10230 let Inst{30} = idx;
10232 let Inst{20-16} = 0b00000;
10234 let Inst{11-10} = size;
10236 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
10237 dag oops, dag iops, list<dag> pattern>
10238 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
10239 oops, iops, pattern> {
10240 // idx encoded in Q field.
10242 let Inst{30} = idx;
10244 let Inst{20-16} = 0b00000;
10246 let Inst{11-10} = size;
10248 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
10249 string asm, dag oops, dag iops>
10250 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10251 "$Rn = $wback", oops, iops, []> {
10252 // idx encoded in Q field.
10255 let Inst{30} = idx;
10257 let Inst{20-16} = Xm;
10259 let Inst{11-10} = size;
10261 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
10262 string asm, dag oops, dag iops>
10263 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
10264 "$Rn = $wback", oops, iops, []> {
10265 // idx encoded in Q field.
10268 let Inst{30} = idx;
10270 let Inst{20-16} = Xm;
10272 let Inst{11-10} = size;
10275 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10276 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
10277 RegisterOperand listtype,
10278 RegisterOperand GPR64pi> {
10279 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
10280 (outs listtype:$dst),
10281 (ins listtype:$Vt, VectorIndexB:$idx,
10284 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
10285 (outs GPR64sp:$wback, listtype:$dst),
10286 (ins listtype:$Vt, VectorIndexB:$idx,
10287 GPR64sp:$Rn, GPR64pi:$Xm)>;
10289 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10290 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
10291 RegisterOperand listtype,
10292 RegisterOperand GPR64pi> {
10293 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
10294 (outs listtype:$dst),
10295 (ins listtype:$Vt, VectorIndexH:$idx,
10298 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
10299 (outs GPR64sp:$wback, listtype:$dst),
10300 (ins listtype:$Vt, VectorIndexH:$idx,
10301 GPR64sp:$Rn, GPR64pi:$Xm)>;
10303 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10304 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
10305 RegisterOperand listtype,
10306 RegisterOperand GPR64pi> {
10307 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
10308 (outs listtype:$dst),
10309 (ins listtype:$Vt, VectorIndexS:$idx,
10312 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
10313 (outs GPR64sp:$wback, listtype:$dst),
10314 (ins listtype:$Vt, VectorIndexS:$idx,
10315 GPR64sp:$Rn, GPR64pi:$Xm)>;
10317 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
10318 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
10319 RegisterOperand listtype, RegisterOperand GPR64pi> {
10320 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
10321 (outs listtype:$dst),
10322 (ins listtype:$Vt, VectorIndexD:$idx,
10325 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
10326 (outs GPR64sp:$wback, listtype:$dst),
10327 (ins listtype:$Vt, VectorIndexD:$idx,
10328 GPR64sp:$Rn, GPR64pi:$Xm)>;
10330 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10331 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
10332 RegisterOperand listtype, RegisterOperand GPR64pi> {
10333 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
10334 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
10337 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
10338 (outs GPR64sp:$wback),
10339 (ins listtype:$Vt, VectorIndexB:$idx,
10340 GPR64sp:$Rn, GPR64pi:$Xm)>;
10342 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10343 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
10344 RegisterOperand listtype, RegisterOperand GPR64pi> {
10345 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
10346 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
10349 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
10350 (outs GPR64sp:$wback),
10351 (ins listtype:$Vt, VectorIndexH:$idx,
10352 GPR64sp:$Rn, GPR64pi:$Xm)>;
10354 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10355 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
10356 RegisterOperand listtype, RegisterOperand GPR64pi> {
10357 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
10358 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
10361 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
10362 (outs GPR64sp:$wback),
10363 (ins listtype:$Vt, VectorIndexS:$idx,
10364 GPR64sp:$Rn, GPR64pi:$Xm)>;
10366 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
10367 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
10368 RegisterOperand listtype, RegisterOperand GPR64pi> {
10369 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
10370 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
10373 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
10374 (outs GPR64sp:$wback),
10375 (ins listtype:$Vt, VectorIndexD:$idx,
10376 GPR64sp:$Rn, GPR64pi:$Xm)>;
10379 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
10380 string Count, int Offset, Operand idxtype> {
10381 // E.g. "ld1 { v0.8b }[0], [x1], #1"
10382 // "ld1\t$Vt, [$Rn], #1"
10383 // may get mapped to
10384 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
10385 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
10386 (!cast<Instruction>(NAME # Type # "_POST")
10388 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
10389 idxtype:$idx, XZR), 1>;
10391 // E.g. "ld1.8b { v0 }[0], [x1], #1"
10392 // "ld1.8b\t$Vt, [$Rn], #1"
10393 // may get mapped to
10394 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
10395 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
10396 (!cast<Instruction>(NAME # Type # "_POST")
10398 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10399 idxtype:$idx, XZR), 0>;
10401 // E.g. "ld1.8b { v0 }[0], [x1]"
10402 // "ld1.8b\t$Vt, [$Rn]"
10403 // may get mapped to
10404 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
10405 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
10406 (!cast<Instruction>(NAME # Type)
10407 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10408 idxtype:$idx, GPR64sp:$Rn), 0>;
10410 // E.g. "ld1.8b { v0 }[0], [x1], x2"
10411 // "ld1.8b\t$Vt, [$Rn], $Xm"
10412 // may get mapped to
10413 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
10414 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
10415 (!cast<Instruction>(NAME # Type # "_POST")
10417 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
10419 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
10422 multiclass SIMDLdSt1SingleAliases<string asm> {
10423 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
10424 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
10425 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
10426 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
10429 multiclass SIMDLdSt2SingleAliases<string asm> {
10430 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
10431 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
10432 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
10433 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
10436 multiclass SIMDLdSt3SingleAliases<string asm> {
10437 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
10438 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
10439 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
10440 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
10443 multiclass SIMDLdSt4SingleAliases<string asm> {
10444 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
10445 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
10446 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
10447 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
10449 } // end of 'let Predicates = [HasNEON]'
10451 //----------------------------------------------------------------------------
10452 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
10453 //----------------------------------------------------------------------------
10455 let Predicates = [HasNEON, HasRDM] in {
10457 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
10458 RegisterOperand regtype, string asm,
10459 string kind, list<dag> pattern>
10460 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
10463 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
10464 SDPatternOperator Accum> {
10465 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
10466 [(set (v4i16 V64:$dst),
10467 (Accum (v4i16 V64:$Rd),
10468 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
10469 (v4i16 V64:$Rm)))))]>;
10470 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
10471 [(set (v8i16 V128:$dst),
10472 (Accum (v8i16 V128:$Rd),
10473 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
10474 (v8i16 V128:$Rm)))))]>;
10475 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
10476 [(set (v2i32 V64:$dst),
10477 (Accum (v2i32 V64:$Rd),
10478 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
10479 (v2i32 V64:$Rm)))))]>;
10480 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
10481 [(set (v4i32 V128:$dst),
10482 (Accum (v4i32 V128:$Rd),
10483 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
10484 (v4i32 V128:$Rm)))))]>;
10487 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
10488 SDPatternOperator Accum> {
10489 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
10490 V64, V64, V128_lo, VectorIndexH,
10491 asm, ".4h", ".4h", ".4h", ".h",
10492 [(set (v4i16 V64:$dst),
10493 (Accum (v4i16 V64:$Rd),
10494 (v4i16 (int_aarch64_neon_sqrdmulh
10496 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10497 VectorIndexH:$idx))))))]> {
10499 let Inst{11} = idx{2};
10500 let Inst{21} = idx{1};
10501 let Inst{20} = idx{0};
10504 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
10505 V128, V128, V128_lo, VectorIndexH,
10506 asm, ".8h", ".8h", ".8h", ".h",
10507 [(set (v8i16 V128:$dst),
10508 (Accum (v8i16 V128:$Rd),
10509 (v8i16 (int_aarch64_neon_sqrdmulh
10511 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
10512 VectorIndexH:$idx))))))]> {
10514 let Inst{11} = idx{2};
10515 let Inst{21} = idx{1};
10516 let Inst{20} = idx{0};
10519 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
10520 V64, V64, V128, VectorIndexS,
10521 asm, ".2s", ".2s", ".2s", ".s",
10522 [(set (v2i32 V64:$dst),
10523 (Accum (v2i32 V64:$Rd),
10524 (v2i32 (int_aarch64_neon_sqrdmulh
10526 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
10527 VectorIndexS:$idx))))))]> {
10529 let Inst{11} = idx{1};
10530 let Inst{21} = idx{0};
10533 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10534 // an intermediate EXTRACT_SUBREG would be untyped.
10535 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
10536 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
10537 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10538 (i32 (vector_extract
10539 (v4i32 (insert_subvector
10541 (v2i32 (int_aarch64_neon_sqrdmulh
10543 (v2i32 (AArch64duplane32
10545 VectorIndexS:$idx)))),
10549 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
10550 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
10555 VectorIndexS:$idx)),
10558 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
10559 V128, V128, V128, VectorIndexS,
10560 asm, ".4s", ".4s", ".4s", ".s",
10561 [(set (v4i32 V128:$dst),
10562 (Accum (v4i32 V128:$Rd),
10563 (v4i32 (int_aarch64_neon_sqrdmulh
10565 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
10566 VectorIndexS:$idx))))))]> {
10568 let Inst{11} = idx{1};
10569 let Inst{21} = idx{0};
10572 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
10573 // an intermediate EXTRACT_SUBREG would be untyped.
10574 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
10575 (i32 (vector_extract
10576 (v4i32 (int_aarch64_neon_sqrdmulh
10578 (v4i32 (AArch64duplane32
10580 VectorIndexS:$idx)))),
10583 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
10584 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
10589 VectorIndexS:$idx)),
10592 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
10593 FPR16Op, FPR16Op, V128_lo,
10594 VectorIndexH, asm, ".h", "", "", ".h",
10597 let Inst{11} = idx{2};
10598 let Inst{21} = idx{1};
10599 let Inst{20} = idx{0};
10602 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
10603 FPR32Op, FPR32Op, V128, VectorIndexS,
10604 asm, ".s", "", "", ".s",
10605 [(set (i32 FPR32Op:$dst),
10606 (Accum (i32 FPR32Op:$Rd),
10607 (i32 (int_aarch64_neon_sqrdmulh
10609 (i32 (vector_extract (v4i32 V128:$Rm),
10610 VectorIndexS:$idx))))))]> {
10612 let Inst{11} = idx{1};
10613 let Inst{21} = idx{0};
10616 } // let Predicates = [HasNeon, HasRDM]
10618 //----------------------------------------------------------------------------
10619 // ARMv8.3 Complex ADD/MLA instructions
10620 //----------------------------------------------------------------------------
10622 class ComplexRotationOperand<int Angle, int Remainder, string Type>
10623 : AsmOperandClass {
10624 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
10625 let DiagnosticType = "InvalidComplexRotation" # Type;
10626 let Name = "ComplexRotation" # Type;
10628 def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],
10629 SDNodeXForm<imm, [{
10630 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32);
10632 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
10633 let PrintMethod = "printComplexRotationOp<90, 0>";
10635 def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],
10636 SDNodeXForm<imm, [{
10637 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32);
10639 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
10640 let PrintMethod = "printComplexRotationOp<180, 90>";
10642 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10643 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
10644 RegisterOperand regtype, Operand rottype,
10645 string asm, string kind, list<dag> pattern>
10646 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10647 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10648 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
10657 let Inst{28-24} = 0b01110;
10658 let Inst{23-22} = size;
10660 let Inst{20-16} = Rm;
10661 let Inst{15-13} = opcode;
10662 // Non-tied version (FCADD) only has one rotation bit
10663 let Inst{12} = rot;
10666 let Inst{9-5} = Rn;
10667 let Inst{4-0} = Rd;
10670 //8.3 CompNum - Floating-point complex number support
10671 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
10672 string asm, SDPatternOperator OpNode>{
10673 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10674 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
10676 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10679 (i32 rottype:$rot)))]>;
10681 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
10683 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10686 (i32 rottype:$rot)))]>;
10689 let Predicates = [HasComplxNum, HasNEON] in {
10690 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
10692 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10695 (i32 rottype:$rot)))]>;
10697 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
10699 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10702 (i32 rottype:$rot)))]>;
10704 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
10706 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10709 (i32 rottype:$rot)))]>;
10713 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10714 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
10716 RegisterOperand regtype,
10717 Operand rottype, string asm,
10718 string kind, list<dag> pattern>
10719 : I<(outs regtype:$dst),
10720 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
10721 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
10722 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
10731 let Inst{28-24} = 0b01110;
10732 let Inst{23-22} = size;
10734 let Inst{20-16} = Rm;
10735 let Inst{15-13} = opcode;
10736 let Inst{12-11} = rot;
10738 let Inst{9-5} = Rn;
10739 let Inst{4-0} = Rd;
10742 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
10743 Operand rottype, string asm,
10744 SDPatternOperator OpNode> {
10745 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10746 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
10747 rottype, asm, ".4h",
10748 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
10751 (i32 rottype:$rot)))]>;
10753 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
10754 rottype, asm, ".8h",
10755 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
10758 (i32 rottype:$rot)))]>;
10761 let Predicates = [HasComplxNum, HasNEON] in {
10762 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
10763 rottype, asm, ".2s",
10764 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
10767 (i32 rottype:$rot)))]>;
10769 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
10770 rottype, asm, ".4s",
10771 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
10774 (i32 rottype:$rot)))]>;
10776 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
10777 rottype, asm, ".2d",
10778 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
10781 (i32 rottype:$rot)))]>;
10785 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10786 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
10787 bit opc1, bit opc2, RegisterOperand dst_reg,
10788 RegisterOperand lhs_reg,
10789 RegisterOperand rhs_reg, Operand vec_idx,
10790 Operand rottype, string asm, string apple_kind,
10791 string dst_kind, string lhs_kind,
10792 string rhs_kind, list<dag> pattern>
10793 : I<(outs dst_reg:$dst),
10794 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
10796 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
10797 "$idx, $rot" # "|" # apple_kind #
10798 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
10808 let Inst{28} = Scalar;
10809 let Inst{27-24} = 0b1111;
10810 let Inst{23-22} = size;
10811 // Bit 21 must be set by the derived class.
10812 let Inst{20-16} = Rm;
10813 let Inst{15} = opc1;
10814 let Inst{14-13} = rot;
10815 let Inst{12} = opc2;
10816 // Bit 11 must be set by the derived class.
10818 let Inst{9-5} = Rn;
10819 let Inst{4-0} = Rd;
10822 // The complex instructions index by pairs of elements, so the VectorIndexes
10823 // don't match the lane types, and the index bits are different to the other
10825 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
10826 string asm, SDPatternOperator OpNode> {
10827 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
10828 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
10829 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
10833 let Inst{21} = idx{0};
10836 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
10837 V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
10838 ".8h", ".8h", ".h", []> {
10840 let Inst{11} = idx{1};
10841 let Inst{21} = idx{0};
10843 } // Predicates = HasComplxNum, HasNEON, HasFullFP16]
10845 let Predicates = [HasComplxNum, HasNEON] in {
10846 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
10847 V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
10848 ".4s", ".4s", ".s", []> {
10850 let Inst{11} = idx{0};
10853 } // Predicates = [HasComplxNum, HasNEON]
10856 //----------------------------------------------------------------------------
10857 // Crypto extensions
10858 //----------------------------------------------------------------------------
10860 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10861 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
10863 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
10867 let Inst{31-16} = 0b0100111000101000;
10868 let Inst{15-12} = opc;
10869 let Inst{11-10} = 0b10;
10870 let Inst{9-5} = Rn;
10871 let Inst{4-0} = Rd;
10874 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
10875 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
10876 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
10878 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
10879 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
10881 [(set (v16i8 V128:$dst),
10882 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
10884 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10885 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
10886 dag oops, dag iops, list<dag> pat>
10887 : I<oops, iops, asm,
10888 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
10889 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
10894 let Inst{31-21} = 0b01011110000;
10895 let Inst{20-16} = Rm;
10897 let Inst{14-12} = opc;
10898 let Inst{11-10} = 0b00;
10899 let Inst{9-5} = Rn;
10900 let Inst{4-0} = Rd;
10903 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
10904 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10905 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
10906 [(set (v4i32 FPR128:$dst),
10907 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
10908 (v4i32 V128:$Rm)))]>;
10910 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
10911 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
10912 (ins V128:$Rd, V128:$Rn, V128:$Rm),
10913 [(set (v4i32 V128:$dst),
10914 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
10915 (v4i32 V128:$Rm)))]>;
10917 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
10918 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
10919 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
10920 [(set (v4i32 FPR128:$dst),
10921 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
10922 (v4i32 V128:$Rm)))]>;
10924 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10925 class SHA2OpInst<bits<4> opc, string asm, string kind,
10926 string cstr, dag oops, dag iops,
10928 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
10929 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
10933 let Inst{31-16} = 0b0101111000101000;
10934 let Inst{15-12} = opc;
10935 let Inst{11-10} = 0b10;
10936 let Inst{9-5} = Rn;
10937 let Inst{4-0} = Rd;
10940 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
10941 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
10942 (ins V128:$Rd, V128:$Rn),
10943 [(set (v4i32 V128:$dst),
10944 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
10946 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
10947 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
10948 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
10950 // Armv8.2-A Crypto extensions
10951 class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
10953 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> {
10956 let Inst{31-25} = 0b1100111;
10957 let Inst{9-5} = Vn;
10958 let Inst{4-0} = Vd;
10961 class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
10962 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops,
10963 "$Vd = $Vdst", []> {
10964 let Inst{31-25} = 0b1100111;
10965 let Inst{24-21} = 0b0110;
10966 let Inst{20-15} = 0b000001;
10967 let Inst{14} = op0;
10968 let Inst{13-12} = 0b00;
10969 let Inst{11-10} = op1;
10971 class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
10972 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">;
10973 class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
10974 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">;
10976 class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
10977 string asmops, string cst>
10978 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
10980 let Inst{24-21} = 0b0011;
10981 let Inst{20-16} = Vm;
10982 let Inst{15} = 0b1;
10983 let Inst{14} = op0;
10984 let Inst{13-12} = 0b00;
10985 let Inst{11-10} = op1;
10987 class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
10988 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10989 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">;
10990 class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
10991 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10992 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10993 class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
10994 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10995 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">;
10996 class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
10997 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10998 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
10999 class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
11000 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
11001 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
11003 class CryptoRRRR<bits<2>op0, string asm, string asmops>
11004 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
11008 let Inst{24-23} = 0b00;
11009 let Inst{22-21} = op0;
11010 let Inst{20-16} = Vm;
11011 let Inst{15} = 0b0;
11012 let Inst{14-10} = Va;
11014 class CryptoRRRR_16B<bits<2>op0, string asm>
11015 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" #
11016 "|.16b\t$Vd, $Vn, $Vm, $Va}"> {
11018 class CryptoRRRR_4S<bits<2>op0, string asm>
11019 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" #
11020 "|.4s\t$Vd, $Vn, $Vm, $Va}"> {
11023 class CryptoRRRi6<string asm>
11024 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
11025 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" #
11026 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> {
11029 let Inst{24-21} = 0b0100;
11030 let Inst{20-16} = Vm;
11031 let Inst{15-10} = imm;
11032 let Inst{9-5} = Vn;
11033 let Inst{4-0} = Vd;
11036 class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
11037 : BaseCryptoV82<(outs V128:$Vdst),
11038 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
11039 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" #
11040 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> {
11043 let Inst{24-21} = 0b0010;
11044 let Inst{20-16} = Vm;
11045 let Inst{15} = 0b1;
11046 let Inst{14} = op0;
11047 let Inst{13-12} = imm;
11048 let Inst{11-10} = op1;
11051 //----------------------------------------------------------------------------
11052 // v8.1 atomic instructions extension:
11056 // * LDOPregister<OP>, and aliases STOPregister<OP>
11058 // Instruction encodings:
11060 // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
11061 // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
11062 // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
11063 // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
11064 // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
11065 // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
11067 // Instruction syntax:
11069 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
11070 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
11071 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
11072 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
11073 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
11074 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
11075 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
11076 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
11077 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
11078 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
11080 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
11081 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
11082 string cstr, list<dag> pattern>
11083 : I<oops, iops, asm, operands, cstr, pattern> {
11091 let Inst{31-30} = Sz;
11092 let Inst{29-24} = 0b001000;
11094 let Inst{22} = Acq;
11095 let Inst{21} = 0b1;
11096 let Inst{20-16} = Rs;
11097 let Inst{15} = Rel;
11098 let Inst{14-10} = 0b11111;
11099 let Inst{9-5} = Rn;
11100 let Inst{4-0} = Rt;
11101 let Predicates = [HasLSE];
11104 class BaseCAS<string order, string size, RegisterClass RC>
11105 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11106 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
11108 Sched<[WriteAtomic]> {
11112 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
11113 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
11114 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
11115 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
11116 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
11119 class BaseCASP<string order, string size, RegisterOperand RC>
11120 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
11121 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
11123 Sched<[WriteAtomic]> {
11127 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
11128 let Sz = 0b00, Acq = Acq, Rel = Rel in
11129 def W : BaseCASP<order, "", WSeqPairClassOperand>;
11130 let Sz = 0b01, Acq = Acq, Rel = Rel in
11131 def X : BaseCASP<order, "", XSeqPairClassOperand>;
11134 let Predicates = [HasLSE] in
11135 class BaseSWP<string order, string size, RegisterClass RC>
11136 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
11137 "\t$Rs, $Rt, [$Rn]","",[]>,
11138 Sched<[WriteAtomic]> {
11143 bits<3> opc = 0b000;
11146 let Inst{31-30} = Sz;
11147 let Inst{29-24} = 0b111000;
11148 let Inst{23} = Acq;
11149 let Inst{22} = Rel;
11150 let Inst{21} = 0b1;
11151 let Inst{20-16} = Rs;
11152 let Inst{15} = 0b1;
11153 let Inst{14-12} = opc;
11154 let Inst{11-10} = 0b00;
11155 let Inst{9-5} = Rn;
11156 let Inst{4-0} = Rt;
11157 let Predicates = [HasLSE];
11160 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
11161 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
11162 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
11163 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
11164 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
11167 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
11168 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
11169 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
11170 "\t$Rs, $Rt, [$Rn]","",[]>,
11171 Sched<[WriteAtomic]> {
11179 let Inst{31-30} = Sz;
11180 let Inst{29-24} = 0b111000;
11181 let Inst{23} = Acq;
11182 let Inst{22} = Rel;
11183 let Inst{21} = 0b1;
11184 let Inst{20-16} = Rs;
11185 let Inst{15} = 0b0;
11186 let Inst{14-12} = opc;
11187 let Inst{11-10} = 0b00;
11188 let Inst{9-5} = Rn;
11189 let Inst{4-0} = Rt;
11190 let Predicates = [HasLSE];
11193 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
11195 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
11196 def B : BaseLDOPregister<op, order, "b", GPR32>;
11197 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
11198 def H : BaseLDOPregister<op, order, "h", GPR32>;
11199 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
11200 def W : BaseLDOPregister<op, order, "", GPR32>;
11201 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
11202 def X : BaseLDOPregister<op, order, "", GPR64>;
11205 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
11206 // complex DAG for DstRHS.
11207 let Predicates = [HasLSE] in
11208 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
11209 string size, dag SrcRHS, dag DstRHS> {
11210 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
11211 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
11212 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
11213 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
11214 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
11215 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
11216 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
11217 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11218 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
11219 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
11222 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
11223 string size, dag RHS> {
11224 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
11227 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
11228 string size, dag LHS, dag RHS> {
11229 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
11232 multiclass LDOPregister_patterns<string inst, string op> {
11233 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
11234 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
11235 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
11236 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>;
11239 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
11240 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
11242 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
11243 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
11245 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11246 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
11248 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11249 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
11251 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
11254 let Predicates = [HasLSE] in
11255 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
11256 string size, dag OLD, dag NEW> {
11257 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
11258 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
11259 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
11260 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11261 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
11262 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11263 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
11264 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11265 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
11266 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
11269 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
11270 string size, dag OLD, dag NEW> {
11271 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
11274 multiclass CASregister_patterns<string inst, string op> {
11275 defm : CASregister_patterns_ord<inst, "X", op, "64",
11276 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
11277 defm : CASregister_patterns_ord<inst, "W", op, "32",
11278 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11279 defm : CASregister_patterns_ord<inst, "H", op, "16",
11280 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11281 defm : CASregister_patterns_ord<inst, "B", op, "8",
11282 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
11285 let Predicates = [HasLSE] in
11286 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
11287 Instruction inst> :
11288 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
11290 multiclass STOPregister<string asm, string instr> {
11291 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
11292 !cast<Instruction>(instr # "LB")>;
11293 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
11294 !cast<Instruction>(instr # "LH")>;
11295 def : BaseSTOPregister<asm # "l", GPR32, WZR,
11296 !cast<Instruction>(instr # "LW")>;
11297 def : BaseSTOPregister<asm # "l", GPR64, XZR,
11298 !cast<Instruction>(instr # "LX")>;
11299 def : BaseSTOPregister<asm # "b", GPR32, WZR,
11300 !cast<Instruction>(instr # "B")>;
11301 def : BaseSTOPregister<asm # "h", GPR32, WZR,
11302 !cast<Instruction>(instr # "H")>;
11303 def : BaseSTOPregister<asm, GPR32, WZR,
11304 !cast<Instruction>(instr # "W")>;
11305 def : BaseSTOPregister<asm, GPR64, XZR,
11306 !cast<Instruction>(instr # "X")>;
11309 class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops,
11310 dag iops, dag oops, list<dag> pat>
11311 : I<oops, iops, asm_inst, asm_ops, "", pat>,
11312 Sched<[]> /* FIXME: fill in scheduling details once known */ {
11315 let Inst{31-21} = 0b11111000001;
11317 let Inst{14-12} = opc;
11318 let Inst{11-10} = 0b00;
11319 let Inst{9-5} = Rn;
11320 let Inst{4-0} = Rt;
11322 let Predicates = [HasV8_7a];
11325 class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops,
11326 list<dag> pat = []>
11327 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> {
11328 let Inst{20-16} = 0b11111;
11331 class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []>
11332 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]",
11333 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> {
11335 let Inst{20-16} = Rs;
11338 //----------------------------------------------------------------------------
11339 // Allow the size specifier tokens to be upper case, not just lower.
11340 def : TokenAlias<".4B", ".4b">; // Add dot product
11341 def : TokenAlias<".8B", ".8b">;
11342 def : TokenAlias<".4H", ".4h">;
11343 def : TokenAlias<".2S", ".2s">;
11344 def : TokenAlias<".1D", ".1d">;
11345 def : TokenAlias<".16B", ".16b">;
11346 def : TokenAlias<".8H", ".8h">;
11347 def : TokenAlias<".4S", ".4s">;
11348 def : TokenAlias<".2D", ".2d">;
11349 def : TokenAlias<".1Q", ".1q">;
11350 def : TokenAlias<".2H", ".2h">;
11351 def : TokenAlias<".B", ".b">;
11352 def : TokenAlias<".H", ".h">;
11353 def : TokenAlias<".S", ".s">;
11354 def : TokenAlias<".D", ".d">;
11355 def : TokenAlias<".Q", ".q">;