1//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9//===----------------------------------------------------------------------===// 10// Describe AArch64 instructions format here 11// 12 13// Format specifies the encoding used by the instruction. This is part of the 14// ad-hoc solution used to emit machine instruction encodings by our machine 15// code emitter. 16class Format<bits<2> val> { 17 bits<2> Value = val; 18} 19 20def PseudoFrm : Format<0>; 21def NormalFrm : Format<1>; // Do we need any others? 22 23// Enum describing whether an instruction is 24// destructive in its first source operand. 25class DestructiveInstTypeEnum<bits<4> val> { 26 bits<4> Value = val; 27} 28def NotDestructive : DestructiveInstTypeEnum<0>; 29// Destructive in its first operand and can be MOVPRFX'd, but has no other 30// special properties. 31def DestructiveOther : DestructiveInstTypeEnum<1>; 32def DestructiveUnary : DestructiveInstTypeEnum<2>; 33def DestructiveBinaryImm : DestructiveInstTypeEnum<3>; 34def DestructiveBinaryShImmUnpred : DestructiveInstTypeEnum<4>; 35def DestructiveBinary : DestructiveInstTypeEnum<5>; 36def DestructiveBinaryComm : DestructiveInstTypeEnum<6>; 37def DestructiveBinaryCommWithRev : DestructiveInstTypeEnum<7>; 38def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>; 39def DestructiveUnaryPassthru : DestructiveInstTypeEnum<9>; 40 41class FalseLanesEnum<bits<2> val> { 42 bits<2> Value = val; 43} 44def FalseLanesNone : FalseLanesEnum<0>; 45def FalseLanesZero : FalseLanesEnum<1>; 46def FalseLanesUndef : FalseLanesEnum<2>; 47 48// AArch64 Instruction Format 49class 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"; 60 Format F = f; 61 bits<2> Form = F.Value; 62 63 // Defaults 64 bit isWhile = 0; 65 bit isPTestLike = 0; 66 FalseLanesEnum FalseLanes = FalseLanesNone; 67 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 68 ElementSizeEnum ElementSize = ElementSizeNone; 69 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; 75 76 let Pattern = []; 77 let Constraints = cstr; 78} 79 80class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 81 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 82 83// Pseudo instructions (don't have encoding information) 84class 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; 90 let isPseudo = 1; 91} 92 93// Real instructions (have encoding information) 94class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 95 let Pattern = pattern; 96 let Size = 4; 97} 98 99// Normal instructions 100class I<dag oops, dag iops, string asm, string operands, string cstr, 101 list<dag> pattern> 102 : EncodedI<cstr, pattern> { 103 dag OutOperandList = oops; 104 dag InOperandList = iops; 105 let AsmString = !strconcat(asm, operands); 106} 107 108class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 109class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 110class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 111 112// Helper fragment for an extract of the high portion of a 128-bit vector. The 113// ComplexPattern match both extract_subvector and bitcast(extract_subvector(..)). 114def extract_high_v16i8 : 115 ComplexPattern<v8i8, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 116def extract_high_v8i16 : 117 ComplexPattern<v4i16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 118def extract_high_v4i32 : 119 ComplexPattern<v2i32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 120 121def extract_high_dup_v8i16 : 122 BinOpFrag<(extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 4))>; 123def extract_high_dup_v4i32 : 124 BinOpFrag<(extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 2))>; 125 126//===----------------------------------------------------------------------===// 127// Asm Operand Classes. 128// 129 130// Shifter operand for arithmetic shifted encodings. 131def ShifterOperand : AsmOperandClass { 132 let Name = "Shifter"; 133} 134 135// Shifter operand for mov immediate encodings. 136def MovImm32ShifterOperand : AsmOperandClass { 137 let SuperClasses = [ShifterOperand]; 138 let Name = "MovImm32Shifter"; 139 let RenderMethod = "addShifterOperands"; 140 let DiagnosticType = "InvalidMovImm32Shift"; 141} 142def MovImm64ShifterOperand : AsmOperandClass { 143 let SuperClasses = [ShifterOperand]; 144 let Name = "MovImm64Shifter"; 145 let RenderMethod = "addShifterOperands"; 146 let DiagnosticType = "InvalidMovImm64Shift"; 147} 148 149// Shifter operand for arithmetic register shifted encodings. 150class ArithmeticShifterOperand<int width> : AsmOperandClass { 151 let SuperClasses = [ShifterOperand]; 152 let Name = "ArithmeticShifter" # width; 153 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 154 let RenderMethod = "addShifterOperands"; 155 let DiagnosticType = "AddSubRegShift" # width; 156} 157 158def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 159def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 160 161// Shifter operand for logical register shifted encodings. 162class LogicalShifterOperand<int width> : AsmOperandClass { 163 let SuperClasses = [ShifterOperand]; 164 let Name = "LogicalShifter" # width; 165 let PredicateMethod = "isLogicalShifter<" # width # ">"; 166 let RenderMethod = "addShifterOperands"; 167 let DiagnosticType = "AddSubRegShift" # width; 168} 169 170def LogicalShifterOperand32 : LogicalShifterOperand<32>; 171def LogicalShifterOperand64 : LogicalShifterOperand<64>; 172 173// Shifter operand for logical vector 128/64-bit shifted encodings. 174def LogicalVecShifterOperand : AsmOperandClass { 175 let SuperClasses = [ShifterOperand]; 176 let Name = "LogicalVecShifter"; 177 let RenderMethod = "addShifterOperands"; 178} 179def LogicalVecHalfWordShifterOperand : AsmOperandClass { 180 let SuperClasses = [LogicalVecShifterOperand]; 181 let Name = "LogicalVecHalfWordShifter"; 182 let RenderMethod = "addShifterOperands"; 183} 184 185// The "MSL" shifter on the vector MOVI instruction. 186def MoveVecShifterOperand : AsmOperandClass { 187 let SuperClasses = [ShifterOperand]; 188 let Name = "MoveVecShifter"; 189 let RenderMethod = "addShifterOperands"; 190} 191 192// Extend operand for arithmetic encodings. 193def ExtendOperand : AsmOperandClass { 194 let Name = "Extend"; 195 let DiagnosticType = "AddSubRegExtendLarge"; 196} 197def ExtendOperand64 : AsmOperandClass { 198 let SuperClasses = [ExtendOperand]; 199 let Name = "Extend64"; 200 let DiagnosticType = "AddSubRegExtendSmall"; 201} 202// 'extend' that's a lsl of a 64-bit register. 203def ExtendOperandLSL64 : AsmOperandClass { 204 let SuperClasses = [ExtendOperand]; 205 let Name = "ExtendLSL64"; 206 let RenderMethod = "addExtend64Operands"; 207 let DiagnosticType = "AddSubRegExtendLarge"; 208} 209 210// 8-bit floating-point immediate encodings. 211def FPImmOperand : AsmOperandClass { 212 let Name = "FPImm"; 213 let ParserMethod = "tryParseFPImm<true>"; 214 let DiagnosticType = "InvalidFPImm"; 215} 216 217def CondCode : AsmOperandClass { 218 let Name = "CondCode"; 219 let DiagnosticType = "InvalidCondCode"; 220} 221 222// A 32-bit register pasrsed as 64-bit 223def GPR32as64Operand : AsmOperandClass { 224 let Name = "GPR32as64"; 225 let ParserMethod = 226 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 227} 228def GPR32as64 : RegisterOperand<GPR32> { 229 let ParserMatchClass = GPR32as64Operand; 230} 231 232// A 64-bit register pasrsed as 32-bit 233def GPR64as32Operand : AsmOperandClass { 234 let Name = "GPR64as32"; 235 let ParserMethod = 236 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 237} 238def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 239 let ParserMatchClass = GPR64as32Operand; 240} 241 242// 8-bit immediate for AdvSIMD where 64-bit values of the form: 243// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 244// are encoded as the eight bit value 'abcdefgh'. 245def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 246 247class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 248 let Name = "UImm" # Width # "s" # Scale; 249 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 250 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 251 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 252} 253 254class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 255 let Name = "SImm" # Width # "s" # Scale; 256 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 257 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 258 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 259} 260 261//===----------------------------------------------------------------------===// 262// Operand Definitions. 263// 264 265// ADR[P] instruction labels. 266def AdrpOperand : AsmOperandClass { 267 let Name = "AdrpLabel"; 268 let ParserMethod = "tryParseAdrpLabel"; 269 let DiagnosticType = "InvalidLabel"; 270} 271def adrplabel : Operand<i64> { 272 let EncoderMethod = "getAdrLabelOpValue"; 273 let PrintMethod = "printAdrpLabel"; 274 let ParserMatchClass = AdrpOperand; 275 let OperandType = "OPERAND_PCREL"; 276} 277 278def AdrOperand : AsmOperandClass { 279 let Name = "AdrLabel"; 280 let ParserMethod = "tryParseAdrLabel"; 281 let DiagnosticType = "InvalidLabel"; 282} 283def adrlabel : Operand<i64> { 284 let EncoderMethod = "getAdrLabelOpValue"; 285 let ParserMatchClass = AdrOperand; 286} 287 288class SImmOperand<int width> : AsmOperandClass { 289 let Name = "SImm" # width; 290 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 291 let RenderMethod = "addImmOperands"; 292 let PredicateMethod = "isSImm<" # width # ">"; 293} 294 295 296class AsmImmRange<int Low, int High> : AsmOperandClass { 297 let Name = "Imm" # Low # "_" # High; 298 let DiagnosticType = "InvalidImm" # Low # "_" # High; 299 let RenderMethod = "addImmOperands"; 300 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 301} 302 303// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 304def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 305def simm10Scaled : Operand<i64> { 306 let ParserMatchClass = SImm10s8Operand; 307 let DecoderMethod = "DecodeSImm<10>"; 308 let PrintMethod = "printImmScale<8>"; 309} 310 311def simm9s16 : Operand<i64> { 312 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 313 let DecoderMethod = "DecodeSImm<9>"; 314 let PrintMethod = "printImmScale<16>"; 315} 316 317// uimm6 predicate - True if the immediate is in the range [0, 63]. 318def UImm6Operand : AsmOperandClass { 319 let Name = "UImm6"; 320 let DiagnosticType = "InvalidImm0_63"; 321} 322 323def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 324 let ParserMatchClass = UImm6Operand; 325} 326 327def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 328 let ParserMatchClass = AsmImmRange<0, 65535>; 329} 330 331def SImm9Operand : SImmOperand<9>; 332def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 333 let ParserMatchClass = SImm9Operand; 334 let DecoderMethod = "DecodeSImm<9>"; 335} 336 337def SImm8Operand : SImmOperand<8>; 338def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> { 339 let ParserMatchClass = SImm8Operand; 340 let DecoderMethod = "DecodeSImm<8>"; 341} 342 343def SImm6Operand : SImmOperand<6>; 344def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 345 let ParserMatchClass = SImm6Operand; 346 let DecoderMethod = "DecodeSImm<6>"; 347} 348 349def SImm5Operand : SImmOperand<5>; 350def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 351 let ParserMatchClass = SImm5Operand; 352 let DecoderMethod = "DecodeSImm<5>"; 353} 354 355def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 356 let ParserMatchClass = SImm5Operand; 357 let DecoderMethod = "DecodeSImm<5>"; 358} 359 360def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 361 let ParserMatchClass = SImm5Operand; 362 let DecoderMethod = "DecodeSImm<5>"; 363 let PrintMethod = "printSImm<8>"; 364} 365 366def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 367 let ParserMatchClass = SImm5Operand; 368 let DecoderMethod = "DecodeSImm<5>"; 369 let PrintMethod = "printSImm<16>"; 370} 371 372// simm7sN predicate - True if the immediate is a multiple of N in the range 373// [-64 * N, 63 * N]. 374 375def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 376def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 377def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 378 379def simm7s4 : Operand<i32> { 380 let ParserMatchClass = SImm7s4Operand; 381 let PrintMethod = "printImmScale<4>"; 382} 383 384def simm7s8 : Operand<i32> { 385 let ParserMatchClass = SImm7s8Operand; 386 let PrintMethod = "printImmScale<8>"; 387} 388 389def simm7s16 : Operand<i32> { 390 let ParserMatchClass = SImm7s16Operand; 391 let PrintMethod = "printImmScale<16>"; 392} 393 394def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>; 395 396def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>; 397def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>; 398def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>; 399def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>; 400def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>; 401 402def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>; 403def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>; 404 405def UImmS1XForm : SDNodeXForm<imm, [{ 406 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 407}]>; 408def UImmS2XForm : SDNodeXForm<imm, [{ 409 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 410}]>; 411def UImmS4XForm : SDNodeXForm<imm, [{ 412 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 413}]>; 414def UImmS8XForm : SDNodeXForm<imm, [{ 415 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 416}]>; 417 418// uimm5sN predicate - True if the immediate is a multiple of N in the range 419// [0 * N, 32 * N]. 420def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 421def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 422def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 423 424def uimm5s2 : Operand<i64>, ImmLeaf<i64, 425 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 426 UImmS2XForm> { 427 let ParserMatchClass = UImm5s2Operand; 428 let PrintMethod = "printImmScale<2>"; 429} 430def uimm5s4 : Operand<i64>, ImmLeaf<i64, 431 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 432 UImmS4XForm> { 433 let ParserMatchClass = UImm5s4Operand; 434 let PrintMethod = "printImmScale<4>"; 435} 436def uimm5s8 : Operand<i64>, ImmLeaf<i64, 437 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 438 UImmS8XForm> { 439 let ParserMatchClass = UImm5s8Operand; 440 let PrintMethod = "printImmScale<8>"; 441} 442 443// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 444// instead of ImmLeaf (Constant) 445def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 446 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 447 UImmS2XForm> { 448 let ParserMatchClass = UImm5s2Operand; 449 let PrintMethod = "printImmScale<2>"; 450} 451def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 452 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 453 UImmS4XForm> { 454 let ParserMatchClass = UImm5s4Operand; 455 let PrintMethod = "printImmScale<4>"; 456} 457def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 458 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 459 UImmS8XForm> { 460 let ParserMatchClass = UImm5s8Operand; 461 let PrintMethod = "printImmScale<8>"; 462} 463 464// uimm6sN predicate - True if the immediate is a multiple of N in the range 465// [0 * N, 64 * N]. 466def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 467def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 468def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 469def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 470def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 471 472def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 473 let ParserMatchClass = UImm6s1Operand; 474} 475def uimm6s2 : Operand<i64>, ImmLeaf<i64, 476[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 477 let PrintMethod = "printImmScale<2>"; 478 let ParserMatchClass = UImm6s2Operand; 479} 480def uimm6s4 : Operand<i64>, ImmLeaf<i64, 481[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 482 let PrintMethod = "printImmScale<4>"; 483 let ParserMatchClass = UImm6s4Operand; 484} 485def uimm6s8 : Operand<i64>, ImmLeaf<i64, 486[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 487 let PrintMethod = "printImmScale<8>"; 488 let ParserMatchClass = UImm6s8Operand; 489} 490def uimm6s16 : Operand<i64>, ImmLeaf<i64, 491[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 492 let PrintMethod = "printImmScale<16>"; 493 let ParserMatchClass = UImm6s16Operand; 494} 495 496def SImmS2XForm : SDNodeXForm<imm, [{ 497 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 498}]>; 499def SImmS3XForm : SDNodeXForm<imm, [{ 500 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 501}]>; 502def SImmS4XForm : SDNodeXForm<imm, [{ 503 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 504}]>; 505def SImmS16XForm : SDNodeXForm<imm, [{ 506 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 507}]>; 508def SImmS32XForm : SDNodeXForm<imm, [{ 509 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 510}]>; 511 512// simm6sN predicate - True if the immediate is a multiple of N in the range 513// [-32 * N, 31 * N]. 514def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 515def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 516 let ParserMatchClass = SImm6s1Operand; 517 let DecoderMethod = "DecodeSImm<6>"; 518} 519 520// simm4sN predicate - True if the immediate is a multiple of N in the range 521// [ -8* N, 7 * N]. 522def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 523def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 524def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 525def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 526def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 527def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 528 529def simm4s1 : Operand<i64>, ImmLeaf<i64, 530[{ return Imm >=-8 && Imm <= 7; }]> { 531 let ParserMatchClass = SImm4s1Operand; 532 let DecoderMethod = "DecodeSImm<4>"; 533} 534 535def simm4s2 : Operand<i64>, ImmLeaf<i64, 536[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 537 let PrintMethod = "printImmScale<2>"; 538 let ParserMatchClass = SImm4s2Operand; 539 let DecoderMethod = "DecodeSImm<4>"; 540} 541 542def simm4s3 : Operand<i64>, ImmLeaf<i64, 543[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 544 let PrintMethod = "printImmScale<3>"; 545 let ParserMatchClass = SImm4s3Operand; 546 let DecoderMethod = "DecodeSImm<4>"; 547} 548 549def simm4s4 : Operand<i64>, ImmLeaf<i64, 550[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 551 let PrintMethod = "printImmScale<4>"; 552 let ParserMatchClass = SImm4s4Operand; 553 let DecoderMethod = "DecodeSImm<4>"; 554} 555def simm4s16 : Operand<i64>, ImmLeaf<i64, 556[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 557 let PrintMethod = "printImmScale<16>"; 558 let ParserMatchClass = SImm4s16Operand; 559 let DecoderMethod = "DecodeSImm<4>"; 560} 561def simm4s32 : Operand<i64>, ImmLeaf<i64, 562[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 563 let PrintMethod = "printImmScale<32>"; 564 let ParserMatchClass = SImm4s32Operand; 565 let DecoderMethod = "DecodeSImm<4>"; 566} 567 568def Imm1_8Operand : AsmImmRange<1, 8>; 569def Imm1_16Operand : AsmImmRange<1, 16>; 570def Imm1_32Operand : AsmImmRange<1, 32>; 571def Imm1_64Operand : AsmImmRange<1, 64>; 572 573class BranchTarget<int N> : AsmOperandClass { 574 let Name = "BranchTarget" # N; 575 let DiagnosticType = "InvalidLabel"; 576 let PredicateMethod = "isBranchTarget<" # N # ">"; 577} 578 579class PCRelLabel<int N> : BranchTarget<N> { 580 let Name = "PCRelLabel" # N; 581} 582 583def BranchTarget14Operand : BranchTarget<14>; 584def BranchTarget26Operand : BranchTarget<26>; 585def PCRelLabel19Operand : PCRelLabel<19>; 586 587def MovWSymbolG3AsmOperand : AsmOperandClass { 588 let Name = "MovWSymbolG3"; 589 let RenderMethod = "addImmOperands"; 590} 591 592def movw_symbol_g3 : Operand<i32> { 593 let ParserMatchClass = MovWSymbolG3AsmOperand; 594} 595 596def MovWSymbolG2AsmOperand : AsmOperandClass { 597 let Name = "MovWSymbolG2"; 598 let RenderMethod = "addImmOperands"; 599} 600 601def movw_symbol_g2 : Operand<i32> { 602 let ParserMatchClass = MovWSymbolG2AsmOperand; 603} 604 605def MovWSymbolG1AsmOperand : AsmOperandClass { 606 let Name = "MovWSymbolG1"; 607 let RenderMethod = "addImmOperands"; 608} 609 610def movw_symbol_g1 : Operand<i32> { 611 let ParserMatchClass = MovWSymbolG1AsmOperand; 612} 613 614def MovWSymbolG0AsmOperand : AsmOperandClass { 615 let Name = "MovWSymbolG0"; 616 let RenderMethod = "addImmOperands"; 617} 618 619def movw_symbol_g0 : Operand<i32> { 620 let ParserMatchClass = MovWSymbolG0AsmOperand; 621} 622 623class fixedpoint_i32<ValueType FloatVT> 624 : Operand<FloatVT>, 625 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 626 let EncoderMethod = "getFixedPointScaleOpValue"; 627 let DecoderMethod = "DecodeFixedPointScaleImm32"; 628 let ParserMatchClass = Imm1_32Operand; 629} 630 631class fixedpoint_i64<ValueType FloatVT> 632 : Operand<FloatVT>, 633 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 634 let EncoderMethod = "getFixedPointScaleOpValue"; 635 let DecoderMethod = "DecodeFixedPointScaleImm64"; 636 let ParserMatchClass = Imm1_64Operand; 637} 638 639def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 640def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 641def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 642 643def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 644def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 645def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 646 647def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 648 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 649}]> { 650 let EncoderMethod = "getVecShiftR8OpValue"; 651 let DecoderMethod = "DecodeVecShiftR8Imm"; 652 let ParserMatchClass = Imm1_8Operand; 653} 654def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 655 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 656}]> { 657 let EncoderMethod = "getVecShiftR16OpValue"; 658 let DecoderMethod = "DecodeVecShiftR16Imm"; 659 let ParserMatchClass = Imm1_16Operand; 660} 661def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 662 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 663}]> { 664 let EncoderMethod = "getVecShiftR16OpValue"; 665 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 666 let ParserMatchClass = Imm1_8Operand; 667} 668def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 669 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 670}]> { 671 let EncoderMethod = "getVecShiftR32OpValue"; 672 let DecoderMethod = "DecodeVecShiftR32Imm"; 673 let ParserMatchClass = Imm1_32Operand; 674} 675def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 676 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 677}]> { 678 let EncoderMethod = "getVecShiftR32OpValue"; 679 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 680 let ParserMatchClass = Imm1_16Operand; 681} 682def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 683 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 684}]> { 685 let EncoderMethod = "getVecShiftR64OpValue"; 686 let DecoderMethod = "DecodeVecShiftR64Imm"; 687 let ParserMatchClass = Imm1_64Operand; 688} 689def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 690 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 691}]> { 692 let EncoderMethod = "getVecShiftR64OpValue"; 693 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 694 let ParserMatchClass = Imm1_32Operand; 695} 696 697// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 698// (ImmLeaf) 699def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 700 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 701}]> { 702 let EncoderMethod = "getVecShiftR8OpValue"; 703 let DecoderMethod = "DecodeVecShiftR8Imm"; 704 let ParserMatchClass = Imm1_8Operand; 705} 706def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 707 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 708}]> { 709 let EncoderMethod = "getVecShiftR16OpValue"; 710 let DecoderMethod = "DecodeVecShiftR16Imm"; 711 let ParserMatchClass = Imm1_16Operand; 712} 713def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 714 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 715}]> { 716 let EncoderMethod = "getVecShiftR32OpValue"; 717 let DecoderMethod = "DecodeVecShiftR32Imm"; 718 let ParserMatchClass = Imm1_32Operand; 719} 720def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 721 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 722}]> { 723 let EncoderMethod = "getVecShiftR64OpValue"; 724 let DecoderMethod = "DecodeVecShiftR64Imm"; 725 let ParserMatchClass = Imm1_64Operand; 726} 727 728def Imm0_0Operand : AsmImmRange<0, 0>; 729def Imm0_1Operand : AsmImmRange<0, 1>; 730def Imm0_3Operand : AsmImmRange<0, 3>; 731def Imm0_7Operand : AsmImmRange<0, 7>; 732def Imm0_15Operand : AsmImmRange<0, 15>; 733def Imm0_31Operand : AsmImmRange<0, 31>; 734def Imm0_63Operand : AsmImmRange<0, 63>; 735 736def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 737 return (((uint32_t)Imm) < 8); 738}]> { 739 let EncoderMethod = "getVecShiftL8OpValue"; 740 let DecoderMethod = "DecodeVecShiftL8Imm"; 741 let ParserMatchClass = Imm0_7Operand; 742} 743def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 744 return (((uint32_t)Imm) < 16); 745}]> { 746 let EncoderMethod = "getVecShiftL16OpValue"; 747 let DecoderMethod = "DecodeVecShiftL16Imm"; 748 let ParserMatchClass = Imm0_15Operand; 749} 750def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 751 return (((uint32_t)Imm) < 32); 752}]> { 753 let EncoderMethod = "getVecShiftL32OpValue"; 754 let DecoderMethod = "DecodeVecShiftL32Imm"; 755 let ParserMatchClass = Imm0_31Operand; 756} 757def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 758 return (((uint32_t)Imm) < 64); 759}]> { 760 let EncoderMethod = "getVecShiftL64OpValue"; 761 let DecoderMethod = "DecodeVecShiftL64Imm"; 762 let ParserMatchClass = Imm0_63Operand; 763} 764 765// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 766// (ImmLeaf) 767def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 768 return (((uint32_t)Imm) < 8); 769}]> { 770 let EncoderMethod = "getVecShiftL8OpValue"; 771 let DecoderMethod = "DecodeVecShiftL8Imm"; 772 let ParserMatchClass = Imm0_7Operand; 773} 774def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 775 return (((uint32_t)Imm) < 16); 776}]> { 777 let EncoderMethod = "getVecShiftL16OpValue"; 778 let DecoderMethod = "DecodeVecShiftL16Imm"; 779 let ParserMatchClass = Imm0_15Operand; 780} 781def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 782 return (((uint32_t)Imm) < 32); 783}]> { 784 let EncoderMethod = "getVecShiftL32OpValue"; 785 let DecoderMethod = "DecodeVecShiftL32Imm"; 786 let ParserMatchClass = Imm0_31Operand; 787} 788def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 789 return (((uint32_t)Imm) < 64); 790}]> { 791 let EncoderMethod = "getVecShiftL64OpValue"; 792 let DecoderMethod = "DecodeVecShiftL64Imm"; 793 let ParserMatchClass = Imm0_63Operand; 794} 795 796// Crazy immediate formats used by 32-bit and 64-bit logical immediate 797// instructions for splatting repeating bit patterns across the immediate. 798def logical_imm32_XFORM : SDNodeXForm<imm, [{ 799 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 800 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 801}]>; 802def logical_imm64_XFORM : SDNodeXForm<imm, [{ 803 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 804 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 805}]>; 806 807def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 808 GISDNodeXFormEquiv<logical_imm32_XFORM>; 809def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 810 GISDNodeXFormEquiv<logical_imm64_XFORM>; 811 812let DiagnosticType = "LogicalSecondSource" in { 813 def LogicalImm32Operand : AsmOperandClass { 814 let Name = "LogicalImm32"; 815 let PredicateMethod = "isLogicalImm<int32_t>"; 816 let RenderMethod = "addLogicalImmOperands<int32_t>"; 817 } 818 def LogicalImm64Operand : AsmOperandClass { 819 let Name = "LogicalImm64"; 820 let PredicateMethod = "isLogicalImm<int64_t>"; 821 let RenderMethod = "addLogicalImmOperands<int64_t>"; 822 } 823 def LogicalImm32NotOperand : AsmOperandClass { 824 let Name = "LogicalImm32Not"; 825 let PredicateMethod = "isLogicalImm<int32_t>"; 826 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 827 } 828 def LogicalImm64NotOperand : AsmOperandClass { 829 let Name = "LogicalImm64Not"; 830 let PredicateMethod = "isLogicalImm<int64_t>"; 831 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 832 } 833} 834def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 835 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 836}], logical_imm32_XFORM> { 837 let PrintMethod = "printLogicalImm<int32_t>"; 838 let ParserMatchClass = LogicalImm32Operand; 839} 840def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 841 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 842}], logical_imm64_XFORM> { 843 let PrintMethod = "printLogicalImm<int64_t>"; 844 let ParserMatchClass = LogicalImm64Operand; 845} 846def logical_imm32_not : Operand<i32> { 847 let ParserMatchClass = LogicalImm32NotOperand; 848} 849def logical_imm64_not : Operand<i64> { 850 let ParserMatchClass = LogicalImm64NotOperand; 851} 852 853// immXX_0_65535 predicates - True if the immediate is in the range [0,65535]. 854let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 855def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{ 856 return ((uint32_t)Imm) < 65536; 857}]>; 858 859def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{ 860 return ((uint64_t)Imm) < 65536; 861}]>; 862} 863 864// imm0_255 predicate - True if the immediate is in the range [0,255]. 865def Imm0_255Operand : AsmImmRange<0,255>; 866 867def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 868 return ((uint32_t)Imm) < 256; 869}]> { 870 let ParserMatchClass = Imm0_255Operand; 871 let PrintMethod = "printImm"; 872} 873 874// imm0_127 predicate - True if the immediate is in the range [0,127] 875def Imm0_127Operand : AsmImmRange<0, 127>; 876def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 877 return ((uint32_t)Imm) < 128; 878}]> { 879 let ParserMatchClass = Imm0_127Operand; 880 let PrintMethod = "printImm"; 881} 882 883def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 884 return ((uint64_t)Imm) < 128; 885}]> { 886 let ParserMatchClass = Imm0_127Operand; 887 let PrintMethod = "printImm"; 888} 889 890// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 891// for all shift-amounts. 892 893// imm0_63 predicate - True if the immediate is in the range [0,63] 894def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 895 return ((uint64_t)Imm) < 64; 896}]> { 897 let ParserMatchClass = Imm0_63Operand; 898} 899 900def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 901 return ((uint64_t)Imm) < 64; 902}]> { 903 let ParserMatchClass = Imm0_63Operand; 904} 905 906// imm0_31 predicate - True if the immediate is in the range [0,31] 907def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 908 return ((uint64_t)Imm) < 32; 909}]> { 910 let ParserMatchClass = Imm0_31Operand; 911} 912 913// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 914// instead of Constant (ImmLeaf) 915def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 916 return ((uint64_t)Imm) < 32; 917}]> { 918 let ParserMatchClass = Imm0_31Operand; 919} 920 921// True if the 32-bit immediate is in the range [0,31] 922def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 923 return ((uint64_t)Imm) < 32; 924}]> { 925 let ParserMatchClass = Imm0_31Operand; 926} 927 928// imm0_1 predicate - True if the immediate is in the range [0,1] 929def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 930 return ((uint64_t)Imm) < 2; 931}]> { 932 let ParserMatchClass = Imm0_1Operand; 933} 934 935// timm0_1 - as above, but use TargetConstant (TImmLeaf) 936def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 937 return ((uint64_t)Imm) < 2; 938}]> { 939 let ParserMatchClass = Imm0_1Operand; 940} 941 942// imm0_15 predicate - True if the immediate is in the range [0,15] 943def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 944 return ((uint64_t)Imm) < 16; 945}]> { 946 let ParserMatchClass = Imm0_15Operand; 947} 948 949// imm0_7 predicate - True if the immediate is in the range [0,7] 950def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 951 return ((uint64_t)Imm) < 8; 952}]> { 953 let ParserMatchClass = Imm0_7Operand; 954} 955 956// imm0_3 predicate - True if the immediate is in the range [0,3] 957def imm0_3 : Operand<i64>, ImmLeaf<i64, [{ 958 return ((uint64_t)Imm) < 4; 959}]> { 960 let ParserMatchClass = Imm0_3Operand; 961} 962 963// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 964def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 965 return ((uint32_t)Imm) < 8; 966}]> { 967 let ParserMatchClass = Imm0_7Operand; 968} 969 970// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 971def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 972 return ((uint32_t)Imm) < 16; 973}]> { 974 let ParserMatchClass = Imm0_15Operand; 975} 976 977// An arithmetic shifter operand: 978// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 979// {5-0} - imm6 980class arith_shift<ValueType Ty, int width> : Operand<Ty> { 981 let PrintMethod = "printShifter"; 982 let ParserMatchClass = !cast<AsmOperandClass>( 983 "ArithmeticShifterOperand" # width); 984} 985 986def arith_shift32 : arith_shift<i32, 32>; 987def arith_shift64 : arith_shift<i64, 64>; 988 989class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 990 : Operand<Ty>, 991 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 992 let PrintMethod = "printShiftedRegister"; 993 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 994} 995 996def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 997def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 998 999def gi_arith_shifted_reg32 : 1000 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 1001 GIComplexPatternEquiv<arith_shifted_reg32>; 1002 1003def gi_arith_shifted_reg64 : 1004 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 1005 GIComplexPatternEquiv<arith_shifted_reg64>; 1006 1007// An arithmetic shifter operand: 1008// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 1009// {5-0} - imm6 1010class logical_shift<int width> : Operand<i32> { 1011 let PrintMethod = "printShifter"; 1012 let ParserMatchClass = !cast<AsmOperandClass>( 1013 "LogicalShifterOperand" # width); 1014} 1015 1016def logical_shift32 : logical_shift<32>; 1017def logical_shift64 : logical_shift<64>; 1018 1019class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1020 : Operand<Ty>, 1021 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1022 let PrintMethod = "printShiftedRegister"; 1023 let MIOperandInfo = (ops regclass, shiftop); 1024} 1025 1026def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1027def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1028 1029def gi_logical_shifted_reg32 : 1030 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1031 GIComplexPatternEquiv<logical_shifted_reg32>; 1032 1033def gi_logical_shifted_reg64 : 1034 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1035 GIComplexPatternEquiv<logical_shifted_reg64>; 1036 1037// A logical vector shifter operand: 1038// {7-6} - shift type: 00 = lsl 1039// {5-0} - imm6: #0, #8, #16, or #24 1040def logical_vec_shift : Operand<i32> { 1041 let PrintMethod = "printShifter"; 1042 let EncoderMethod = "getVecShifterOpValue"; 1043 let ParserMatchClass = LogicalVecShifterOperand; 1044} 1045 1046// A logical vector half-word shifter operand: 1047// {7-6} - shift type: 00 = lsl 1048// {5-0} - imm6: #0 or #8 1049def logical_vec_hw_shift : Operand<i32> { 1050 let PrintMethod = "printShifter"; 1051 let EncoderMethod = "getVecShifterOpValue"; 1052 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1053} 1054 1055// A vector move shifter operand: 1056// {0} - imm1: #8 or #16 1057def move_vec_shift : Operand<i32> { 1058 let PrintMethod = "printShifter"; 1059 let EncoderMethod = "getMoveVecShifterOpValue"; 1060 let ParserMatchClass = MoveVecShifterOperand; 1061} 1062 1063let DiagnosticType = "AddSubSecondSource" in { 1064 def AddSubImmOperand : AsmOperandClass { 1065 let Name = "AddSubImm"; 1066 let ParserMethod = "tryParseImmWithOptionalShift"; 1067 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1068 } 1069 def AddSubImmNegOperand : AsmOperandClass { 1070 let Name = "AddSubImmNeg"; 1071 let ParserMethod = "tryParseImmWithOptionalShift"; 1072 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1073 } 1074} 1075// An ADD/SUB immediate shifter operand: 1076// second operand: 1077// {7-6} - shift type: 00 = lsl 1078// {5-0} - imm6: #0 or #12 1079class addsub_shifted_imm<ValueType Ty> 1080 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1081 let PrintMethod = "printAddSubImm"; 1082 let EncoderMethod = "getAddSubImmOpValue"; 1083 let ParserMatchClass = AddSubImmOperand; 1084 let MIOperandInfo = (ops i32imm, i32imm); 1085} 1086 1087class addsub_shifted_imm_neg<ValueType Ty> 1088 : Operand<Ty> { 1089 let EncoderMethod = "getAddSubImmOpValue"; 1090 let ParserMatchClass = AddSubImmNegOperand; 1091 let MIOperandInfo = (ops i32imm, i32imm); 1092} 1093 1094def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1095def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1096def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1097def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1098 1099def gi_addsub_shifted_imm32 : 1100 GIComplexOperandMatcher<s32, "selectArithImmed">, 1101 GIComplexPatternEquiv<addsub_shifted_imm32>; 1102 1103def gi_addsub_shifted_imm64 : 1104 GIComplexOperandMatcher<s64, "selectArithImmed">, 1105 GIComplexPatternEquiv<addsub_shifted_imm64>; 1106 1107class neg_addsub_shifted_imm<ValueType Ty> 1108 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1109 let PrintMethod = "printAddSubImm"; 1110 let EncoderMethod = "getAddSubImmOpValue"; 1111 let ParserMatchClass = AddSubImmOperand; 1112 let MIOperandInfo = (ops i32imm, i32imm); 1113} 1114 1115def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1116def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1117 1118def gi_neg_addsub_shifted_imm32 : 1119 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1120 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1121 1122def gi_neg_addsub_shifted_imm64 : 1123 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1124 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1125 1126// An extend operand: 1127// {5-3} - extend type 1128// {2-0} - imm3 1129def arith_extend : Operand<i32> { 1130 let PrintMethod = "printArithExtend"; 1131 let ParserMatchClass = ExtendOperand; 1132} 1133def arith_extend64 : Operand<i32> { 1134 let PrintMethod = "printArithExtend"; 1135 let ParserMatchClass = ExtendOperand64; 1136} 1137 1138// 'extend' that's a lsl of a 64-bit register. 1139def arith_extendlsl64 : Operand<i32> { 1140 let PrintMethod = "printArithExtend"; 1141 let ParserMatchClass = ExtendOperandLSL64; 1142} 1143 1144class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1145 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1146 let PrintMethod = "printExtendedRegister"; 1147 let MIOperandInfo = (ops GPR32, arith_extend); 1148} 1149 1150class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1151 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1152 let PrintMethod = "printExtendedRegister"; 1153 let MIOperandInfo = (ops GPR32, arith_extend64); 1154} 1155 1156def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1157def gi_arith_extended_reg32_i32 : 1158 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1159 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1160 1161def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1162def gi_arith_extended_reg32_i64 : 1163 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1164 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1165 1166def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1167def gi_arith_extended_reg32to64_i64 : 1168 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1169 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1170 1171// Floating-point immediate. 1172 1173def fpimm16XForm : SDNodeXForm<fpimm, [{ 1174 APFloat InVal = N->getValueAPF(); 1175 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1176 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1177 }]>; 1178 1179def fpimm32XForm : SDNodeXForm<fpimm, [{ 1180 APFloat InVal = N->getValueAPF(); 1181 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1182 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1183 }]>; 1184 1185def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{ 1186 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF() 1187 .bitcastToAPInt() 1188 .getZExtValue()); 1189 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1190 }]>; 1191 1192def fpimm64XForm : SDNodeXForm<fpimm, [{ 1193 APFloat InVal = N->getValueAPF(); 1194 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1195 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1196 }]>; 1197 1198def fpimm16 : Operand<f16>, 1199 FPImmLeaf<f16, [{ 1200 return AArch64_AM::getFP16Imm(Imm) != -1; 1201 }], fpimm16XForm> { 1202 let ParserMatchClass = FPImmOperand; 1203 let PrintMethod = "printFPImmOperand"; 1204} 1205 1206def fpimm32 : Operand<f32>, 1207 FPImmLeaf<f32, [{ 1208 return AArch64_AM::getFP32Imm(Imm) != -1; 1209 }], fpimm32XForm> { 1210 let ParserMatchClass = FPImmOperand; 1211 let PrintMethod = "printFPImmOperand"; 1212} 1213 1214def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{ 1215 uint64_t Enc = Imm.bitcastToAPInt().getZExtValue(); 1216 return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc); 1217 }], fpimm32SIMDModImmType4XForm> { 1218} 1219 1220def fpimm64 : Operand<f64>, 1221 FPImmLeaf<f64, [{ 1222 return AArch64_AM::getFP64Imm(Imm) != -1; 1223 }], fpimm64XForm> { 1224 let ParserMatchClass = FPImmOperand; 1225 let PrintMethod = "printFPImmOperand"; 1226} 1227 1228def fpimm8 : Operand<i32> { 1229 let ParserMatchClass = FPImmOperand; 1230 let PrintMethod = "printFPImmOperand"; 1231} 1232 1233def fpimm0 : FPImmLeaf<fAny, [{ 1234 return Imm.isExactlyValue(+0.0); 1235}]>; 1236 1237def fpimm_half : FPImmLeaf<fAny, [{ 1238 return Imm.isExactlyValue(+0.5); 1239}]>; 1240 1241def fpimm_one : FPImmLeaf<fAny, [{ 1242 return Imm.isExactlyValue(+1.0); 1243}]>; 1244 1245def fpimm_two : FPImmLeaf<fAny, [{ 1246 return Imm.isExactlyValue(+2.0); 1247}]>; 1248 1249def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1250 GISDNodeXFormEquiv<fpimm16XForm>; 1251def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1252 GISDNodeXFormEquiv<fpimm32XForm>; 1253def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1254 GISDNodeXFormEquiv<fpimm64XForm>; 1255def gi_fpimm32SIMDModImmType4 : 1256 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, 1257 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>; 1258 1259// Vector lane operands 1260class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1261 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1262 let DiagnosticType = "Invalid" # Name; 1263 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1264 let RenderMethod = "addVectorIndexOperands"; 1265} 1266 1267class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1268 : Operand<ty> { 1269 let ParserMatchClass = mc; 1270 let PrintMethod = "printVectorIndex"; 1271} 1272 1273multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1274 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1275 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1276} 1277 1278def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1279def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1280def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1281def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1282def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1283def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1284 1285let OperandNamespace = "AArch64" in { 1286 let OperandType = "OPERAND_IMPLICIT_IMM_0" in { 1287 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1288 [{ return ((uint64_t)Imm) == 0; }]>; 1289 } 1290} 1291defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1292 [{ return ((uint64_t)Imm) == 1; }]>; 1293defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1294 [{ return ((uint64_t)Imm) < 16; }]>; 1295defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1296 [{ return ((uint64_t)Imm) < 8; }]>; 1297defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1298 [{ return ((uint64_t)Imm) < 4; }]>; 1299defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1300 [{ return ((uint64_t)Imm) < 2; }]>; 1301 1302defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1303 [{ return ((uint64_t)Imm) == 1; }]>; 1304defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1305 [{ return ((uint64_t)Imm) < 16; }]>; 1306defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1307 [{ return ((uint64_t)Imm) < 8; }]>; 1308defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1309 [{ return ((uint64_t)Imm) < 4; }]>; 1310defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1311 [{ return ((uint64_t)Imm) < 2; }]>; 1312 1313def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1314def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1315def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1316def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1317def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1318 1319defm sve_elm_idx_extdup_b 1320 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1321 [{ return ((uint64_t)Imm) < 64; }]>; 1322defm sve_elm_idx_extdup_h 1323 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1324 [{ return ((uint64_t)Imm) < 32; }]>; 1325defm sve_elm_idx_extdup_s 1326 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1327 [{ return ((uint64_t)Imm) < 16; }]>; 1328defm sve_elm_idx_extdup_d 1329 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1330 [{ return ((uint64_t)Imm) < 8; }]>; 1331defm sve_elm_idx_extdup_q 1332 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1333 [{ return ((uint64_t)Imm) < 4; }]>; 1334 1335def sme_elm_idx0_0 : Operand<i64>, ImmLeaf<i64, [{ 1336 return ((uint64_t)Imm) == 0; 1337}]> { 1338 let ParserMatchClass = Imm0_0Operand; 1339 let PrintMethod = "printMatrixIndex"; 1340 let OperandNamespace = "AArch64"; 1341 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1342} 1343def sme_elm_idx0_1 : Operand<i64>, ImmLeaf<i64, [{ 1344 return ((uint64_t)Imm) <= 1; 1345}]> { 1346 let ParserMatchClass = Imm0_1Operand; 1347 let PrintMethod = "printMatrixIndex"; 1348} 1349def sme_elm_idx0_3 : Operand<i64>, ImmLeaf<i64, [{ 1350 return ((uint64_t)Imm) <= 3; 1351}]> { 1352 let ParserMatchClass = Imm0_3Operand; 1353 let PrintMethod = "printMatrixIndex"; 1354} 1355def sme_elm_idx0_7 : Operand<i64>, ImmLeaf<i64, [{ 1356 return ((uint64_t)Imm) <= 7; 1357}]> { 1358 let ParserMatchClass = Imm0_7Operand; 1359 let PrintMethod = "printMatrixIndex"; 1360} 1361def sme_elm_idx0_15 : Operand<i64>, ImmLeaf<i64, [{ 1362 return ((uint64_t)Imm) <= 15; 1363}]> { 1364 let ParserMatchClass = Imm0_15Operand; 1365 let PrintMethod = "printMatrixIndex"; 1366} 1367 1368// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1369// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1370// are encoded as the eight bit value 'abcdefgh'. 1371def simdimmtype10 : Operand<i32>, 1372 FPImmLeaf<f64, [{ 1373 return AArch64_AM::isAdvSIMDModImmType10( 1374 Imm.bitcastToAPInt().getZExtValue()); 1375 }], SDNodeXForm<fpimm, [{ 1376 APFloat InVal = N->getValueAPF(); 1377 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1378 .bitcastToAPInt() 1379 .getZExtValue()); 1380 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1381 }]>> { 1382 let ParserMatchClass = SIMDImmType10Operand; 1383 let PrintMethod = "printSIMDType10Operand"; 1384} 1385 1386 1387//--- 1388// System management 1389//--- 1390 1391// Base encoding for system instruction operands. 1392let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1393class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1394 list<dag> pattern = []> 1395 : I<oops, iops, asm, operands, "", pattern> { 1396 let Inst{31-22} = 0b1101010100; 1397 let Inst{21} = L; 1398} 1399 1400// System instructions which do not have an Rt register. 1401class SimpleSystemI<bit L, dag iops, string asm, string operands, 1402 list<dag> pattern = []> 1403 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1404 let Inst{4-0} = 0b11111; 1405} 1406 1407// System instructions which have an Rt register. 1408class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1409 list<dag> pattern = []> 1410 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1411 Sched<[WriteSys]> { 1412 bits<5> Rt; 1413 let Inst{4-0} = Rt; 1414} 1415 1416// System instructions for transactional memory extension 1417class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1418 string asm, string operands, list<dag> pattern> 1419 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1420 Sched<[WriteSys]> { 1421 let Inst{20-12} = 0b000110011; 1422 let Inst{11-8} = CRm; 1423 let Inst{7-5} = op2; 1424 let DecoderMethod = ""; 1425 1426 let mayLoad = 1; 1427 let mayStore = 1; 1428} 1429 1430// System instructions for transactional memory - single input operand 1431class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1432 : TMBaseSystemI<0b1, CRm, 0b011, 1433 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1434 bits<5> Rt; 1435 let Inst{4-0} = Rt; 1436} 1437 1438// System instructions that pass a register argument 1439// This class assumes the register is for input rather than output. 1440class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1441 list<dag> pattern = []> 1442 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1443 let Inst{20-12} = 0b000110001; 1444 let Inst{11-8} = CRm; 1445 let Inst{7-5} = Op2; 1446} 1447 1448// System instructions for transactional memory - no operand 1449class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1450 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1451 let Inst{4-0} = 0b11111; 1452} 1453 1454// System instructions for exit from transactions 1455class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1456 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1457 Sched<[WriteSys]> { 1458 bits<16> imm; 1459 let Inst{31-24} = 0b11010100; 1460 let Inst{23-21} = op1; 1461 let Inst{20-5} = imm; 1462 let Inst{4-0} = 0b00000; 1463} 1464 1465// Hint instructions that take both a CRm and a 3-bit immediate. 1466// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1467// model patterns with sufficiently fine granularity 1468let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1469 class HintI<string mnemonic> 1470 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1471 [(int_aarch64_hint imm0_127:$imm)]>, 1472 Sched<[WriteHint]> { 1473 bits <7> imm; 1474 let Inst{20-12} = 0b000110010; 1475 let Inst{11-5} = imm; 1476 } 1477 1478// System instructions taking a single literal operand which encodes into 1479// CRm. op2 differentiates the opcodes. 1480def BarrierAsmOperand : AsmOperandClass { 1481 let Name = "Barrier"; 1482 let ParserMethod = "tryParseBarrierOperand"; 1483} 1484def barrier_op : Operand<i32> { 1485 let PrintMethod = "printBarrierOption"; 1486 let ParserMatchClass = BarrierAsmOperand; 1487} 1488def BarriernXSAsmOperand : AsmOperandClass { 1489 let Name = "BarriernXS"; 1490 let ParserMethod = "tryParseBarriernXSOperand"; 1491} 1492def barrier_nxs_op : Operand<i32> { 1493 let PrintMethod = "printBarriernXSOption"; 1494 let ParserMatchClass = BarriernXSAsmOperand; 1495} 1496class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1497 list<dag> pattern = []> 1498 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1499 Sched<[WriteBarrier]> { 1500 bits<4> CRm; 1501 let Inst{20-12} = 0b000110011; 1502 let Inst{11-8} = CRm; 1503 let Inst{7-5} = opc; 1504} 1505 1506class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1507 : SimpleSystemI<0, (ins), asm, "", pattern>, 1508 Sched<[]> { 1509 bits<4> CRm; 1510 let CRm = 0b0011; 1511 let Inst{31-12} = 0b11010101000000110010; 1512 let Inst{11-8} = CRm; 1513 let Inst{7-5} = op2; 1514 let Inst{4-0} = 0b11111; 1515} 1516 1517// MRS/MSR system instructions. These have different operand classes because 1518// a different subset of registers can be accessed through each instruction. 1519def MRSSystemRegisterOperand : AsmOperandClass { 1520 let Name = "MRSSystemRegister"; 1521 let ParserMethod = "tryParseSysReg"; 1522 let DiagnosticType = "MRS"; 1523} 1524// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1525def mrs_sysreg_op : Operand<i32> { 1526 let ParserMatchClass = MRSSystemRegisterOperand; 1527 let DecoderMethod = "DecodeMRSSystemRegister"; 1528 let PrintMethod = "printMRSSystemRegister"; 1529} 1530 1531def MSRSystemRegisterOperand : AsmOperandClass { 1532 let Name = "MSRSystemRegister"; 1533 let ParserMethod = "tryParseSysReg"; 1534 let DiagnosticType = "MSR"; 1535} 1536def msr_sysreg_op : Operand<i32> { 1537 let ParserMatchClass = MSRSystemRegisterOperand; 1538 let DecoderMethod = "DecodeMSRSystemRegister"; 1539 let PrintMethod = "printMSRSystemRegister"; 1540} 1541 1542def PSBHintOperand : AsmOperandClass { 1543 let Name = "PSBHint"; 1544 let ParserMethod = "tryParsePSBHint"; 1545} 1546def psbhint_op : Operand<i32> { 1547 let ParserMatchClass = PSBHintOperand; 1548 let PrintMethod = "printPSBHintOp"; 1549 let MCOperandPredicate = [{ 1550 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1551 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1552 if (!MCOp.isImm()) 1553 return false; 1554 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1555 }]; 1556} 1557 1558def BTIHintOperand : AsmOperandClass { 1559 let Name = "BTIHint"; 1560 let ParserMethod = "tryParseBTIHint"; 1561} 1562def btihint_op : Operand<i32> { 1563 let ParserMatchClass = BTIHintOperand; 1564 let PrintMethod = "printBTIHintOp"; 1565 let MCOperandPredicate = [{ 1566 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1567 if (!MCOp.isImm()) 1568 return false; 1569 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1570 }]; 1571} 1572 1573class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1574 "mrs", "\t$Rt, $systemreg"> { 1575 bits<16> systemreg; 1576 let Inst{20-5} = systemreg; 1577 let DecoderNamespace = "Fallback"; 1578 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1579 // require doing this. The alternative was to explicitly model each one, but 1580 // it feels like it is unnecessary because it seems there are no negative 1581 // consequences setting these flags for all. 1582 let Defs = [NZCV]; 1583} 1584 1585// FIXME: Some of these def NZCV, others don't. Best way to model that? 1586// Explicitly modeling each of the system register as a register class 1587// would do it, but feels like overkill at this point. 1588class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1589 "msr", "\t$systemreg, $Rt"> { 1590 bits<16> systemreg; 1591 let Inst{20-5} = systemreg; 1592 let DecoderNamespace = "Fallback"; 1593} 1594 1595def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1596 let Name = "SystemPStateFieldWithImm0_15"; 1597 let ParserMethod = "tryParseSysReg"; 1598} 1599def pstatefield4_op : Operand<i32> { 1600 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1601 let PrintMethod = "printSystemPStateField"; 1602} 1603 1604// Instructions to modify PSTATE, no input reg 1605let Defs = [NZCV] in 1606class PstateWriteSimple<dag iops, string asm, string operands> 1607 : SimpleSystemI<0, iops, asm, operands> { 1608 1609 let Inst{20-19} = 0b00; 1610 let Inst{15-12} = 0b0100; 1611} 1612 1613class MSRpstateImm0_15 1614 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1615 "\t$pstatefield, $imm">, 1616 Sched<[WriteSys]> { 1617 1618 bits<6> pstatefield; 1619 bits<4> imm; 1620 let Inst{18-16} = pstatefield{5-3}; 1621 let Inst{11-8} = imm; 1622 let Inst{7-5} = pstatefield{2-0}; 1623 1624 let DecoderMethod = "DecodeSystemPStateInstruction"; 1625 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1626 // Fail the decoder should attempt to decode the instruction as MSRI. 1627 let hasCompleteDecoder = 0; 1628} 1629 1630def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1631 let Name = "SystemPStateFieldWithImm0_1"; 1632 let ParserMethod = "tryParseSysReg"; 1633} 1634def pstatefield1_op : Operand<i32> { 1635 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1636 let PrintMethod = "printSystemPStateField"; 1637} 1638 1639class MSRpstateImm0_1 1640 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1641 "\t$pstatefield, $imm">, 1642 Sched<[WriteSys]> { 1643 1644 bits<6> pstatefield; 1645 bit imm; 1646 let Inst{18-16} = pstatefield{5-3}; 1647 let Inst{11-9} = 0b000; 1648 let Inst{8} = imm; 1649 let Inst{7-5} = pstatefield{2-0}; 1650 1651 let DecoderMethod = "DecodeSystemPStateInstruction"; 1652 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1653 // Fail the decoder should attempt to decode the instruction as MSRI. 1654 let hasCompleteDecoder = 0; 1655} 1656 1657// SYS and SYSL generic system instructions. 1658def SysCRAsmOperand : AsmOperandClass { 1659 let Name = "SysCR"; 1660 let ParserMethod = "tryParseSysCROperand"; 1661} 1662 1663def sys_cr_op : Operand<i32> { 1664 let PrintMethod = "printSysCROperand"; 1665 let ParserMatchClass = SysCRAsmOperand; 1666} 1667 1668class SystemXtI<bit L, string asm> 1669 : RtSystemI<L, (outs), 1670 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1671 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1672 bits<3> op1; 1673 bits<4> Cn; 1674 bits<4> Cm; 1675 bits<3> op2; 1676 let Inst{20-19} = 0b01; 1677 let Inst{18-16} = op1; 1678 let Inst{15-12} = Cn; 1679 let Inst{11-8} = Cm; 1680 let Inst{7-5} = op2; 1681} 1682 1683class SystemLXtI<bit L, string asm> 1684 : RtSystemI<L, (outs), 1685 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1686 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1687 bits<3> op1; 1688 bits<4> Cn; 1689 bits<4> Cm; 1690 bits<3> op2; 1691 let Inst{20-19} = 0b01; 1692 let Inst{18-16} = op1; 1693 let Inst{15-12} = Cn; 1694 let Inst{11-8} = Cm; 1695 let Inst{7-5} = op2; 1696} 1697 1698 1699// Branch (register) instructions: 1700// 1701// case opc of 1702// 0001 blr 1703// 0000 br 1704// 0101 dret 1705// 0100 eret 1706// 0010 ret 1707// otherwise UNDEFINED 1708class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1709 string operands, list<dag> pattern> 1710 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1711 let Inst{31-25} = 0b1101011; 1712 let Inst{24-21} = opc; 1713 let Inst{20-16} = 0b11111; 1714 let Inst{15-10} = 0b000000; 1715 let Inst{4-0} = 0b00000; 1716} 1717 1718class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1719 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1720 bits<5> Rn; 1721 let Inst{9-5} = Rn; 1722} 1723 1724let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1725class SpecialReturn<bits<4> opc, string asm> 1726 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1727 let Inst{9-5} = 0b11111; 1728} 1729 1730let mayLoad = 1 in 1731class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1732 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1733 Sched<[]> { 1734 bits<5> Rn; 1735 bits<5> Rt; 1736 let Inst{31-30} = sz; 1737 let Inst{29-10} = 0b11100010111111110000; 1738 let Inst{9-5} = Rn; 1739 let Inst{4-0} = Rt; 1740} 1741 1742class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1743 list<dag> pattern> 1744 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1745 let isAuthenticated = 1; 1746 let Inst{31-25} = 0b1101011; 1747 let Inst{20-11} = 0b1111100001; 1748 let Inst{10} = M; 1749 let Inst{4-0} = 0b11111; 1750} 1751 1752class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1753 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1754 bits<5> Rn; 1755 bits<5> Rm; 1756 let Inst{24-22} = 0b100; 1757 let Inst{21} = op; 1758 let Inst{9-5} = Rn; 1759 let Inst{4-0} = Rm; 1760} 1761 1762class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1763 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1764 bits<5> Rn; 1765 let Inst{24} = 0; 1766 let Inst{23-21} = opc; 1767 let Inst{9-5} = Rn; 1768} 1769 1770let Uses = [LR,SP] in 1771class AuthReturn<bits<3> op, bits<1> M, string asm> 1772 : AuthBase<M, (outs), (ins), asm, "", []> { 1773 let Inst{24} = 0; 1774 let Inst{23-21} = op; 1775 let Inst{9-0} = 0b1111111111; 1776} 1777 1778let mayLoad = 1 in 1779class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1780 string operands, string cstr> 1781 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1782 bits<10> offset; 1783 bits<5> Rn; 1784 bits<5> Rt; 1785 let isAuthenticated = 1; 1786 let Inst{31-24} = 0b11111000; 1787 let Inst{23} = M; 1788 let Inst{22} = offset{9}; 1789 let Inst{21} = 1; 1790 let Inst{20-12} = offset{8-0}; 1791 let Inst{11} = W; 1792 let Inst{10} = 1; 1793 let Inst{9-5} = Rn; 1794 let Inst{4-0} = Rt; 1795 1796 let DecoderMethod = "DecodeAuthLoadInstruction"; 1797} 1798 1799multiclass AuthLoad<bit M, string asm, Operand opr> { 1800 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1801 (ins GPR64sp:$Rn, opr:$offset), 1802 asm, "\t$Rt, [$Rn, $offset]", "">; 1803 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1804 (ins GPR64sp:$Rn, opr:$offset), 1805 asm, "\t$Rt, [$Rn, $offset]!", 1806 "$Rn = $wback,@earlyclobber $wback">; 1807 1808 def : InstAlias<asm # "\t$Rt, [$Rn]", 1809 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1810 1811 def : InstAlias<asm # "\t$Rt, [$wback]!", 1812 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1813} 1814 1815//--- 1816// Conditional branch instruction. 1817//--- 1818 1819// Condition code. 1820// 4-bit immediate. Pretty-printed as <cc> 1821def ccode : Operand<i32> { 1822 let PrintMethod = "printCondCode"; 1823 let ParserMatchClass = CondCode; 1824} 1825def inv_ccode : Operand<i32> { 1826 // AL and NV are invalid in the aliases which use inv_ccode 1827 let PrintMethod = "printInverseCondCode"; 1828 let ParserMatchClass = CondCode; 1829 let MCOperandPredicate = [{ 1830 return MCOp.isImm() && 1831 MCOp.getImm() != AArch64CC::AL && 1832 MCOp.getImm() != AArch64CC::NV; 1833 }]; 1834} 1835 1836// Conditional branch target. 19-bit immediate. The low two bits of the target 1837// offset are implied zero and so are not part of the immediate. 1838def am_brcond : Operand<OtherVT> { 1839 let EncoderMethod = "getCondBranchTargetOpValue"; 1840 let DecoderMethod = "DecodePCRelLabel19"; 1841 let PrintMethod = "printAlignedLabel"; 1842 let ParserMatchClass = PCRelLabel19Operand; 1843 let OperandType = "OPERAND_PCREL"; 1844} 1845 1846class BranchCond<bit bit4, string mnemonic> 1847 : I<(outs), (ins ccode:$cond, am_brcond:$target), 1848 mnemonic, ".$cond\t$target", "", 1849 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 1850 let isBranch = 1; 1851 let isTerminator = 1; 1852 let Uses = [NZCV]; 1853 1854 bits<4> cond; 1855 bits<19> target; 1856 let Inst{31-24} = 0b01010100; 1857 let Inst{23-5} = target; 1858 let Inst{4} = bit4; 1859 let Inst{3-0} = cond; 1860} 1861 1862//--- 1863// Compare-and-branch instructions. 1864//--- 1865class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1866 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1867 asm, "\t$Rt, $target", "", 1868 [(node regtype:$Rt, bb:$target)]>, 1869 Sched<[WriteBr]> { 1870 let isBranch = 1; 1871 let isTerminator = 1; 1872 1873 bits<5> Rt; 1874 bits<19> target; 1875 let Inst{30-25} = 0b011010; 1876 let Inst{24} = op; 1877 let Inst{23-5} = target; 1878 let Inst{4-0} = Rt; 1879} 1880 1881multiclass CmpBranch<bit op, string asm, SDNode node> { 1882 def W : BaseCmpBranch<GPR32, op, asm, node> { 1883 let Inst{31} = 0; 1884 } 1885 def X : BaseCmpBranch<GPR64, op, asm, node> { 1886 let Inst{31} = 1; 1887 } 1888} 1889 1890//--- 1891// Test-bit-and-branch instructions. 1892//--- 1893// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1894// the target offset are implied zero and so are not part of the immediate. 1895def am_tbrcond : Operand<OtherVT> { 1896 let EncoderMethod = "getTestBranchTargetOpValue"; 1897 let PrintMethod = "printAlignedLabel"; 1898 let ParserMatchClass = BranchTarget14Operand; 1899 let OperandType = "OPERAND_PCREL"; 1900} 1901 1902// AsmOperand classes to emit (or not) special diagnostics 1903def TBZImm0_31Operand : AsmOperandClass { 1904 let Name = "TBZImm0_31"; 1905 let PredicateMethod = "isImmInRange<0,31>"; 1906 let RenderMethod = "addImmOperands"; 1907} 1908def TBZImm32_63Operand : AsmOperandClass { 1909 let Name = "Imm32_63"; 1910 let PredicateMethod = "isImmInRange<32,63>"; 1911 let DiagnosticType = "InvalidImm0_63"; 1912 let RenderMethod = "addImmOperands"; 1913} 1914 1915class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1916 return (((uint32_t)Imm) < 32); 1917}]> { 1918 let ParserMatchClass = matcher; 1919} 1920 1921def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1922def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1923 1924def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1925 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1926}]> { 1927 let ParserMatchClass = TBZImm32_63Operand; 1928} 1929 1930class BaseTestBranch<RegisterClass regtype, Operand immtype, 1931 bit op, string asm, SDNode node> 1932 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1933 asm, "\t$Rt, $bit_off, $target", "", 1934 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1935 Sched<[WriteBr]> { 1936 let isBranch = 1; 1937 let isTerminator = 1; 1938 1939 bits<5> Rt; 1940 bits<6> bit_off; 1941 bits<14> target; 1942 1943 let Inst{30-25} = 0b011011; 1944 let Inst{24} = op; 1945 let Inst{23-19} = bit_off{4-0}; 1946 let Inst{18-5} = target; 1947 let Inst{4-0} = Rt; 1948 1949 let DecoderMethod = "DecodeTestAndBranch"; 1950} 1951 1952multiclass TestBranch<bit op, string asm, SDNode node> { 1953 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1954 let Inst{31} = 0; 1955 } 1956 1957 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1958 let Inst{31} = 1; 1959 } 1960 1961 // Alias X-reg with 0-31 imm to W-Reg. 1962 def : InstAlias<asm # "\t$Rd, $imm, $target", 1963 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1964 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1965 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1966 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1967 tbz_imm0_31_diag:$imm, bb:$target)>; 1968} 1969 1970//--- 1971// Unconditional branch (immediate) instructions. 1972//--- 1973def am_b_target : Operand<OtherVT> { 1974 let EncoderMethod = "getBranchTargetOpValue"; 1975 let PrintMethod = "printAlignedLabel"; 1976 let ParserMatchClass = BranchTarget26Operand; 1977 let OperandType = "OPERAND_PCREL"; 1978} 1979def am_bl_target : Operand<i64> { 1980 let EncoderMethod = "getBranchTargetOpValue"; 1981 let PrintMethod = "printAlignedLabel"; 1982 let ParserMatchClass = BranchTarget26Operand; 1983 let OperandType = "OPERAND_PCREL"; 1984} 1985 1986class BImm<bit op, dag iops, string asm, list<dag> pattern> 1987 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1988 bits<26> addr; 1989 let Inst{31} = op; 1990 let Inst{30-26} = 0b00101; 1991 let Inst{25-0} = addr; 1992 1993 let DecoderMethod = "DecodeUnconditionalBranch"; 1994} 1995 1996class BranchImm<bit op, string asm, list<dag> pattern> 1997 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1998class CallImm<bit op, string asm, list<dag> pattern> 1999 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 2000 2001//--- 2002// Basic one-operand data processing instructions. 2003//--- 2004 2005let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2006class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 2007 SDPatternOperator node> 2008 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 2009 [(set regtype:$Rd, (node regtype:$Rn))]>, 2010 Sched<[WriteI, ReadI]> { 2011 bits<5> Rd; 2012 bits<5> Rn; 2013 2014 let Inst{30-13} = 0b101101011000000000; 2015 let Inst{12-10} = opc; 2016 let Inst{9-5} = Rn; 2017 let Inst{4-0} = Rd; 2018} 2019 2020let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2021multiclass OneOperandData<bits<3> opc, string asm, 2022 SDPatternOperator node = null_frag> { 2023 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 2024 let Inst{31} = 0; 2025 } 2026 2027 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 2028 let Inst{31} = 1; 2029 } 2030} 2031 2032class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 2033 : BaseOneOperandData<opc, GPR32, asm, node> { 2034 let Inst{31} = 0; 2035} 2036 2037class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 2038 : BaseOneOperandData<opc, GPR64, asm, node> { 2039 let Inst{31} = 1; 2040} 2041 2042class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2043 SDPatternOperator op> 2044 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2045 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2046 Sched<[WriteI, ReadI]> { 2047 bits<5> Rd; 2048 bits<5> Rn; 2049 let Inst{31-15} = 0b11011010110000010; 2050 let Inst{14-12} = opcode_prefix; 2051 let Inst{11-10} = opcode; 2052 let Inst{9-5} = Rn; 2053 let Inst{4-0} = Rd; 2054} 2055 2056class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2057 SDPatternOperator op> 2058 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2059 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2060 Sched<[]> { 2061 bits<5> Rd; 2062 let Inst{31-15} = 0b11011010110000010; 2063 let Inst{14-12} = opcode_prefix; 2064 let Inst{11-10} = opcode; 2065 let Inst{9-5} = 0b11111; 2066 let Inst{4-0} = Rd; 2067} 2068 2069class SignAuthTwoOperand<bits<4> opc, string asm, 2070 SDPatternOperator OpNode> 2071 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2072 asm, "\t$Rd, $Rn, $Rm", "", 2073 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2074 Sched<[WriteI, ReadI, ReadI]> { 2075 bits<5> Rd; 2076 bits<5> Rn; 2077 bits<5> Rm; 2078 let Inst{31-21} = 0b10011010110; 2079 let Inst{20-16} = Rm; 2080 let Inst{15-14} = 0b00; 2081 let Inst{13-10} = opc; 2082 let Inst{9-5} = Rn; 2083 let Inst{4-0} = Rd; 2084} 2085 2086class ClearAuth<bits<1> data, string asm> 2087 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2088 bits<5> Rd; 2089 let Inst{31-11} = 0b110110101100000101000; 2090 let Inst{10} = data; 2091 let Inst{9-5} = 0b11111; 2092 let Inst{4-0} = Rd; 2093} 2094 2095// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2096class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2097 : I<(outs), iops, asm, ops, "", []>, 2098 Sched<[WriteI, ReadI, ReadI]> { 2099 let Uses = [NZCV]; 2100 let Defs = [NZCV]; 2101 bits<5> Rn; 2102 let Inst{31} = sf; 2103 let Inst{30-15} = 0b0111010000000000; 2104 let Inst{14} = sz; 2105 let Inst{13-10} = 0b0010; 2106 let Inst{9-5} = Rn; 2107 let Inst{4-0} = 0b01101; 2108} 2109 2110class FlagRotate<dag iops, string asm, string ops> 2111 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2112 bits<6> imm; 2113 bits<4> mask; 2114 let Inst{20-15} = imm; 2115 let Inst{13-10} = 0b0001; 2116 let Inst{4} = 0b0; 2117 let Inst{3-0} = mask; 2118} 2119 2120//--- 2121// Basic two-operand data processing instructions. 2122//--- 2123class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2124 list<dag> pattern> 2125 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2126 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2127 Sched<[WriteI, ReadI, ReadI]> { 2128 let Uses = [NZCV]; 2129 bits<5> Rd; 2130 bits<5> Rn; 2131 bits<5> Rm; 2132 let Inst{30} = isSub; 2133 let Inst{28-21} = 0b11010000; 2134 let Inst{20-16} = Rm; 2135 let Inst{15-10} = 0; 2136 let Inst{9-5} = Rn; 2137 let Inst{4-0} = Rd; 2138} 2139 2140class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2141 SDNode OpNode> 2142 : BaseBaseAddSubCarry<isSub, regtype, asm, 2143 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2144 2145class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2146 SDNode OpNode> 2147 : BaseBaseAddSubCarry<isSub, regtype, asm, 2148 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2149 (implicit NZCV)]> { 2150 let Defs = [NZCV]; 2151} 2152 2153multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2154 SDNode OpNode, SDNode OpNode_setflags> { 2155 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2156 let Inst{31} = 0; 2157 let Inst{29} = 0; 2158 } 2159 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2160 let Inst{31} = 1; 2161 let Inst{29} = 0; 2162 } 2163 2164 // Sets flags. 2165 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2166 OpNode_setflags> { 2167 let Inst{31} = 0; 2168 let Inst{29} = 1; 2169 } 2170 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2171 OpNode_setflags> { 2172 let Inst{31} = 1; 2173 let Inst{29} = 1; 2174 } 2175} 2176 2177class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2178 SDPatternOperator OpNode, 2179 RegisterClass in1regtype = regtype, 2180 RegisterClass in2regtype = regtype> 2181 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2182 asm, "\t$Rd, $Rn, $Rm", "", 2183 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2184 bits<5> Rd; 2185 bits<5> Rn; 2186 bits<5> Rm; 2187 let Inst{30-21} = 0b0011010110; 2188 let Inst{20-16} = Rm; 2189 let Inst{15-14} = 0b00; 2190 let Inst{13-10} = opc; 2191 let Inst{9-5} = Rn; 2192 let Inst{4-0} = Rd; 2193} 2194 2195class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2196 SDPatternOperator OpNode> 2197 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2198 let Inst{10} = isSigned; 2199} 2200 2201multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2202 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2203 Sched<[WriteID32, ReadID, ReadID]> { 2204 let Inst{31} = 0; 2205 } 2206 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2207 Sched<[WriteID64, ReadID, ReadID]> { 2208 let Inst{31} = 1; 2209 } 2210} 2211 2212class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2213 SDPatternOperator OpNode = null_frag> 2214 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2215 Sched<[WriteIS, ReadI]> { 2216 let Inst{11-10} = shift_type; 2217} 2218 2219multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2220 def Wr : BaseShift<shift_type, GPR32, asm> { 2221 let Inst{31} = 0; 2222 } 2223 2224 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2225 let Inst{31} = 1; 2226 } 2227 2228 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2229 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2230 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2231 2232 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2233 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2234 2235 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2236 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2237 2238 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2239 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2240 2241 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2242 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2243 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2244 2245 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2246 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2247 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2248} 2249 2250class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2251 : InstAlias<asm#"\t$dst, $src1, $src2", 2252 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2253 2254class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2255 RegisterClass addtype, string asm, 2256 list<dag> pattern> 2257 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2258 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2259 bits<5> Rd; 2260 bits<5> Rn; 2261 bits<5> Rm; 2262 bits<5> Ra; 2263 let Inst{30-24} = 0b0011011; 2264 let Inst{23-21} = opc; 2265 let Inst{20-16} = Rm; 2266 let Inst{15} = isSub; 2267 let Inst{14-10} = Ra; 2268 let Inst{9-5} = Rn; 2269 let Inst{4-0} = Rd; 2270} 2271 2272multiclass MulAccum<bit isSub, string asm> { 2273 // MADD/MSUB generation is decided by MachineCombiner.cpp 2274 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2275 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2276 let Inst{31} = 0; 2277 } 2278 2279 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2280 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2281 let Inst{31} = 1; 2282 } 2283} 2284 2285class WideMulAccum<bit isSub, bits<3> opc, string asm, 2286 SDNode AccNode, SDNode ExtNode> 2287 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2288 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2289 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2290 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2291 let Inst{31} = 1; 2292} 2293 2294class MulHi<bits<3> opc, string asm, SDNode OpNode> 2295 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2296 asm, "\t$Rd, $Rn, $Rm", "", 2297 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2298 Sched<[WriteIM64, ReadIM, ReadIM]> { 2299 bits<5> Rd; 2300 bits<5> Rn; 2301 bits<5> Rm; 2302 let Inst{31-24} = 0b10011011; 2303 let Inst{23-21} = opc; 2304 let Inst{20-16} = Rm; 2305 let Inst{15} = 0; 2306 let Inst{9-5} = Rn; 2307 let Inst{4-0} = Rd; 2308 2309 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2310 // (i.e. all bits 1) but is ignored by the processor. 2311 let PostEncoderMethod = "fixMulHigh"; 2312} 2313 2314class MulAccumWAlias<string asm, Instruction inst> 2315 : InstAlias<asm#"\t$dst, $src1, $src2", 2316 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2317class MulAccumXAlias<string asm, Instruction inst> 2318 : InstAlias<asm#"\t$dst, $src1, $src2", 2319 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2320class WideMulAccumAlias<string asm, Instruction inst> 2321 : InstAlias<asm#"\t$dst, $src1, $src2", 2322 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2323 2324class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2325 SDPatternOperator OpNode, string asm> 2326 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2327 asm, "\t$Rd, $Rn, $Rm", "", 2328 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2329 Sched<[WriteISReg, ReadI, ReadISReg]> { 2330 bits<5> Rd; 2331 bits<5> Rn; 2332 bits<5> Rm; 2333 2334 let Inst{31} = sf; 2335 let Inst{30-21} = 0b0011010110; 2336 let Inst{20-16} = Rm; 2337 let Inst{15-13} = 0b010; 2338 let Inst{12} = C; 2339 let Inst{11-10} = sz; 2340 let Inst{9-5} = Rn; 2341 let Inst{4-0} = Rd; 2342 let Predicates = [HasCRC]; 2343} 2344 2345//--- 2346// Address generation. 2347//--- 2348 2349class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2350 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2351 pattern>, 2352 Sched<[WriteI]> { 2353 bits<5> Xd; 2354 bits<21> label; 2355 let Inst{31} = page; 2356 let Inst{30-29} = label{1-0}; 2357 let Inst{28-24} = 0b10000; 2358 let Inst{23-5} = label{20-2}; 2359 let Inst{4-0} = Xd; 2360 2361 let DecoderMethod = "DecodeAdrInstruction"; 2362} 2363 2364//--- 2365// Move immediate. 2366//--- 2367 2368def movimm32_imm : Operand<i32> { 2369 let ParserMatchClass = AsmImmRange<0, 65535>; 2370 let EncoderMethod = "getMoveWideImmOpValue"; 2371 let PrintMethod = "printImm"; 2372} 2373def movimm32_shift : Operand<i32> { 2374 let PrintMethod = "printShifter"; 2375 let ParserMatchClass = MovImm32ShifterOperand; 2376} 2377def movimm64_shift : Operand<i32> { 2378 let PrintMethod = "printShifter"; 2379 let ParserMatchClass = MovImm64ShifterOperand; 2380} 2381 2382let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2383class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2384 string asm> 2385 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2386 asm, "\t$Rd, $imm$shift", "", []>, 2387 Sched<[WriteImm]> { 2388 bits<5> Rd; 2389 bits<16> imm; 2390 bits<6> shift; 2391 let Inst{30-29} = opc; 2392 let Inst{28-23} = 0b100101; 2393 let Inst{22-21} = shift{5-4}; 2394 let Inst{20-5} = imm; 2395 let Inst{4-0} = Rd; 2396 2397 let DecoderMethod = "DecodeMoveImmInstruction"; 2398} 2399 2400multiclass MoveImmediate<bits<2> opc, string asm> { 2401 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2402 let Inst{31} = 0; 2403 } 2404 2405 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2406 let Inst{31} = 1; 2407 } 2408} 2409 2410let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2411class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2412 string asm> 2413 : I<(outs regtype:$Rd), 2414 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2415 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2416 Sched<[WriteI, ReadI]> { 2417 bits<5> Rd; 2418 bits<16> imm; 2419 bits<6> shift; 2420 let Inst{30-29} = opc; 2421 let Inst{28-23} = 0b100101; 2422 let Inst{22-21} = shift{5-4}; 2423 let Inst{20-5} = imm; 2424 let Inst{4-0} = Rd; 2425 2426 let DecoderMethod = "DecodeMoveImmInstruction"; 2427} 2428 2429multiclass InsertImmediate<bits<2> opc, string asm> { 2430 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2431 let Inst{31} = 0; 2432 } 2433 2434 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2435 let Inst{31} = 1; 2436 } 2437} 2438 2439//--- 2440// Add/Subtract 2441//--- 2442 2443class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2444 string asm_inst, string asm_ops, 2445 dag inputs, dag pattern> 2446 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2447 Sched<[WriteI, ReadI]> { 2448 bits<5> Rd; 2449 bits<5> Rn; 2450 let Inst{30} = isSub; 2451 let Inst{29} = setFlags; 2452 let Inst{28-24} = 0b10001; 2453 let Inst{9-5} = Rn; 2454 let Inst{4-0} = Rd; 2455} 2456 2457class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2458 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2459 string asm_inst, SDPatternOperator OpNode> 2460 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2461 (ins srcRegtype:$Rn, immtype:$imm), 2462 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2463 bits<14> imm; 2464 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2465 let Inst{21-10} = imm{11-0}; 2466 let DecoderMethod = "DecodeAddSubImmShift"; 2467} 2468 2469class BaseAddSubRegPseudo<RegisterClass regtype, 2470 SDPatternOperator OpNode> 2471 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2472 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2473 Sched<[WriteI, ReadI, ReadI]>; 2474 2475class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2476 arith_shifted_reg shifted_regtype, string asm, 2477 SDPatternOperator OpNode> 2478 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2479 asm, "\t$Rd, $Rn, $Rm", "", 2480 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2481 Sched<[WriteISReg, ReadI, ReadISReg]> { 2482 // The operands are in order to match the 'addr' MI operands, so we 2483 // don't need an encoder method and by-name matching. Just use the default 2484 // in-order handling. Since we're using by-order, make sure the names 2485 // do not match. 2486 bits<5> dst; 2487 bits<5> src1; 2488 bits<5> src2; 2489 bits<8> shift; 2490 let Inst{30} = isSub; 2491 let Inst{29} = setFlags; 2492 let Inst{28-24} = 0b01011; 2493 let Inst{23-22} = shift{7-6}; 2494 let Inst{21} = 0; 2495 let Inst{20-16} = src2; 2496 let Inst{15-10} = shift{5-0}; 2497 let Inst{9-5} = src1; 2498 let Inst{4-0} = dst; 2499 2500 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2501} 2502 2503class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2504 RegisterClass src1Regtype, Operand src2Regtype, 2505 string asm, SDPatternOperator OpNode> 2506 : I<(outs dstRegtype:$R1), 2507 (ins src1Regtype:$R2, src2Regtype:$R3), 2508 asm, "\t$R1, $R2, $R3", "", 2509 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2510 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2511 bits<5> Rd; 2512 bits<5> Rn; 2513 bits<5> Rm; 2514 bits<6> ext; 2515 let Inst{30} = isSub; 2516 let Inst{29} = setFlags; 2517 let Inst{28-24} = 0b01011; 2518 let Inst{23-21} = 0b001; 2519 let Inst{20-16} = Rm; 2520 let Inst{15-13} = ext{5-3}; 2521 let Inst{12-10} = ext{2-0}; 2522 let Inst{9-5} = Rn; 2523 let Inst{4-0} = Rd; 2524 2525 let DecoderMethod = "DecodeAddSubERegInstruction"; 2526} 2527 2528let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2529class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2530 RegisterClass src1Regtype, RegisterClass src2Regtype, 2531 Operand ext_op, string asm> 2532 : I<(outs dstRegtype:$Rd), 2533 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2534 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2535 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2536 bits<5> Rd; 2537 bits<5> Rn; 2538 bits<5> Rm; 2539 bits<6> ext; 2540 let Inst{30} = isSub; 2541 let Inst{29} = setFlags; 2542 let Inst{28-24} = 0b01011; 2543 let Inst{23-21} = 0b001; 2544 let Inst{20-16} = Rm; 2545 let Inst{15} = ext{5}; 2546 let Inst{12-10} = ext{2-0}; 2547 let Inst{9-5} = Rn; 2548 let Inst{4-0} = Rd; 2549 2550 let DecoderMethod = "DecodeAddSubERegInstruction"; 2551} 2552 2553// Aliases for register+register add/subtract. 2554class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2555 RegisterClass src1Regtype, RegisterClass src2Regtype, 2556 int shiftExt> 2557 : InstAlias<asm#"\t$dst, $src1, $src2", 2558 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2559 shiftExt)>; 2560 2561multiclass AddSub<bit isSub, string mnemonic, string alias, 2562 SDPatternOperator OpNode = null_frag> { 2563 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2564 // Add/Subtract immediate 2565 // Increase the weight of the immediate variant to try to match it before 2566 // the extended register variant. 2567 // We used to match the register variant before the immediate when the 2568 // register argument could be implicitly zero-extended. 2569 let AddedComplexity = 6 in 2570 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2571 mnemonic, OpNode> { 2572 let Inst{31} = 0; 2573 } 2574 let AddedComplexity = 6 in 2575 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2576 mnemonic, OpNode> { 2577 let Inst{31} = 1; 2578 } 2579 2580 // Add/Subtract register - Only used for CodeGen 2581 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2582 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2583 2584 // Add/Subtract shifted register 2585 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2586 OpNode> { 2587 let Inst{31} = 0; 2588 } 2589 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2590 OpNode> { 2591 let Inst{31} = 1; 2592 } 2593 } 2594 2595 // Add/Subtract extended register 2596 let AddedComplexity = 1, hasSideEffects = 0 in { 2597 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2598 arith_extended_reg32_i32, mnemonic, OpNode> { 2599 let Inst{31} = 0; 2600 } 2601 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2602 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2603 let Inst{31} = 1; 2604 } 2605 } 2606 2607 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2608 arith_extendlsl64, mnemonic> { 2609 // UXTX and SXTX only. 2610 let Inst{14-13} = 0b11; 2611 let Inst{31} = 1; 2612 } 2613 2614 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2615 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2616 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2617 addsub_shifted_imm32_neg:$imm), 0>; 2618 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2619 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2620 addsub_shifted_imm64_neg:$imm), 0>; 2621 2622 // Register/register aliases with no shift when SP is not used. 2623 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2624 GPR32, GPR32, GPR32, 0>; 2625 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2626 GPR64, GPR64, GPR64, 0>; 2627 2628 // Register/register aliases with no shift when either the destination or 2629 // first source register is SP. 2630 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2631 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2632 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2633 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2634 def : AddSubRegAlias<mnemonic, 2635 !cast<Instruction>(NAME#"Xrx64"), 2636 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2637 def : AddSubRegAlias<mnemonic, 2638 !cast<Instruction>(NAME#"Xrx64"), 2639 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2640} 2641 2642multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2643 string alias, string cmpAlias> { 2644 let isCompare = 1, Defs = [NZCV] in { 2645 // Add/Subtract immediate 2646 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2647 mnemonic, OpNode> { 2648 let Inst{31} = 0; 2649 } 2650 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2651 mnemonic, OpNode> { 2652 let Inst{31} = 1; 2653 } 2654 2655 // Add/Subtract register 2656 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2657 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2658 2659 // Add/Subtract shifted register 2660 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2661 OpNode> { 2662 let Inst{31} = 0; 2663 } 2664 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2665 OpNode> { 2666 let Inst{31} = 1; 2667 } 2668 2669 // Add/Subtract extended register 2670 let AddedComplexity = 1 in { 2671 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2672 arith_extended_reg32_i32, mnemonic, OpNode> { 2673 let Inst{31} = 0; 2674 } 2675 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2676 arith_extended_reg32_i64, mnemonic, OpNode> { 2677 let Inst{31} = 1; 2678 } 2679 } 2680 2681 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2682 arith_extendlsl64, mnemonic> { 2683 // UXTX and SXTX only. 2684 let Inst{14-13} = 0b11; 2685 let Inst{31} = 1; 2686 } 2687 } // Defs = [NZCV] 2688 2689 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2690 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2691 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2692 addsub_shifted_imm32_neg:$imm), 0>; 2693 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2694 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2695 addsub_shifted_imm64_neg:$imm), 0>; 2696 2697 // Compare aliases 2698 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2699 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2700 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2701 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2702 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2703 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2704 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2705 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2706 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2707 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2708 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2709 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2710 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2711 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2712 2713 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2714 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2715 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2716 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2717 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2718 2719 // Compare shorthands 2720 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2721 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2722 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2723 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2724 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2725 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2726 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2727 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2728 2729 // Register/register aliases with no shift when SP is not used. 2730 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2731 GPR32, GPR32, GPR32, 0>; 2732 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2733 GPR64, GPR64, GPR64, 0>; 2734 2735 // Register/register aliases with no shift when the first source register 2736 // is SP. 2737 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2738 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2739 def : AddSubRegAlias<mnemonic, 2740 !cast<Instruction>(NAME#"Xrx64"), 2741 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2742} 2743 2744class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2745 : BaseAddSubImm< 2746 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2747 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2748 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2749 bits<6> imm6; 2750 bits<4> imm4; 2751 let Inst{31} = 1; 2752 let Inst{23-22} = 0b10; 2753 let Inst{21-16} = imm6; 2754 let Inst{15-14} = 0b00; 2755 let Inst{13-10} = imm4; 2756 let Unpredictable{15-14} = 0b11; 2757} 2758 2759class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2760 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2761 let Inst{31} = 1; 2762 let Inst{29} = setsFlags; 2763} 2764 2765//--- 2766// Extract 2767//--- 2768def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2769 SDTCisPtrTy<3>]>; 2770def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2771 2772class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2773 list<dag> patterns> 2774 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2775 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2776 Sched<[WriteExtr, ReadExtrHi]> { 2777 bits<5> Rd; 2778 bits<5> Rn; 2779 bits<5> Rm; 2780 bits<6> imm; 2781 2782 let Inst{30-23} = 0b00100111; 2783 let Inst{21} = 0; 2784 let Inst{20-16} = Rm; 2785 let Inst{15-10} = imm; 2786 let Inst{9-5} = Rn; 2787 let Inst{4-0} = Rd; 2788} 2789 2790multiclass ExtractImm<string asm> { 2791 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2792 [(set GPR32:$Rd, 2793 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2794 let Inst{31} = 0; 2795 let Inst{22} = 0; 2796 // imm<5> must be zero. 2797 let imm{5} = 0; 2798 } 2799 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2800 [(set GPR64:$Rd, 2801 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2802 2803 let Inst{31} = 1; 2804 let Inst{22} = 1; 2805 } 2806} 2807 2808//--- 2809// Bitfield 2810//--- 2811 2812let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2813class BaseBitfieldImm<bits<2> opc, 2814 RegisterClass regtype, Operand imm_type, string asm> 2815 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2816 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2817 Sched<[WriteIS, ReadI]> { 2818 bits<5> Rd; 2819 bits<5> Rn; 2820 bits<6> immr; 2821 bits<6> imms; 2822 2823 let Inst{30-29} = opc; 2824 let Inst{28-23} = 0b100110; 2825 let Inst{21-16} = immr; 2826 let Inst{15-10} = imms; 2827 let Inst{9-5} = Rn; 2828 let Inst{4-0} = Rd; 2829} 2830 2831multiclass BitfieldImm<bits<2> opc, string asm> { 2832 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2833 let Inst{31} = 0; 2834 let Inst{22} = 0; 2835 // imms<5> and immr<5> must be zero, else ReservedValue(). 2836 let Inst{21} = 0; 2837 let Inst{15} = 0; 2838 } 2839 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2840 let Inst{31} = 1; 2841 let Inst{22} = 1; 2842 } 2843} 2844 2845let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2846class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2847 RegisterClass regtype, Operand imm_type, string asm> 2848 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2849 imm_type:$imms), 2850 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2851 Sched<[WriteIS, ReadI]> { 2852 bits<5> Rd; 2853 bits<5> Rn; 2854 bits<6> immr; 2855 bits<6> imms; 2856 2857 let Inst{30-29} = opc; 2858 let Inst{28-23} = 0b100110; 2859 let Inst{21-16} = immr; 2860 let Inst{15-10} = imms; 2861 let Inst{9-5} = Rn; 2862 let Inst{4-0} = Rd; 2863} 2864 2865multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2866 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2867 let Inst{31} = 0; 2868 let Inst{22} = 0; 2869 // imms<5> and immr<5> must be zero, else ReservedValue(). 2870 let Inst{21} = 0; 2871 let Inst{15} = 0; 2872 } 2873 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2874 let Inst{31} = 1; 2875 let Inst{22} = 1; 2876 } 2877} 2878 2879//--- 2880// Logical 2881//--- 2882 2883// Logical (immediate) 2884class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2885 RegisterClass sregtype, Operand imm_type, string asm, 2886 list<dag> pattern> 2887 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2888 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2889 Sched<[WriteI, ReadI]> { 2890 bits<5> Rd; 2891 bits<5> Rn; 2892 bits<13> imm; 2893 let Inst{30-29} = opc; 2894 let Inst{28-23} = 0b100100; 2895 let Inst{22} = imm{12}; 2896 let Inst{21-16} = imm{11-6}; 2897 let Inst{15-10} = imm{5-0}; 2898 let Inst{9-5} = Rn; 2899 let Inst{4-0} = Rd; 2900 2901 let DecoderMethod = "DecodeLogicalImmInstruction"; 2902} 2903 2904// Logical (shifted register) 2905class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2906 logical_shifted_reg shifted_regtype, string asm, 2907 list<dag> pattern> 2908 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2909 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2910 Sched<[WriteISReg, ReadI, ReadISReg]> { 2911 // The operands are in order to match the 'addr' MI operands, so we 2912 // don't need an encoder method and by-name matching. Just use the default 2913 // in-order handling. Since we're using by-order, make sure the names 2914 // do not match. 2915 bits<5> dst; 2916 bits<5> src1; 2917 bits<5> src2; 2918 bits<8> shift; 2919 let Inst{30-29} = opc; 2920 let Inst{28-24} = 0b01010; 2921 let Inst{23-22} = shift{7-6}; 2922 let Inst{21} = N; 2923 let Inst{20-16} = src2; 2924 let Inst{15-10} = shift{5-0}; 2925 let Inst{9-5} = src1; 2926 let Inst{4-0} = dst; 2927 2928 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2929} 2930 2931// Aliases for register+register logical instructions. 2932class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2933 : InstAlias<asm#"\t$dst, $src1, $src2", 2934 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2935 2936multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2937 string Alias> { 2938 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2939 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2940 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2941 logical_imm32:$imm))]> { 2942 let Inst{31} = 0; 2943 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2944 } 2945 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2946 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2947 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2948 logical_imm64:$imm))]> { 2949 let Inst{31} = 1; 2950 } 2951 2952 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2953 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2954 logical_imm32_not:$imm), 0>; 2955 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2956 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2957 logical_imm64_not:$imm), 0>; 2958} 2959 2960multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2961 string Alias> { 2962 let isCompare = 1, Defs = [NZCV] in { 2963 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2964 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2965 let Inst{31} = 0; 2966 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2967 } 2968 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2969 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2970 let Inst{31} = 1; 2971 } 2972 } // end Defs = [NZCV] 2973 2974 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2975 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2976 logical_imm32_not:$imm), 0>; 2977 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2978 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2979 logical_imm64_not:$imm), 0>; 2980} 2981 2982class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2983 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2984 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2985 Sched<[WriteI, ReadI, ReadI]>; 2986 2987// Split from LogicalImm as not all instructions have both. 2988multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2989 SDPatternOperator OpNode> { 2990 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2991 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2992 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2993 } 2994 2995 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2996 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2997 logical_shifted_reg32:$Rm))]> { 2998 let Inst{31} = 0; 2999 } 3000 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3001 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3002 logical_shifted_reg64:$Rm))]> { 3003 let Inst{31} = 1; 3004 } 3005 3006 def : LogicalRegAlias<mnemonic, 3007 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3008 def : LogicalRegAlias<mnemonic, 3009 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3010} 3011 3012// Split from LogicalReg to allow setting NZCV Defs 3013multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3014 SDPatternOperator OpNode = null_frag> { 3015 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3016 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3017 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3018 3019 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3020 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 3021 let Inst{31} = 0; 3022 } 3023 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3024 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 3025 let Inst{31} = 1; 3026 } 3027 } // Defs = [NZCV] 3028 3029 def : LogicalRegAlias<mnemonic, 3030 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3031 def : LogicalRegAlias<mnemonic, 3032 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3033} 3034 3035//--- 3036// Conditionally set flags 3037//--- 3038 3039let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3040class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3041 string mnemonic, SDNode OpNode> 3042 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3043 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3044 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3045 (i32 imm:$cond), NZCV))]>, 3046 Sched<[WriteI, ReadI]> { 3047 let Uses = [NZCV]; 3048 let Defs = [NZCV]; 3049 3050 bits<5> Rn; 3051 bits<5> imm; 3052 bits<4> nzcv; 3053 bits<4> cond; 3054 3055 let Inst{30} = op; 3056 let Inst{29-21} = 0b111010010; 3057 let Inst{20-16} = imm; 3058 let Inst{15-12} = cond; 3059 let Inst{11-10} = 0b10; 3060 let Inst{9-5} = Rn; 3061 let Inst{4} = 0b0; 3062 let Inst{3-0} = nzcv; 3063} 3064 3065let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3066class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3067 SDNode OpNode> 3068 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3069 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3070 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3071 (i32 imm:$cond), NZCV))]>, 3072 Sched<[WriteI, ReadI, ReadI]> { 3073 let Uses = [NZCV]; 3074 let Defs = [NZCV]; 3075 3076 bits<5> Rn; 3077 bits<5> Rm; 3078 bits<4> nzcv; 3079 bits<4> cond; 3080 3081 let Inst{30} = op; 3082 let Inst{29-21} = 0b111010010; 3083 let Inst{20-16} = Rm; 3084 let Inst{15-12} = cond; 3085 let Inst{11-10} = 0b00; 3086 let Inst{9-5} = Rn; 3087 let Inst{4} = 0b0; 3088 let Inst{3-0} = nzcv; 3089} 3090 3091multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3092 // immediate operand variants 3093 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3094 let Inst{31} = 0; 3095 } 3096 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3097 let Inst{31} = 1; 3098 } 3099 // register operand variants 3100 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3101 let Inst{31} = 0; 3102 } 3103 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3104 let Inst{31} = 1; 3105 } 3106} 3107 3108//--- 3109// Conditional select 3110//--- 3111 3112class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3113 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3114 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3115 [(set regtype:$Rd, 3116 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3117 Sched<[WriteI, ReadI, ReadI]> { 3118 let Uses = [NZCV]; 3119 3120 bits<5> Rd; 3121 bits<5> Rn; 3122 bits<5> Rm; 3123 bits<4> cond; 3124 3125 let Inst{30} = op; 3126 let Inst{29-21} = 0b011010100; 3127 let Inst{20-16} = Rm; 3128 let Inst{15-12} = cond; 3129 let Inst{11-10} = op2; 3130 let Inst{9-5} = Rn; 3131 let Inst{4-0} = Rd; 3132} 3133 3134multiclass CondSelect<bit op, bits<2> op2, string asm> { 3135 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3136 let Inst{31} = 0; 3137 } 3138 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3139 let Inst{31} = 1; 3140 } 3141} 3142 3143class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3144 PatFrag frag> 3145 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3146 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3147 [(set regtype:$Rd, 3148 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3149 (i32 imm:$cond), NZCV))]>, 3150 Sched<[WriteI, ReadI, ReadI]> { 3151 let Uses = [NZCV]; 3152 3153 bits<5> Rd; 3154 bits<5> Rn; 3155 bits<5> Rm; 3156 bits<4> cond; 3157 3158 let Inst{30} = op; 3159 let Inst{29-21} = 0b011010100; 3160 let Inst{20-16} = Rm; 3161 let Inst{15-12} = cond; 3162 let Inst{11-10} = op2; 3163 let Inst{9-5} = Rn; 3164 let Inst{4-0} = Rd; 3165} 3166 3167def inv_cond_XFORM : SDNodeXForm<imm, [{ 3168 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3169 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3170 MVT::i32); 3171}]>; 3172 3173multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3174 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3175 let Inst{31} = 0; 3176 } 3177 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3178 let Inst{31} = 1; 3179 } 3180 3181 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3182 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3183 (inv_cond_XFORM imm:$cond))>; 3184 3185 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3186 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3187 (inv_cond_XFORM imm:$cond))>; 3188} 3189 3190//--- 3191// Special Mask Value 3192//--- 3193def maski8_or_more : Operand<i32>, 3194 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3195} 3196def maski16_or_more : Operand<i32>, 3197 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3198} 3199 3200 3201//--- 3202// Load/store 3203//--- 3204 3205// (unsigned immediate) 3206// Indexed for 8-bit registers. offset is in range [0,4095]. 3207def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3208def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3209def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3210def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3211def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3212 3213// (unsigned immediate) 3214// Indexed for 8-bit registers. offset is in range [0,63]. 3215def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3216def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3217def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3218def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3219 3220def gi_am_indexed8 : 3221 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3222 GIComplexPatternEquiv<am_indexed8>; 3223def gi_am_indexed16 : 3224 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3225 GIComplexPatternEquiv<am_indexed16>; 3226def gi_am_indexed32 : 3227 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3228 GIComplexPatternEquiv<am_indexed32>; 3229def gi_am_indexed64 : 3230 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3231 GIComplexPatternEquiv<am_indexed64>; 3232def gi_am_indexed128 : 3233 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3234 GIComplexPatternEquiv<am_indexed128>; 3235 3236class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3237 let Name = "UImm12Offset" # Scale; 3238 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3239 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3240 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3241} 3242 3243def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3244def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3245def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3246def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3247def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3248 3249class uimm12_scaled<int Scale> : Operand<i64> { 3250 let ParserMatchClass 3251 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3252 let EncoderMethod 3253 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3254 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3255} 3256 3257def uimm12s1 : uimm12_scaled<1>; 3258def uimm12s2 : uimm12_scaled<2>; 3259def uimm12s4 : uimm12_scaled<4>; 3260def uimm12s8 : uimm12_scaled<8>; 3261def uimm12s16 : uimm12_scaled<16>; 3262 3263class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3264 string asm, list<dag> pattern> 3265 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3266 bits<5> Rt; 3267 3268 bits<5> Rn; 3269 bits<12> offset; 3270 3271 let Inst{31-30} = sz; 3272 let Inst{29-27} = 0b111; 3273 let Inst{26} = V; 3274 let Inst{25-24} = 0b01; 3275 let Inst{23-22} = opc; 3276 let Inst{21-10} = offset; 3277 let Inst{9-5} = Rn; 3278 let Inst{4-0} = Rt; 3279 3280 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3281} 3282 3283multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3284 Operand indextype, string asm, list<dag> pattern> { 3285 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3286 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3287 (ins GPR64sp:$Rn, indextype:$offset), 3288 asm, pattern>, 3289 Sched<[WriteLD]>; 3290 3291 def : InstAlias<asm # "\t$Rt, [$Rn]", 3292 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3293} 3294 3295multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3296 Operand indextype, string asm, list<dag> pattern> { 3297 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3298 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3299 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3300 asm, pattern>, 3301 Sched<[WriteST]>; 3302 3303 def : InstAlias<asm # "\t$Rt, [$Rn]", 3304 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3305} 3306 3307// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3308// substitute zero-registers automatically. 3309// 3310// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3311// into StoreUI. 3312multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3313 Operand indextype, string asm, list<dag> pattern> { 3314 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3315 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3316 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3317 asm, pattern>, 3318 Sched<[WriteST]>; 3319 3320 def : InstAlias<asm # "\t$Rt, [$Rn]", 3321 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3322} 3323 3324def PrefetchOperand : AsmOperandClass { 3325 let Name = "Prefetch"; 3326 let ParserMethod = "tryParsePrefetch"; 3327} 3328def prfop : Operand<i32> { 3329 let PrintMethod = "printPrefetchOp"; 3330 let ParserMatchClass = PrefetchOperand; 3331} 3332 3333let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3334class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3335 : BaseLoadStoreUI<sz, V, opc, 3336 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3337 asm, pat>, 3338 Sched<[WriteLD]>; 3339 3340//--- 3341// Load literal 3342//--- 3343 3344// Load literal address: 19-bit immediate. The low two bits of the target 3345// offset are implied zero and so are not part of the immediate. 3346def am_ldrlit : Operand<iPTR> { 3347 let EncoderMethod = "getLoadLiteralOpValue"; 3348 let DecoderMethod = "DecodePCRelLabel19"; 3349 let PrintMethod = "printAlignedLabel"; 3350 let ParserMatchClass = PCRelLabel19Operand; 3351 let OperandType = "OPERAND_PCREL"; 3352} 3353 3354let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3355class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3356 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3357 asm, "\t$Rt, $label", "", pat>, 3358 Sched<[WriteLD]> { 3359 bits<5> Rt; 3360 bits<19> label; 3361 let Inst{31-30} = opc; 3362 let Inst{29-27} = 0b011; 3363 let Inst{26} = V; 3364 let Inst{25-24} = 0b00; 3365 let Inst{23-5} = label; 3366 let Inst{4-0} = Rt; 3367} 3368 3369let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3370class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3371 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3372 asm, "\t$Rt, $label", "", pat>, 3373 Sched<[WriteLD]> { 3374 bits<5> Rt; 3375 bits<19> label; 3376 let Inst{31-30} = opc; 3377 let Inst{29-27} = 0b011; 3378 let Inst{26} = V; 3379 let Inst{25-24} = 0b00; 3380 let Inst{23-5} = label; 3381 let Inst{4-0} = Rt; 3382} 3383 3384//--- 3385// Load/store register offset 3386//--- 3387 3388def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3389def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3390def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3391def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3392def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3393 3394def gi_ro_Xindexed8 : 3395 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3396 GIComplexPatternEquiv<ro_Xindexed8>; 3397def gi_ro_Xindexed16 : 3398 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3399 GIComplexPatternEquiv<ro_Xindexed16>; 3400def gi_ro_Xindexed32 : 3401 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3402 GIComplexPatternEquiv<ro_Xindexed32>; 3403def gi_ro_Xindexed64 : 3404 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3405 GIComplexPatternEquiv<ro_Xindexed64>; 3406def gi_ro_Xindexed128 : 3407 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3408 GIComplexPatternEquiv<ro_Xindexed128>; 3409 3410def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3411def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3412def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3413def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3414def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3415 3416def gi_ro_Windexed8 : 3417 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3418 GIComplexPatternEquiv<ro_Windexed8>; 3419def gi_ro_Windexed16 : 3420 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3421 GIComplexPatternEquiv<ro_Windexed16>; 3422def gi_ro_Windexed32 : 3423 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3424 GIComplexPatternEquiv<ro_Windexed32>; 3425def gi_ro_Windexed64 : 3426 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3427 GIComplexPatternEquiv<ro_Windexed64>; 3428def gi_ro_Windexed128 : 3429 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3430 GIComplexPatternEquiv<ro_Windexed128>; 3431 3432class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3433 let Name = "Mem" # Reg # "Extend" # Width; 3434 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3435 let RenderMethod = "addMemExtendOperands"; 3436 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3437} 3438 3439def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3440 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3441 // the trivial shift. 3442 let RenderMethod = "addMemExtend8Operands"; 3443} 3444def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3445def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3446def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3447def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3448 3449def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3450 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3451 // the trivial shift. 3452 let RenderMethod = "addMemExtend8Operands"; 3453} 3454def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3455def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3456def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3457def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3458 3459class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3460 : Operand<i32> { 3461 let ParserMatchClass = ParserClass; 3462 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3463 let DecoderMethod = "DecodeMemExtend"; 3464 let EncoderMethod = "getMemExtendOpValue"; 3465 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3466} 3467 3468def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3469def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3470def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3471def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3472def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3473 3474def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3475def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3476def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3477def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3478def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3479 3480class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3481 Operand wextend, Operand xextend> { 3482 // CodeGen-level pattern covering the entire addressing mode. 3483 ComplexPattern Wpat = windex; 3484 ComplexPattern Xpat = xindex; 3485 3486 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3487 Operand Wext = wextend; 3488 Operand Xext = xextend; 3489} 3490 3491def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3492def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3493def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3494def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3495def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3496 ro_Xextend128>; 3497 3498class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3499 dag outs, list<dag> pat> 3500 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3501 bits<5> Rt; 3502 bits<5> Rn; 3503 bits<5> Rm; 3504 bits<2> extend; 3505 let Inst{31-30} = sz; 3506 let Inst{29-27} = 0b111; 3507 let Inst{26} = V; 3508 let Inst{25-24} = 0b00; 3509 let Inst{23-22} = opc; 3510 let Inst{21} = 1; 3511 let Inst{20-16} = Rm; 3512 let Inst{15} = extend{1}; // sign extend Rm? 3513 let Inst{14} = 1; 3514 let Inst{12} = extend{0}; // do shift? 3515 let Inst{11-10} = 0b10; 3516 let Inst{9-5} = Rn; 3517 let Inst{4-0} = Rt; 3518} 3519 3520class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3521 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3522 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3523 3524multiclass Load8RO<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 : LoadStore8RO<sz, V, opc, asm, 3528 (outs regtype:$Rt), 3529 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3530 [(set (Ty regtype:$Rt), 3531 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3532 ro_Wextend8:$extend)))]>, 3533 Sched<[WriteLDIdx, ReadAdrBase]> { 3534 let Inst{13} = 0b0; 3535 } 3536 3537 let AddedComplexity = 10 in 3538 def roX : LoadStore8RO<sz, V, opc, asm, 3539 (outs regtype:$Rt), 3540 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3541 [(set (Ty regtype:$Rt), 3542 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3543 ro_Xextend8:$extend)))]>, 3544 Sched<[WriteLDIdx, ReadAdrBase]> { 3545 let Inst{13} = 0b1; 3546 } 3547 3548 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3549} 3550 3551multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3552 string asm, ValueType Ty, SDPatternOperator storeop> { 3553 let AddedComplexity = 10 in 3554 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3555 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3556 [(storeop (Ty regtype:$Rt), 3557 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3558 ro_Wextend8:$extend))]>, 3559 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3560 let Inst{13} = 0b0; 3561 } 3562 3563 let AddedComplexity = 10 in 3564 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3565 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3566 [(storeop (Ty regtype:$Rt), 3567 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3568 ro_Xextend8:$extend))]>, 3569 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3570 let Inst{13} = 0b1; 3571 } 3572 3573 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3574} 3575 3576class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3577 dag outs, list<dag> pat> 3578 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3579 bits<5> Rt; 3580 bits<5> Rn; 3581 bits<5> Rm; 3582 bits<2> extend; 3583 let Inst{31-30} = sz; 3584 let Inst{29-27} = 0b111; 3585 let Inst{26} = V; 3586 let Inst{25-24} = 0b00; 3587 let Inst{23-22} = opc; 3588 let Inst{21} = 1; 3589 let Inst{20-16} = Rm; 3590 let Inst{15} = extend{1}; // sign extend Rm? 3591 let Inst{14} = 1; 3592 let Inst{12} = extend{0}; // do shift? 3593 let Inst{11-10} = 0b10; 3594 let Inst{9-5} = Rn; 3595 let Inst{4-0} = Rt; 3596} 3597 3598multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3599 string asm, ValueType Ty, SDPatternOperator loadop> { 3600 let AddedComplexity = 10 in 3601 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3602 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3603 [(set (Ty regtype:$Rt), 3604 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3605 ro_Wextend16:$extend)))]>, 3606 Sched<[WriteLDIdx, ReadAdrBase]> { 3607 let Inst{13} = 0b0; 3608 } 3609 3610 let AddedComplexity = 10 in 3611 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3612 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3613 [(set (Ty regtype:$Rt), 3614 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3615 ro_Xextend16:$extend)))]>, 3616 Sched<[WriteLDIdx, ReadAdrBase]> { 3617 let Inst{13} = 0b1; 3618 } 3619 3620 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3621} 3622 3623multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3624 string asm, ValueType Ty, SDPatternOperator storeop> { 3625 let AddedComplexity = 10 in 3626 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3627 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3628 [(storeop (Ty regtype:$Rt), 3629 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3630 ro_Wextend16:$extend))]>, 3631 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3632 let Inst{13} = 0b0; 3633 } 3634 3635 let AddedComplexity = 10 in 3636 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3637 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3638 [(storeop (Ty regtype:$Rt), 3639 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3640 ro_Xextend16:$extend))]>, 3641 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3642 let Inst{13} = 0b1; 3643 } 3644 3645 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3646} 3647 3648class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3649 dag outs, list<dag> pat> 3650 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3651 bits<5> Rt; 3652 bits<5> Rn; 3653 bits<5> Rm; 3654 bits<2> extend; 3655 let Inst{31-30} = sz; 3656 let Inst{29-27} = 0b111; 3657 let Inst{26} = V; 3658 let Inst{25-24} = 0b00; 3659 let Inst{23-22} = opc; 3660 let Inst{21} = 1; 3661 let Inst{20-16} = Rm; 3662 let Inst{15} = extend{1}; // sign extend Rm? 3663 let Inst{14} = 1; 3664 let Inst{12} = extend{0}; // do shift? 3665 let Inst{11-10} = 0b10; 3666 let Inst{9-5} = Rn; 3667 let Inst{4-0} = Rt; 3668} 3669 3670multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3671 string asm, ValueType Ty, SDPatternOperator loadop> { 3672 let AddedComplexity = 10 in 3673 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3674 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3675 [(set (Ty regtype:$Rt), 3676 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3677 ro_Wextend32:$extend)))]>, 3678 Sched<[WriteLDIdx, ReadAdrBase]> { 3679 let Inst{13} = 0b0; 3680 } 3681 3682 let AddedComplexity = 10 in 3683 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3684 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3685 [(set (Ty regtype:$Rt), 3686 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3687 ro_Xextend32:$extend)))]>, 3688 Sched<[WriteLDIdx, ReadAdrBase]> { 3689 let Inst{13} = 0b1; 3690 } 3691 3692 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3693} 3694 3695multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3696 string asm, ValueType Ty, SDPatternOperator storeop> { 3697 let AddedComplexity = 10 in 3698 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 3699 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3700 [(storeop (Ty regtype:$Rt), 3701 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3702 ro_Wextend32:$extend))]>, 3703 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3704 let Inst{13} = 0b0; 3705 } 3706 3707 let AddedComplexity = 10 in 3708 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 3709 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3710 [(storeop (Ty regtype:$Rt), 3711 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3712 ro_Xextend32:$extend))]>, 3713 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3714 let Inst{13} = 0b1; 3715 } 3716 3717 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3718} 3719 3720class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3721 dag outs, list<dag> pat> 3722 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3723 bits<5> Rt; 3724 bits<5> Rn; 3725 bits<5> Rm; 3726 bits<2> extend; 3727 let Inst{31-30} = sz; 3728 let Inst{29-27} = 0b111; 3729 let Inst{26} = V; 3730 let Inst{25-24} = 0b00; 3731 let Inst{23-22} = opc; 3732 let Inst{21} = 1; 3733 let Inst{20-16} = Rm; 3734 let Inst{15} = extend{1}; // sign extend Rm? 3735 let Inst{14} = 1; 3736 let Inst{12} = extend{0}; // do shift? 3737 let Inst{11-10} = 0b10; 3738 let Inst{9-5} = Rn; 3739 let Inst{4-0} = Rt; 3740} 3741 3742multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3743 string asm, ValueType Ty, SDPatternOperator loadop> { 3744 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3745 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3746 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3747 [(set (Ty regtype:$Rt), 3748 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3749 ro_Wextend64:$extend)))]>, 3750 Sched<[WriteLDIdx, ReadAdrBase]> { 3751 let Inst{13} = 0b0; 3752 } 3753 3754 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3755 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3756 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3757 [(set (Ty regtype:$Rt), 3758 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3759 ro_Xextend64:$extend)))]>, 3760 Sched<[WriteLDIdx, ReadAdrBase]> { 3761 let Inst{13} = 0b1; 3762 } 3763 3764 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3765} 3766 3767multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3768 string asm, ValueType Ty, SDPatternOperator storeop> { 3769 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3770 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 3771 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3772 [(storeop (Ty regtype:$Rt), 3773 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3774 ro_Wextend64:$extend))]>, 3775 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3776 let Inst{13} = 0b0; 3777 } 3778 3779 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3780 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 3781 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3782 [(storeop (Ty regtype:$Rt), 3783 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3784 ro_Xextend64:$extend))]>, 3785 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3786 let Inst{13} = 0b1; 3787 } 3788 3789 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3790} 3791 3792class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3793 dag outs, list<dag> pat> 3794 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3795 bits<5> Rt; 3796 bits<5> Rn; 3797 bits<5> Rm; 3798 bits<2> extend; 3799 let Inst{31-30} = sz; 3800 let Inst{29-27} = 0b111; 3801 let Inst{26} = V; 3802 let Inst{25-24} = 0b00; 3803 let Inst{23-22} = opc; 3804 let Inst{21} = 1; 3805 let Inst{20-16} = Rm; 3806 let Inst{15} = extend{1}; // sign extend Rm? 3807 let Inst{14} = 1; 3808 let Inst{12} = extend{0}; // do shift? 3809 let Inst{11-10} = 0b10; 3810 let Inst{9-5} = Rn; 3811 let Inst{4-0} = Rt; 3812} 3813 3814multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3815 string asm, ValueType Ty, SDPatternOperator loadop> { 3816 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3817 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3818 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3819 [(set (Ty regtype:$Rt), 3820 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3821 ro_Wextend128:$extend)))]>, 3822 Sched<[WriteLDIdx, ReadAdrBase]> { 3823 let Inst{13} = 0b0; 3824 } 3825 3826 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3827 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3828 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3829 [(set (Ty regtype:$Rt), 3830 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3831 ro_Xextend128:$extend)))]>, 3832 Sched<[WriteLDIdx, ReadAdrBase]> { 3833 let Inst{13} = 0b1; 3834 } 3835 3836 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3837} 3838 3839multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3840 string asm> { 3841 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3842 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 3843 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3844 []>, 3845 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3846 let Inst{13} = 0b0; 3847 } 3848 3849 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3850 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 3851 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3852 []>, 3853 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3854 let Inst{13} = 0b1; 3855 } 3856 3857 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3858} 3859 3860let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3861class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3862 string asm, list<dag> pat> 3863 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3864 Sched<[WriteLD]> { 3865 bits<5> Rt; 3866 bits<5> Rn; 3867 bits<5> Rm; 3868 bits<2> extend; 3869 let Inst{31-30} = sz; 3870 let Inst{29-27} = 0b111; 3871 let Inst{26} = V; 3872 let Inst{25-24} = 0b00; 3873 let Inst{23-22} = opc; 3874 let Inst{21} = 1; 3875 let Inst{20-16} = Rm; 3876 let Inst{15} = extend{1}; // sign extend Rm? 3877 let Inst{14} = 1; 3878 let Inst{12} = extend{0}; // do shift? 3879 let Inst{11-10} = 0b10; 3880 let Inst{9-5} = Rn; 3881 let Inst{4-0} = Rt; 3882} 3883 3884multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3885 def roW : BasePrefetchRO<sz, V, opc, (outs), 3886 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3887 asm, [(AArch64Prefetch imm:$Rt, 3888 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3889 ro_Wextend64:$extend))]> { 3890 let Inst{13} = 0b0; 3891 } 3892 3893 def roX : BasePrefetchRO<sz, V, opc, (outs), 3894 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3895 asm, [(AArch64Prefetch imm:$Rt, 3896 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3897 ro_Xextend64:$extend))]> { 3898 let Inst{13} = 0b1; 3899 } 3900 3901 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3902 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3903 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3904} 3905 3906//--- 3907// Load/store unscaled immediate 3908//--- 3909 3910def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 3911def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 3912def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 3913def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 3914def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 3915 3916def gi_am_unscaled8 : 3917 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3918 GIComplexPatternEquiv<am_unscaled8>; 3919def gi_am_unscaled16 : 3920 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3921 GIComplexPatternEquiv<am_unscaled16>; 3922def gi_am_unscaled32 : 3923 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3924 GIComplexPatternEquiv<am_unscaled32>; 3925def gi_am_unscaled64 : 3926 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3927 GIComplexPatternEquiv<am_unscaled64>; 3928def gi_am_unscaled128 : 3929 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3930 GIComplexPatternEquiv<am_unscaled128>; 3931 3932 3933class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3934 string asm, list<dag> pattern> 3935 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3936 bits<5> Rt; 3937 bits<5> Rn; 3938 bits<9> offset; 3939 let Inst{31-30} = sz; 3940 let Inst{29-27} = 0b111; 3941 let Inst{26} = V; 3942 let Inst{25-24} = 0b00; 3943 let Inst{23-22} = opc; 3944 let Inst{21} = 0; 3945 let Inst{20-12} = offset; 3946 let Inst{11-10} = 0b00; 3947 let Inst{9-5} = Rn; 3948 let Inst{4-0} = Rt; 3949 3950 let DecoderMethod = "DecodeSignedLdStInstruction"; 3951} 3952 3953// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3954multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3955 DAGOperand regtype > { 3956 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3957 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3958 Sched<[WriteST]> { 3959 let Inst{29} = 0; 3960 let Inst{24} = 1; 3961 } 3962 def : InstAlias<asm # "\t$Rt, [$Rn]", 3963 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3964} 3965 3966multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3967 DAGOperand regtype > { 3968 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3969 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3970 asm, []>, 3971 Sched<[WriteST]> { 3972 let Inst{29} = 0; 3973 let Inst{24} = 1; 3974 } 3975 def : InstAlias<asm # "\t$Rt, [$Rn]", 3976 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3977} 3978 3979multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3980 string asm, list<dag> pattern> { 3981 let AddedComplexity = 1 in // try this before LoadUI 3982 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3983 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3984 Sched<[WriteLD]>; 3985 3986 def : InstAlias<asm # "\t$Rt, [$Rn]", 3987 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3988} 3989 3990multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3991 string asm, list<dag> pattern> { 3992 let AddedComplexity = 1 in // try this before StoreUI 3993 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3994 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3995 asm, pattern>, 3996 Sched<[WriteST]>; 3997 3998 def : InstAlias<asm # "\t$Rt, [$Rn]", 3999 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4000} 4001 4002multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4003 list<dag> pat> { 4004 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4005 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4006 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4007 asm, pat>, 4008 Sched<[WriteLD]>; 4009 4010 def : InstAlias<asm # "\t$Rt, [$Rn]", 4011 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4012} 4013 4014//--- 4015// Load/store unscaled immediate, unprivileged 4016//--- 4017 4018class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4019 dag oops, dag iops, string asm> 4020 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4021 bits<5> Rt; 4022 bits<5> Rn; 4023 bits<9> offset; 4024 let Inst{31-30} = sz; 4025 let Inst{29-27} = 0b111; 4026 let Inst{26} = V; 4027 let Inst{25-24} = 0b00; 4028 let Inst{23-22} = opc; 4029 let Inst{21} = 0; 4030 let Inst{20-12} = offset; 4031 let Inst{11-10} = 0b10; 4032 let Inst{9-5} = Rn; 4033 let Inst{4-0} = Rt; 4034 4035 let DecoderMethod = "DecodeSignedLdStInstruction"; 4036} 4037 4038multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4039 RegisterClass regtype, string asm> { 4040 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4041 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4042 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4043 Sched<[WriteLD]>; 4044 4045 def : InstAlias<asm # "\t$Rt, [$Rn]", 4046 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4047} 4048 4049multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4050 RegisterClass regtype, string asm> { 4051 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4052 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4053 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4054 asm>, 4055 Sched<[WriteST]>; 4056 4057 def : InstAlias<asm # "\t$Rt, [$Rn]", 4058 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4059} 4060 4061//--- 4062// Load/store pre-indexed 4063//--- 4064 4065class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4066 string asm, string cstr, list<dag> pat> 4067 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4068 bits<5> Rt; 4069 bits<5> Rn; 4070 bits<9> offset; 4071 let Inst{31-30} = sz; 4072 let Inst{29-27} = 0b111; 4073 let Inst{26} = V; 4074 let Inst{25-24} = 0; 4075 let Inst{23-22} = opc; 4076 let Inst{21} = 0; 4077 let Inst{20-12} = offset; 4078 let Inst{11-10} = 0b11; 4079 let Inst{9-5} = Rn; 4080 let Inst{4-0} = Rt; 4081 4082 let DecoderMethod = "DecodeSignedLdStInstruction"; 4083} 4084 4085let hasSideEffects = 0 in { 4086let mayStore = 0, mayLoad = 1 in 4087class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4088 string asm> 4089 : BaseLoadStorePreIdx<sz, V, opc, 4090 (outs GPR64sp:$wback, regtype:$Rt), 4091 (ins GPR64sp:$Rn, simm9:$offset), asm, 4092 "$Rn = $wback,@earlyclobber $wback", []>, 4093 Sched<[WriteAdr, WriteLD]>; 4094 4095let mayStore = 1, mayLoad = 0 in 4096class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4097 string asm, SDPatternOperator storeop, ValueType Ty> 4098 : BaseLoadStorePreIdx<sz, V, opc, 4099 (outs GPR64sp:$wback), 4100 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4101 asm, "$Rn = $wback,@earlyclobber $wback", 4102 [(set GPR64sp:$wback, 4103 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4104 Sched<[WriteAdr, WriteST]>; 4105} // hasSideEffects = 0 4106 4107//--- 4108// Load/store post-indexed 4109//--- 4110 4111class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4112 string asm, string cstr, list<dag> pat> 4113 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4114 bits<5> Rt; 4115 bits<5> Rn; 4116 bits<9> offset; 4117 let Inst{31-30} = sz; 4118 let Inst{29-27} = 0b111; 4119 let Inst{26} = V; 4120 let Inst{25-24} = 0b00; 4121 let Inst{23-22} = opc; 4122 let Inst{21} = 0b0; 4123 let Inst{20-12} = offset; 4124 let Inst{11-10} = 0b01; 4125 let Inst{9-5} = Rn; 4126 let Inst{4-0} = Rt; 4127 4128 let DecoderMethod = "DecodeSignedLdStInstruction"; 4129} 4130 4131let hasSideEffects = 0 in { 4132let mayStore = 0, mayLoad = 1 in 4133class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4134 string asm> 4135 : BaseLoadStorePostIdx<sz, V, opc, 4136 (outs GPR64sp:$wback, regtype:$Rt), 4137 (ins GPR64sp:$Rn, simm9:$offset), 4138 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4139 Sched<[WriteAdr, WriteLD]>; 4140 4141let mayStore = 1, mayLoad = 0 in 4142class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4143 string asm, SDPatternOperator storeop, ValueType Ty> 4144 : BaseLoadStorePostIdx<sz, V, opc, 4145 (outs GPR64sp:$wback), 4146 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4147 asm, "$Rn = $wback,@earlyclobber $wback", 4148 [(set GPR64sp:$wback, 4149 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4150 Sched<[WriteAdr, WriteST]>; 4151} // hasSideEffects = 0 4152 4153 4154//--- 4155// Load/store pair 4156//--- 4157 4158// (indexed, offset) 4159 4160class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4161 string asm> 4162 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4163 bits<5> Rt; 4164 bits<5> Rt2; 4165 bits<5> Rn; 4166 bits<7> offset; 4167 let Inst{31-30} = opc; 4168 let Inst{29-27} = 0b101; 4169 let Inst{26} = V; 4170 let Inst{25-23} = 0b010; 4171 let Inst{22} = L; 4172 let Inst{21-15} = offset; 4173 let Inst{14-10} = Rt2; 4174 let Inst{9-5} = Rn; 4175 let Inst{4-0} = Rt; 4176 4177 let DecoderMethod = "DecodePairLdStInstruction"; 4178} 4179 4180multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4181 Operand indextype, string asm> { 4182 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4183 def i : BaseLoadStorePairOffset<opc, V, 1, 4184 (outs regtype:$Rt, regtype:$Rt2), 4185 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4186 Sched<[WriteLD, WriteLDHi]>; 4187 4188 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4189 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4190 GPR64sp:$Rn, 0)>; 4191} 4192 4193 4194multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4195 Operand indextype, string asm> { 4196 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4197 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4198 (ins regtype:$Rt, regtype:$Rt2, 4199 GPR64sp:$Rn, indextype:$offset), 4200 asm>, 4201 Sched<[WriteSTP]>; 4202 4203 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4204 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4205 GPR64sp:$Rn, 0)>; 4206} 4207 4208// (pre-indexed) 4209class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4210 string asm> 4211 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4212 bits<5> Rt; 4213 bits<5> Rt2; 4214 bits<5> Rn; 4215 bits<7> offset; 4216 let Inst{31-30} = opc; 4217 let Inst{29-27} = 0b101; 4218 let Inst{26} = V; 4219 let Inst{25-23} = 0b011; 4220 let Inst{22} = L; 4221 let Inst{21-15} = offset; 4222 let Inst{14-10} = Rt2; 4223 let Inst{9-5} = Rn; 4224 let Inst{4-0} = Rt; 4225 4226 let DecoderMethod = "DecodePairLdStInstruction"; 4227} 4228 4229let hasSideEffects = 0 in { 4230let mayStore = 0, mayLoad = 1 in 4231class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4232 Operand indextype, string asm> 4233 : BaseLoadStorePairPreIdx<opc, V, 1, 4234 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4235 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4236 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4237 4238let mayStore = 1, mayLoad = 0 in 4239class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4240 Operand indextype, string asm> 4241 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4242 (ins regtype:$Rt, regtype:$Rt2, 4243 GPR64sp:$Rn, indextype:$offset), 4244 asm>, 4245 Sched<[WriteAdr, WriteSTP]>; 4246} // hasSideEffects = 0 4247 4248// (post-indexed) 4249 4250class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4251 string asm> 4252 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4253 bits<5> Rt; 4254 bits<5> Rt2; 4255 bits<5> Rn; 4256 bits<7> offset; 4257 let Inst{31-30} = opc; 4258 let Inst{29-27} = 0b101; 4259 let Inst{26} = V; 4260 let Inst{25-23} = 0b001; 4261 let Inst{22} = L; 4262 let Inst{21-15} = offset; 4263 let Inst{14-10} = Rt2; 4264 let Inst{9-5} = Rn; 4265 let Inst{4-0} = Rt; 4266 4267 let DecoderMethod = "DecodePairLdStInstruction"; 4268} 4269 4270let hasSideEffects = 0 in { 4271let mayStore = 0, mayLoad = 1 in 4272class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4273 Operand idxtype, string asm> 4274 : BaseLoadStorePairPostIdx<opc, V, 1, 4275 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4276 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4277 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4278 4279let mayStore = 1, mayLoad = 0 in 4280class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4281 Operand idxtype, string asm> 4282 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4283 (ins regtype:$Rt, regtype:$Rt2, 4284 GPR64sp:$Rn, idxtype:$offset), 4285 asm>, 4286 Sched<[WriteAdr, WriteSTP]>; 4287} // hasSideEffects = 0 4288 4289// (no-allocate) 4290 4291class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4292 string asm> 4293 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4294 bits<5> Rt; 4295 bits<5> Rt2; 4296 bits<5> Rn; 4297 bits<7> offset; 4298 let Inst{31-30} = opc; 4299 let Inst{29-27} = 0b101; 4300 let Inst{26} = V; 4301 let Inst{25-23} = 0b000; 4302 let Inst{22} = L; 4303 let Inst{21-15} = offset; 4304 let Inst{14-10} = Rt2; 4305 let Inst{9-5} = Rn; 4306 let Inst{4-0} = Rt; 4307 4308 let DecoderMethod = "DecodePairLdStInstruction"; 4309} 4310 4311multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4312 Operand indextype, string asm> { 4313 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4314 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4315 (outs regtype:$Rt, regtype:$Rt2), 4316 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4317 Sched<[WriteLD, WriteLDHi]>; 4318 4319 4320 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4321 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4322 GPR64sp:$Rn, 0)>; 4323} 4324 4325multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4326 Operand indextype, string asm> { 4327 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4328 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4329 (ins regtype:$Rt, regtype:$Rt2, 4330 GPR64sp:$Rn, indextype:$offset), 4331 asm>, 4332 Sched<[WriteSTP]>; 4333 4334 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4335 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4336 GPR64sp:$Rn, 0)>; 4337} 4338 4339//--- 4340// Load/store exclusive 4341//--- 4342 4343// True exclusive operations write to and/or read from the system's exclusive 4344// monitors, which as far as a compiler is concerned can be modelled as a 4345// random shared memory address. Hence LoadExclusive mayStore. 4346// 4347// Since these instructions have the undefined register bits set to 1 in 4348// their canonical form, we need a post encoder method to set those bits 4349// to 1 when encoding these instructions. We do this using the 4350// fixLoadStoreExclusive function. This function has template parameters: 4351// 4352// fixLoadStoreExclusive<int hasRs, int hasRt2> 4353// 4354// hasRs indicates that the instruction uses the Rs field, so we won't set 4355// it to 1 (and the same for Rt2). We don't need template parameters for 4356// the other register fields since Rt and Rn are always used. 4357// 4358let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4359class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4360 dag oops, dag iops, string asm, string operands> 4361 : I<oops, iops, asm, operands, "", []> { 4362 let Inst{31-30} = sz; 4363 let Inst{29-24} = 0b001000; 4364 let Inst{23} = o2; 4365 let Inst{22} = L; 4366 let Inst{21} = o1; 4367 let Inst{15} = o0; 4368 4369 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4370} 4371 4372// Neither Rs nor Rt2 operands. 4373class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4374 dag oops, dag iops, string asm, string operands> 4375 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4376 bits<5> Rt; 4377 bits<5> Rn; 4378 let Inst{20-16} = 0b11111; 4379 let Unpredictable{20-16} = 0b11111; 4380 let Inst{14-10} = 0b11111; 4381 let Unpredictable{14-10} = 0b11111; 4382 let Inst{9-5} = Rn; 4383 let Inst{4-0} = Rt; 4384 4385 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4386} 4387 4388// Simple load acquires don't set the exclusive monitor 4389let mayLoad = 1, mayStore = 0 in 4390class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4391 RegisterClass regtype, string asm> 4392 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4393 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4394 Sched<[WriteLD]>; 4395 4396class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4397 RegisterClass regtype, string asm> 4398 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4399 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4400 Sched<[WriteLD]>; 4401 4402class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4403 RegisterClass regtype, string asm> 4404 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4405 (outs regtype:$Rt, regtype:$Rt2), 4406 (ins GPR64sp0:$Rn), asm, 4407 "\t$Rt, $Rt2, [$Rn]">, 4408 Sched<[WriteLD, WriteLDHi]> { 4409 bits<5> Rt; 4410 bits<5> Rt2; 4411 bits<5> Rn; 4412 let Inst{14-10} = Rt2; 4413 let Inst{9-5} = Rn; 4414 let Inst{4-0} = Rt; 4415 4416 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4417} 4418 4419// Simple store release operations do not check the exclusive monitor. 4420let mayLoad = 0, mayStore = 1 in 4421class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4422 RegisterClass regtype, string asm> 4423 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4424 (ins regtype:$Rt, GPR64sp0:$Rn), 4425 asm, "\t$Rt, [$Rn]">, 4426 Sched<[WriteST]>; 4427 4428let mayLoad = 1, mayStore = 1 in 4429class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4430 RegisterClass regtype, string asm> 4431 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4432 (ins regtype:$Rt, GPR64sp0:$Rn), 4433 asm, "\t$Ws, $Rt, [$Rn]">, 4434 Sched<[WriteSTX]> { 4435 bits<5> Ws; 4436 bits<5> Rt; 4437 bits<5> Rn; 4438 let Inst{20-16} = Ws; 4439 let Inst{9-5} = Rn; 4440 let Inst{4-0} = Rt; 4441 4442 let Constraints = "@earlyclobber $Ws"; 4443 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4444} 4445 4446class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4447 RegisterClass regtype, string asm> 4448 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4449 (outs GPR32:$Ws), 4450 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4451 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4452 Sched<[WriteSTX]> { 4453 bits<5> Ws; 4454 bits<5> Rt; 4455 bits<5> Rt2; 4456 bits<5> Rn; 4457 let Inst{20-16} = Ws; 4458 let Inst{14-10} = Rt2; 4459 let Inst{9-5} = Rn; 4460 let Inst{4-0} = Rt; 4461 4462 let Constraints = "@earlyclobber $Ws"; 4463} 4464 4465// Armv8.5-A Memory Tagging Extension 4466class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4467 string asm_opnds, string cstr, dag oops, dag iops> 4468 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4469 Sched<[]> { 4470 bits<5> Rn; 4471 4472 let Inst{31-24} = 0b11011001; 4473 let Inst{23-22} = opc1; 4474 let Inst{21} = 1; 4475 // Inst{20-12} defined by subclass 4476 let Inst{11-10} = opc2; 4477 let Inst{9-5} = Rn; 4478 // Inst{4-0} defined by subclass 4479} 4480 4481class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4482 dag oops, dag iops> 4483 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4484 "", oops, iops> { 4485 bits<5> Rt; 4486 4487 let Inst{20-12} = 0b000000000; 4488 let Inst{4-0} = Rt; 4489 4490 let mayLoad = Load; 4491} 4492 4493class MemTagLoad<string asm_insn, string asm_opnds> 4494 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4495 (outs GPR64:$wback), 4496 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4497 bits<5> Rt; 4498 bits<9> offset; 4499 4500 let Inst{20-12} = offset; 4501 let Inst{4-0} = Rt; 4502 4503 let mayLoad = 1; 4504} 4505 4506class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4507 string asm_opnds, string cstr, dag oops, dag iops> 4508 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4509 bits<5> Rt; 4510 bits<9> offset; 4511 4512 let Inst{20-12} = offset; 4513 let Inst{4-0} = Rt; 4514 4515 let mayStore = 1; 4516} 4517 4518multiclass MemTagStore<bits<2> opc1, string insn> { 4519 def Offset : 4520 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4521 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4522 def PreIndex : 4523 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4524 "$Rn = $wback", 4525 (outs GPR64sp:$wback), 4526 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4527 def PostIndex : 4528 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4529 "$Rn = $wback", 4530 (outs GPR64sp:$wback), 4531 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4532 4533 def : InstAlias<insn # "\t$Rt, [$Rn]", 4534 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4535} 4536 4537//--- 4538// Exception generation 4539//--- 4540 4541let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4542class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4543 list<dag> pattern = []> 4544 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4545 Sched<[WriteSys]> { 4546 bits<16> imm; 4547 let Inst{31-24} = 0b11010100; 4548 let Inst{23-21} = op1; 4549 let Inst{20-5} = imm; 4550 let Inst{4-2} = 0b000; 4551 let Inst{1-0} = ll; 4552} 4553 4554//--- 4555// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4556//-- 4557let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4558class UDFType<bits<16> opc, string asm> 4559 : I<(outs), (ins uimm16:$imm), 4560 asm, "\t$imm", "", []>, 4561 Sched<[]> { 4562 bits<16> imm; 4563 let Inst{31-16} = opc; 4564 let Inst{15-0} = imm; 4565} 4566} 4567let Predicates = [HasFPARMv8] in { 4568 4569//--- 4570// Floating point to integer conversion 4571//--- 4572 4573let mayRaiseFPException = 1 in 4574class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4575 RegisterClass srcType, RegisterClass dstType, 4576 string asm, list<dag> pattern> 4577 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4578 asm, "\t$Rd, $Rn", "", pattern>, 4579 Sched<[WriteFCvt]> { 4580 bits<5> Rd; 4581 bits<5> Rn; 4582 let Inst{30-29} = 0b00; 4583 let Inst{28-24} = 0b11110; 4584 let Inst{23-22} = type; 4585 let Inst{21} = 1; 4586 let Inst{20-19} = rmode; 4587 let Inst{18-16} = opcode; 4588 let Inst{15-10} = 0; 4589 let Inst{9-5} = Rn; 4590 let Inst{4-0} = Rd; 4591} 4592 4593let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 4594class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4595 RegisterClass srcType, RegisterClass dstType, 4596 Operand immType, string asm, list<dag> pattern> 4597 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4598 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4599 Sched<[WriteFCvt]> { 4600 bits<5> Rd; 4601 bits<5> Rn; 4602 bits<6> scale; 4603 let Inst{30-29} = 0b00; 4604 let Inst{28-24} = 0b11110; 4605 let Inst{23-22} = type; 4606 let Inst{21} = 0; 4607 let Inst{20-19} = rmode; 4608 let Inst{18-16} = opcode; 4609 let Inst{15-10} = scale; 4610 let Inst{9-5} = Rn; 4611 let Inst{4-0} = Rd; 4612} 4613 4614multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4615 SDPatternOperator OpN> { 4616 // Unscaled half-precision to 32-bit 4617 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4618 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4619 let Inst{31} = 0; // 32-bit GPR flag 4620 let Predicates = [HasFullFP16]; 4621 } 4622 4623 // Unscaled half-precision to 64-bit 4624 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4625 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4626 let Inst{31} = 1; // 64-bit GPR flag 4627 let Predicates = [HasFullFP16]; 4628 } 4629 4630 // Unscaled single-precision to 32-bit 4631 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4632 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4633 let Inst{31} = 0; // 32-bit GPR flag 4634 } 4635 4636 // Unscaled single-precision to 64-bit 4637 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4638 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4639 let Inst{31} = 1; // 64-bit GPR flag 4640 } 4641 4642 // Unscaled double-precision to 32-bit 4643 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4644 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4645 let Inst{31} = 0; // 32-bit GPR flag 4646 } 4647 4648 // Unscaled double-precision to 64-bit 4649 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4650 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4651 let Inst{31} = 1; // 64-bit GPR flag 4652 } 4653} 4654 4655multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4656 SDPatternOperator OpN> { 4657 // Scaled half-precision to 32-bit 4658 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4659 fixedpoint_f16_i32, asm, 4660 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4661 fixedpoint_f16_i32:$scale)))]> { 4662 let Inst{31} = 0; // 32-bit GPR flag 4663 let scale{5} = 1; 4664 let Predicates = [HasFullFP16]; 4665 } 4666 4667 // Scaled half-precision to 64-bit 4668 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4669 fixedpoint_f16_i64, asm, 4670 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4671 fixedpoint_f16_i64:$scale)))]> { 4672 let Inst{31} = 1; // 64-bit GPR flag 4673 let Predicates = [HasFullFP16]; 4674 } 4675 4676 // Scaled single-precision to 32-bit 4677 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4678 fixedpoint_f32_i32, asm, 4679 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4680 fixedpoint_f32_i32:$scale)))]> { 4681 let Inst{31} = 0; // 32-bit GPR flag 4682 let scale{5} = 1; 4683 } 4684 4685 // Scaled single-precision to 64-bit 4686 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4687 fixedpoint_f32_i64, asm, 4688 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4689 fixedpoint_f32_i64:$scale)))]> { 4690 let Inst{31} = 1; // 64-bit GPR flag 4691 } 4692 4693 // Scaled double-precision to 32-bit 4694 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4695 fixedpoint_f64_i32, asm, 4696 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4697 fixedpoint_f64_i32:$scale)))]> { 4698 let Inst{31} = 0; // 32-bit GPR flag 4699 let scale{5} = 1; 4700 } 4701 4702 // Scaled double-precision to 64-bit 4703 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4704 fixedpoint_f64_i64, asm, 4705 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4706 fixedpoint_f64_i64:$scale)))]> { 4707 let Inst{31} = 1; // 64-bit GPR flag 4708 } 4709} 4710 4711//--- 4712// Integer to floating point conversion 4713//--- 4714 4715let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 4716class BaseIntegerToFP<bit isUnsigned, 4717 RegisterClass srcType, RegisterClass dstType, 4718 Operand immType, string asm, list<dag> pattern> 4719 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4720 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4721 Sched<[WriteFCvt]> { 4722 bits<5> Rd; 4723 bits<5> Rn; 4724 bits<6> scale; 4725 let Inst{30-24} = 0b0011110; 4726 let Inst{21-17} = 0b00001; 4727 let Inst{16} = isUnsigned; 4728 let Inst{15-10} = scale; 4729 let Inst{9-5} = Rn; 4730 let Inst{4-0} = Rd; 4731} 4732 4733let mayRaiseFPException = 1 in 4734class BaseIntegerToFPUnscaled<bit isUnsigned, 4735 RegisterClass srcType, RegisterClass dstType, 4736 ValueType dvt, string asm, SDPatternOperator node> 4737 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4738 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4739 Sched<[WriteFCvt]> { 4740 bits<5> Rd; 4741 bits<5> Rn; 4742 bits<6> scale; 4743 let Inst{30-24} = 0b0011110; 4744 let Inst{21-17} = 0b10001; 4745 let Inst{16} = isUnsigned; 4746 let Inst{15-10} = 0b000000; 4747 let Inst{9-5} = Rn; 4748 let Inst{4-0} = Rd; 4749} 4750 4751multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4752 // Unscaled 4753 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4754 let Inst{31} = 0; // 32-bit GPR flag 4755 let Inst{23-22} = 0b11; // 16-bit FPR flag 4756 let Predicates = [HasFullFP16]; 4757 } 4758 4759 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4760 let Inst{31} = 0; // 32-bit GPR flag 4761 let Inst{23-22} = 0b00; // 32-bit FPR flag 4762 } 4763 4764 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4765 let Inst{31} = 0; // 32-bit GPR flag 4766 let Inst{23-22} = 0b01; // 64-bit FPR flag 4767 } 4768 4769 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4770 let Inst{31} = 1; // 64-bit GPR flag 4771 let Inst{23-22} = 0b11; // 16-bit FPR flag 4772 let Predicates = [HasFullFP16]; 4773 } 4774 4775 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4776 let Inst{31} = 1; // 64-bit GPR flag 4777 let Inst{23-22} = 0b00; // 32-bit FPR flag 4778 } 4779 4780 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4781 let Inst{31} = 1; // 64-bit GPR flag 4782 let Inst{23-22} = 0b01; // 64-bit FPR flag 4783 } 4784 4785 // Scaled 4786 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4787 [(set (f16 FPR16:$Rd), 4788 (fdiv (node GPR32:$Rn), 4789 fixedpoint_f16_i32:$scale))]> { 4790 let Inst{31} = 0; // 32-bit GPR flag 4791 let Inst{23-22} = 0b11; // 16-bit FPR flag 4792 let scale{5} = 1; 4793 let Predicates = [HasFullFP16]; 4794 } 4795 4796 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4797 [(set FPR32:$Rd, 4798 (fdiv (node GPR32:$Rn), 4799 fixedpoint_f32_i32:$scale))]> { 4800 let Inst{31} = 0; // 32-bit GPR flag 4801 let Inst{23-22} = 0b00; // 32-bit FPR flag 4802 let scale{5} = 1; 4803 } 4804 4805 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4806 [(set FPR64:$Rd, 4807 (fdiv (node GPR32:$Rn), 4808 fixedpoint_f64_i32:$scale))]> { 4809 let Inst{31} = 0; // 32-bit GPR flag 4810 let Inst{23-22} = 0b01; // 64-bit FPR flag 4811 let scale{5} = 1; 4812 } 4813 4814 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4815 [(set (f16 FPR16:$Rd), 4816 (fdiv (node GPR64:$Rn), 4817 fixedpoint_f16_i64:$scale))]> { 4818 let Inst{31} = 1; // 64-bit GPR flag 4819 let Inst{23-22} = 0b11; // 16-bit FPR flag 4820 let Predicates = [HasFullFP16]; 4821 } 4822 4823 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4824 [(set FPR32:$Rd, 4825 (fdiv (node GPR64:$Rn), 4826 fixedpoint_f32_i64:$scale))]> { 4827 let Inst{31} = 1; // 64-bit GPR flag 4828 let Inst{23-22} = 0b00; // 32-bit FPR flag 4829 } 4830 4831 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4832 [(set FPR64:$Rd, 4833 (fdiv (node GPR64:$Rn), 4834 fixedpoint_f64_i64:$scale))]> { 4835 let Inst{31} = 1; // 64-bit GPR flag 4836 let Inst{23-22} = 0b01; // 64-bit FPR flag 4837 } 4838} 4839 4840//--- 4841// Unscaled integer <-> floating point conversion (i.e. FMOV) 4842//--- 4843 4844let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4845class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4846 RegisterClass srcType, RegisterClass dstType, 4847 string asm> 4848 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4849 // We use COPY_TO_REGCLASS for these bitconvert operations. 4850 // copyPhysReg() expands the resultant COPY instructions after 4851 // regalloc is done. This gives greater freedom for the allocator 4852 // and related passes (coalescing, copy propagation, et. al.) to 4853 // be more effective. 4854 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4855 Sched<[WriteFCopy]> { 4856 bits<5> Rd; 4857 bits<5> Rn; 4858 let Inst{30-24} = 0b0011110; 4859 let Inst{21} = 1; 4860 let Inst{20-19} = rmode; 4861 let Inst{18-16} = opcode; 4862 let Inst{15-10} = 0b000000; 4863 let Inst{9-5} = Rn; 4864 let Inst{4-0} = Rd; 4865} 4866 4867let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4868class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4869 RegisterClass srcType, RegisterOperand dstType, string asm, 4870 string kind> 4871 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4872 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4873 Sched<[WriteFCopy]> { 4874 bits<5> Rd; 4875 bits<5> Rn; 4876 let Inst{30-23} = 0b00111101; 4877 let Inst{21} = 1; 4878 let Inst{20-19} = rmode; 4879 let Inst{18-16} = opcode; 4880 let Inst{15-10} = 0b000000; 4881 let Inst{9-5} = Rn; 4882 let Inst{4-0} = Rd; 4883 4884 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4885} 4886 4887let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4888class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4889 RegisterOperand srcType, RegisterClass dstType, string asm, 4890 string kind> 4891 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4892 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4893 Sched<[WriteFCopy]> { 4894 bits<5> Rd; 4895 bits<5> Rn; 4896 let Inst{30-23} = 0b00111101; 4897 let Inst{21} = 1; 4898 let Inst{20-19} = rmode; 4899 let Inst{18-16} = opcode; 4900 let Inst{15-10} = 0b000000; 4901 let Inst{9-5} = Rn; 4902 let Inst{4-0} = Rd; 4903 4904 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4905} 4906 4907 4908multiclass UnscaledConversion<string asm> { 4909 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4910 let Inst{31} = 0; // 32-bit GPR flag 4911 let Inst{23-22} = 0b11; // 16-bit FPR flag 4912 let Predicates = [HasFullFP16]; 4913 } 4914 4915 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4916 let Inst{31} = 1; // 64-bit GPR flag 4917 let Inst{23-22} = 0b11; // 16-bit FPR flag 4918 let Predicates = [HasFullFP16]; 4919 } 4920 4921 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4922 let Inst{31} = 0; // 32-bit GPR flag 4923 let Inst{23-22} = 0b00; // 32-bit FPR flag 4924 } 4925 4926 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4927 let Inst{31} = 1; // 64-bit GPR flag 4928 let Inst{23-22} = 0b01; // 64-bit FPR flag 4929 } 4930 4931 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4932 let Inst{31} = 0; // 32-bit GPR flag 4933 let Inst{23-22} = 0b11; // 16-bit FPR flag 4934 let Predicates = [HasFullFP16]; 4935 } 4936 4937 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4938 let Inst{31} = 1; // 64-bit GPR flag 4939 let Inst{23-22} = 0b11; // 16-bit FPR flag 4940 let Predicates = [HasFullFP16]; 4941 } 4942 4943 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4944 let Inst{31} = 0; // 32-bit GPR flag 4945 let Inst{23-22} = 0b00; // 32-bit FPR flag 4946 } 4947 4948 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4949 let Inst{31} = 1; // 64-bit GPR flag 4950 let Inst{23-22} = 0b01; // 64-bit FPR flag 4951 } 4952 4953 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4954 asm, ".d"> { 4955 let Inst{31} = 1; 4956 let Inst{22} = 0; 4957 } 4958 4959 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4960 asm, ".d"> { 4961 let Inst{31} = 1; 4962 let Inst{22} = 0; 4963 } 4964} 4965 4966//--- 4967// Floating point conversion 4968//--- 4969 4970let mayRaiseFPException = 1 in 4971class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4972 RegisterClass srcType, string asm, list<dag> pattern> 4973 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4974 Sched<[WriteFCvt]> { 4975 bits<5> Rd; 4976 bits<5> Rn; 4977 let Inst{31-24} = 0b00011110; 4978 let Inst{23-22} = type; 4979 let Inst{21-17} = 0b10001; 4980 let Inst{16-15} = opcode; 4981 let Inst{14-10} = 0b10000; 4982 let Inst{9-5} = Rn; 4983 let Inst{4-0} = Rd; 4984} 4985 4986multiclass FPConversion<string asm> { 4987 // Double-precision to Half-precision 4988 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4989 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4990 4991 // Double-precision to Single-precision 4992 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4993 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4994 4995 // Half-precision to Double-precision 4996 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4997 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 4998 4999 // Half-precision to Single-precision 5000 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5001 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5002 5003 // Single-precision to Double-precision 5004 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5005 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5006 5007 // Single-precision to Half-precision 5008 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5009 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5010} 5011 5012//--- 5013// Single operand floating point data processing 5014//--- 5015 5016let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5017class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5018 ValueType vt, string asm, SDPatternOperator node> 5019 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5020 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5021 Sched<[WriteF]> { 5022 bits<5> Rd; 5023 bits<5> Rn; 5024 let Inst{31-24} = 0b00011110; 5025 let Inst{21} = 0b1; 5026 let Inst{20-15} = opcode; 5027 let Inst{14-10} = 0b10000; 5028 let Inst{9-5} = Rn; 5029 let Inst{4-0} = Rd; 5030} 5031 5032multiclass SingleOperandFPData<bits<4> opcode, string asm, 5033 SDPatternOperator node = null_frag, 5034 int fpexceptions = 1> { 5035 let mayRaiseFPException = fpexceptions in { 5036 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5037 let Inst{23-22} = 0b11; // 16-bit size flag 5038 let Predicates = [HasFullFP16]; 5039 } 5040 5041 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5042 let Inst{23-22} = 0b00; // 32-bit size flag 5043 } 5044 5045 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5046 let Inst{23-22} = 0b01; // 64-bit size flag 5047 } 5048 } 5049} 5050 5051multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5052 SDPatternOperator node = null_frag> 5053 : SingleOperandFPData<opcode, asm, node, 0>; 5054 5055let mayRaiseFPException = 1 in 5056multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5057 SDPatternOperator node = null_frag>{ 5058 5059 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5060 let Inst{23-22} = 0b00; // 32-bit registers 5061 } 5062 5063 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5064 let Inst{23-22} = 0b01; // 64-bit registers 5065 } 5066} 5067 5068// FRInt[32|64][Z|N] instructions 5069multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5070 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5071 5072//--- 5073// Two operand floating point data processing 5074//--- 5075 5076let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5077class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5078 string asm, list<dag> pat> 5079 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5080 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5081 Sched<[WriteF]> { 5082 bits<5> Rd; 5083 bits<5> Rn; 5084 bits<5> Rm; 5085 let Inst{31-24} = 0b00011110; 5086 let Inst{21} = 1; 5087 let Inst{20-16} = Rm; 5088 let Inst{15-12} = opcode; 5089 let Inst{11-10} = 0b10; 5090 let Inst{9-5} = Rn; 5091 let Inst{4-0} = Rd; 5092} 5093 5094multiclass TwoOperandFPData<bits<4> opcode, string asm, 5095 SDPatternOperator node = null_frag> { 5096 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5097 [(set (f16 FPR16:$Rd), 5098 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5099 let Inst{23-22} = 0b11; // 16-bit size flag 5100 let Predicates = [HasFullFP16]; 5101 } 5102 5103 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5104 [(set (f32 FPR32:$Rd), 5105 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5106 let Inst{23-22} = 0b00; // 32-bit size flag 5107 } 5108 5109 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5110 [(set (f64 FPR64:$Rd), 5111 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5112 let Inst{23-22} = 0b01; // 64-bit size flag 5113 } 5114} 5115 5116multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5117 SDPatternOperator node> { 5118 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5119 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5120 let Inst{23-22} = 0b11; // 16-bit size flag 5121 let Predicates = [HasFullFP16]; 5122 } 5123 5124 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5125 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5126 let Inst{23-22} = 0b00; // 32-bit size flag 5127 } 5128 5129 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5130 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5131 let Inst{23-22} = 0b01; // 64-bit size flag 5132 } 5133} 5134 5135 5136//--- 5137// Three operand floating point data processing 5138//--- 5139 5140let mayRaiseFPException = 1 in 5141class BaseThreeOperandFPData<bit isNegated, bit isSub, 5142 RegisterClass regtype, string asm, list<dag> pat> 5143 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5144 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5145 Sched<[WriteFMul]> { 5146 bits<5> Rd; 5147 bits<5> Rn; 5148 bits<5> Rm; 5149 bits<5> Ra; 5150 let Inst{31-24} = 0b00011111; 5151 let Inst{21} = isNegated; 5152 let Inst{20-16} = Rm; 5153 let Inst{15} = isSub; 5154 let Inst{14-10} = Ra; 5155 let Inst{9-5} = Rn; 5156 let Inst{4-0} = Rd; 5157} 5158 5159multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5160 SDPatternOperator node> { 5161 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5162 [(set (f16 FPR16:$Rd), 5163 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5164 let Inst{23-22} = 0b11; // 16-bit size flag 5165 let Predicates = [HasFullFP16]; 5166 } 5167 5168 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5169 [(set FPR32:$Rd, 5170 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5171 let Inst{23-22} = 0b00; // 32-bit size flag 5172 } 5173 5174 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5175 [(set FPR64:$Rd, 5176 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5177 let Inst{23-22} = 0b01; // 64-bit size flag 5178 } 5179} 5180 5181//--- 5182// Floating point data comparisons 5183//--- 5184 5185let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5186class BaseOneOperandFPComparison<bit signalAllNans, 5187 RegisterClass regtype, string asm, 5188 list<dag> pat> 5189 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5190 Sched<[WriteFCmp]> { 5191 bits<5> Rn; 5192 let Inst{31-24} = 0b00011110; 5193 let Inst{21} = 1; 5194 5195 let Inst{15-10} = 0b001000; 5196 let Inst{9-5} = Rn; 5197 let Inst{4} = signalAllNans; 5198 let Inst{3-0} = 0b1000; 5199 5200 // Rm should be 0b00000 canonically, but we need to accept any value. 5201 let PostEncoderMethod = "fixOneOperandFPComparison"; 5202} 5203 5204let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5205class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5206 string asm, list<dag> pat> 5207 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5208 Sched<[WriteFCmp]> { 5209 bits<5> Rm; 5210 bits<5> Rn; 5211 let Inst{31-24} = 0b00011110; 5212 let Inst{21} = 1; 5213 let Inst{20-16} = Rm; 5214 let Inst{15-10} = 0b001000; 5215 let Inst{9-5} = Rn; 5216 let Inst{4} = signalAllNans; 5217 let Inst{3-0} = 0b0000; 5218} 5219 5220multiclass FPComparison<bit signalAllNans, string asm, 5221 SDPatternOperator OpNode = null_frag> { 5222 let Defs = [NZCV] in { 5223 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5224 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5225 let Inst{23-22} = 0b11; 5226 let Predicates = [HasFullFP16]; 5227 } 5228 5229 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5230 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5231 let Inst{23-22} = 0b11; 5232 let Predicates = [HasFullFP16]; 5233 } 5234 5235 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5236 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5237 let Inst{23-22} = 0b00; 5238 } 5239 5240 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5241 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5242 let Inst{23-22} = 0b00; 5243 } 5244 5245 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5246 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5247 let Inst{23-22} = 0b01; 5248 } 5249 5250 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5251 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5252 let Inst{23-22} = 0b01; 5253 } 5254 } // Defs = [NZCV] 5255} 5256 5257//--- 5258// Floating point conditional comparisons 5259//--- 5260 5261let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5262class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5263 string mnemonic, list<dag> pat> 5264 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5265 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5266 Sched<[WriteFCmp]> { 5267 let Uses = [NZCV]; 5268 let Defs = [NZCV]; 5269 5270 bits<5> Rn; 5271 bits<5> Rm; 5272 bits<4> nzcv; 5273 bits<4> cond; 5274 5275 let Inst{31-24} = 0b00011110; 5276 let Inst{21} = 1; 5277 let Inst{20-16} = Rm; 5278 let Inst{15-12} = cond; 5279 let Inst{11-10} = 0b01; 5280 let Inst{9-5} = Rn; 5281 let Inst{4} = signalAllNans; 5282 let Inst{3-0} = nzcv; 5283} 5284 5285multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5286 SDPatternOperator OpNode = null_frag> { 5287 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5288 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5289 (i32 imm:$cond), NZCV))]> { 5290 let Inst{23-22} = 0b11; 5291 let Predicates = [HasFullFP16]; 5292 } 5293 5294 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5295 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5296 (i32 imm:$cond), NZCV))]> { 5297 let Inst{23-22} = 0b00; 5298 } 5299 5300 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5301 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5302 (i32 imm:$cond), NZCV))]> { 5303 let Inst{23-22} = 0b01; 5304 } 5305} 5306 5307//--- 5308// Floating point conditional select 5309//--- 5310 5311class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5312 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5313 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5314 [(set regtype:$Rd, 5315 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5316 (i32 imm:$cond), NZCV))]>, 5317 Sched<[WriteF]> { 5318 bits<5> Rd; 5319 bits<5> Rn; 5320 bits<5> Rm; 5321 bits<4> cond; 5322 5323 let Inst{31-24} = 0b00011110; 5324 let Inst{21} = 1; 5325 let Inst{20-16} = Rm; 5326 let Inst{15-12} = cond; 5327 let Inst{11-10} = 0b11; 5328 let Inst{9-5} = Rn; 5329 let Inst{4-0} = Rd; 5330} 5331 5332multiclass FPCondSelect<string asm> { 5333 let Uses = [NZCV] in { 5334 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5335 let Inst{23-22} = 0b11; 5336 let Predicates = [HasFullFP16]; 5337 } 5338 5339 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5340 let Inst{23-22} = 0b00; 5341 } 5342 5343 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5344 let Inst{23-22} = 0b01; 5345 } 5346 } // Uses = [NZCV] 5347} 5348 5349//--- 5350// Floating move immediate 5351//--- 5352 5353class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5354 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5355 [(set regtype:$Rd, fpimmtype:$imm)]>, 5356 Sched<[WriteFImm]> { 5357 bits<5> Rd; 5358 bits<8> imm; 5359 let Inst{31-24} = 0b00011110; 5360 let Inst{21} = 1; 5361 let Inst{20-13} = imm; 5362 let Inst{12-5} = 0b10000000; 5363 let Inst{4-0} = Rd; 5364} 5365 5366multiclass FPMoveImmediate<string asm> { 5367 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5368 let Inst{23-22} = 0b11; 5369 let Predicates = [HasFullFP16]; 5370 } 5371 5372 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5373 let Inst{23-22} = 0b00; 5374 } 5375 5376 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5377 let Inst{23-22} = 0b01; 5378 } 5379} 5380} // end of 'let Predicates = [HasFPARMv8]' 5381 5382//---------------------------------------------------------------------------- 5383// AdvSIMD 5384//---------------------------------------------------------------------------- 5385 5386let Predicates = [HasNEON] in { 5387 5388//---------------------------------------------------------------------------- 5389// AdvSIMD three register vector instructions 5390//---------------------------------------------------------------------------- 5391 5392let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5393class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5394 RegisterOperand regtype, string asm, string kind, 5395 list<dag> pattern> 5396 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5397 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5398 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5399 Sched<[!if(Q, WriteVq, WriteVd)]> { 5400 bits<5> Rd; 5401 bits<5> Rn; 5402 bits<5> Rm; 5403 let Inst{31} = 0; 5404 let Inst{30} = Q; 5405 let Inst{29} = U; 5406 let Inst{28-24} = 0b01110; 5407 let Inst{23-21} = size; 5408 let Inst{20-16} = Rm; 5409 let Inst{15-11} = opcode; 5410 let Inst{10} = 1; 5411 let Inst{9-5} = Rn; 5412 let Inst{4-0} = Rd; 5413} 5414 5415let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5416class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5417 RegisterOperand regtype, string asm, string kind, 5418 list<dag> pattern> 5419 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5420 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5421 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5422 Sched<[!if(Q, WriteVq, WriteVd)]> { 5423 bits<5> Rd; 5424 bits<5> Rn; 5425 bits<5> Rm; 5426 let Inst{31} = 0; 5427 let Inst{30} = Q; 5428 let Inst{29} = U; 5429 let Inst{28-24} = 0b01110; 5430 let Inst{23-21} = size; 5431 let Inst{20-16} = Rm; 5432 let Inst{15-11} = opcode; 5433 let Inst{10} = 1; 5434 let Inst{9-5} = Rn; 5435 let Inst{4-0} = Rd; 5436} 5437 5438let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5439class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5440 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5441 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5442 5443multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5444 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5445 [(set (v8i8 V64:$dst), 5446 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5447 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5448 [(set (v16i8 V128:$dst), 5449 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5450 (v16i8 V128:$Rm)))]>; 5451 5452 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5453 (v4i16 V64:$RHS))), 5454 (!cast<Instruction>(NAME#"v8i8") 5455 V64:$LHS, V64:$MHS, V64:$RHS)>; 5456 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5457 (v2i32 V64:$RHS))), 5458 (!cast<Instruction>(NAME#"v8i8") 5459 V64:$LHS, V64:$MHS, V64:$RHS)>; 5460 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5461 (v1i64 V64:$RHS))), 5462 (!cast<Instruction>(NAME#"v8i8") 5463 V64:$LHS, V64:$MHS, V64:$RHS)>; 5464 5465 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5466 (v8i16 V128:$RHS))), 5467 (!cast<Instruction>(NAME#"v16i8") 5468 V128:$LHS, V128:$MHS, V128:$RHS)>; 5469 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5470 (v4i32 V128:$RHS))), 5471 (!cast<Instruction>(NAME#"v16i8") 5472 V128:$LHS, V128:$MHS, V128:$RHS)>; 5473 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5474 (v2i64 V128:$RHS))), 5475 (!cast<Instruction>(NAME#"v16i8") 5476 V128:$LHS, V128:$MHS, V128:$RHS)>; 5477} 5478 5479// All operand sizes distinguished in the encoding. 5480multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5481 SDPatternOperator OpNode> { 5482 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5483 asm, ".8b", 5484 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5485 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5486 asm, ".16b", 5487 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5488 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5489 asm, ".4h", 5490 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5491 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5492 asm, ".8h", 5493 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5494 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5495 asm, ".2s", 5496 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5497 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5498 asm, ".4s", 5499 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5500 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5501 asm, ".2d", 5502 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5503} 5504 5505multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5506 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5507 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5508 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5509 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5510 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5511 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5512 5513 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5514 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5515 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5516 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5517 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5518 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5519 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5520 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5521} 5522 5523// As above, but D sized elements unsupported. 5524multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5525 SDPatternOperator OpNode> { 5526 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5527 asm, ".8b", 5528 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5529 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5530 asm, ".16b", 5531 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5532 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5533 asm, ".4h", 5534 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5535 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5536 asm, ".8h", 5537 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5538 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5539 asm, ".2s", 5540 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5541 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5542 asm, ".4s", 5543 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5544} 5545 5546multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5547 SDPatternOperator OpNode> { 5548 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5549 asm, ".8b", 5550 [(set (v8i8 V64:$dst), 5551 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5552 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5553 asm, ".16b", 5554 [(set (v16i8 V128:$dst), 5555 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5556 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5557 asm, ".4h", 5558 [(set (v4i16 V64:$dst), 5559 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5560 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5561 asm, ".8h", 5562 [(set (v8i16 V128:$dst), 5563 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5564 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5565 asm, ".2s", 5566 [(set (v2i32 V64:$dst), 5567 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5568 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5569 asm, ".4s", 5570 [(set (v4i32 V128:$dst), 5571 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5572} 5573 5574// As above, but only B sized elements supported. 5575multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5576 SDPatternOperator OpNode> { 5577 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5578 asm, ".8b", 5579 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5580 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5581 asm, ".16b", 5582 [(set (v16i8 V128:$Rd), 5583 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5584} 5585 5586// As above, but only floating point elements supported. 5587let mayRaiseFPException = 1 in 5588multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5589 string asm, SDPatternOperator OpNode> { 5590 let Predicates = [HasNEON, HasFullFP16] in { 5591 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5592 asm, ".4h", 5593 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5594 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5595 asm, ".8h", 5596 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5597 } // Predicates = [HasNEON, HasFullFP16] 5598 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5599 asm, ".2s", 5600 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5601 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5602 asm, ".4s", 5603 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5604 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5605 asm, ".2d", 5606 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5607} 5608 5609let mayRaiseFPException = 1 in 5610multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5611 string asm, 5612 SDPatternOperator OpNode> { 5613 let Predicates = [HasNEON, HasFullFP16] in { 5614 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5615 asm, ".4h", 5616 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5617 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5618 asm, ".8h", 5619 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5620 } // Predicates = [HasNEON, HasFullFP16] 5621 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5622 asm, ".2s", 5623 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5624 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5625 asm, ".4s", 5626 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5627 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5628 asm, ".2d", 5629 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5630} 5631 5632let mayRaiseFPException = 1 in 5633multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5634 string asm, SDPatternOperator OpNode> { 5635 let Predicates = [HasNEON, HasFullFP16] in { 5636 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5637 asm, ".4h", 5638 [(set (v4f16 V64:$dst), 5639 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5640 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5641 asm, ".8h", 5642 [(set (v8f16 V128:$dst), 5643 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5644 } // Predicates = [HasNEON, HasFullFP16] 5645 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5646 asm, ".2s", 5647 [(set (v2f32 V64:$dst), 5648 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5649 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5650 asm, ".4s", 5651 [(set (v4f32 V128:$dst), 5652 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5653 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5654 asm, ".2d", 5655 [(set (v2f64 V128:$dst), 5656 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5657} 5658 5659// As above, but D and B sized elements unsupported. 5660let mayRaiseFPException = 1 in 5661multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5662 SDPatternOperator OpNode> { 5663 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5664 asm, ".4h", 5665 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5666 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5667 asm, ".8h", 5668 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5669 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5670 asm, ".2s", 5671 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5672 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5673 asm, ".4s", 5674 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5675} 5676 5677// Logical three vector ops share opcode bits, and only use B sized elements. 5678multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5679 SDPatternOperator OpNode = null_frag> { 5680 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5681 asm, ".8b", 5682 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5683 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5684 asm, ".16b", 5685 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5686 5687 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5688 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5689 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5690 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5691 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5692 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5693 5694 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5695 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5696 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5697 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5698 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5699 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5700} 5701 5702multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5703 string asm, SDPatternOperator OpNode = null_frag> { 5704 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5705 asm, ".8b", 5706 [(set (v8i8 V64:$dst), 5707 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5708 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5709 asm, ".16b", 5710 [(set (v16i8 V128:$dst), 5711 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5712 (v16i8 V128:$Rm)))]>; 5713 5714 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5715 (v4i16 V64:$RHS))), 5716 (!cast<Instruction>(NAME#"v8i8") 5717 V64:$LHS, V64:$MHS, V64:$RHS)>; 5718 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5719 (v2i32 V64:$RHS))), 5720 (!cast<Instruction>(NAME#"v8i8") 5721 V64:$LHS, V64:$MHS, V64:$RHS)>; 5722 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5723 (v1i64 V64:$RHS))), 5724 (!cast<Instruction>(NAME#"v8i8") 5725 V64:$LHS, V64:$MHS, V64:$RHS)>; 5726 5727 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5728 (v8i16 V128:$RHS))), 5729 (!cast<Instruction>(NAME#"v16i8") 5730 V128:$LHS, V128:$MHS, V128:$RHS)>; 5731 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5732 (v4i32 V128:$RHS))), 5733 (!cast<Instruction>(NAME#"v16i8") 5734 V128:$LHS, V128:$MHS, V128:$RHS)>; 5735 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5736 (v2i64 V128:$RHS))), 5737 (!cast<Instruction>(NAME#"v16i8") 5738 V128:$LHS, V128:$MHS, V128:$RHS)>; 5739} 5740 5741// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5742// bytes from S-sized elements. 5743class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5744 string kind2, RegisterOperand RegType, 5745 ValueType AccumType, ValueType InputType, 5746 SDPatternOperator OpNode> : 5747 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5748 [(set (AccumType RegType:$dst), 5749 (OpNode (AccumType RegType:$Rd), 5750 (InputType RegType:$Rn), 5751 (InputType RegType:$Rm)))]> { 5752 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5753} 5754 5755multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5756 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5757 v2i32, v8i8, OpNode>; 5758 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5759 v4i32, v16i8, OpNode>; 5760} 5761 5762// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5763// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5764// 8H to 4S, when Q=1). 5765let mayRaiseFPException = 1 in 5766class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5767 string kind2, RegisterOperand RegType, 5768 ValueType AccumType, ValueType InputType, 5769 SDPatternOperator OpNode> : 5770 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5771 [(set (AccumType RegType:$dst), 5772 (OpNode (AccumType RegType:$Rd), 5773 (InputType RegType:$Rn), 5774 (InputType RegType:$Rm)))]> { 5775 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5776 let Inst{13} = b13; 5777} 5778 5779multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5780 SDPatternOperator OpNode> { 5781 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5782 v2f32, v4f16, OpNode>; 5783 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5784 v4f32, v8f16, OpNode>; 5785} 5786 5787 5788//---------------------------------------------------------------------------- 5789// AdvSIMD two register vector instructions. 5790//---------------------------------------------------------------------------- 5791 5792let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5793class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5794 bits<2> size2, RegisterOperand regtype, string asm, 5795 string dstkind, string srckind, list<dag> pattern> 5796 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5797 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5798 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5799 Sched<[!if(Q, WriteVq, WriteVd)]> { 5800 bits<5> Rd; 5801 bits<5> Rn; 5802 let Inst{31} = 0; 5803 let Inst{30} = Q; 5804 let Inst{29} = U; 5805 let Inst{28-24} = 0b01110; 5806 let Inst{23-22} = size; 5807 let Inst{21} = 0b1; 5808 let Inst{20-19} = size2; 5809 let Inst{18-17} = 0b00; 5810 let Inst{16-12} = opcode; 5811 let Inst{11-10} = 0b10; 5812 let Inst{9-5} = Rn; 5813 let Inst{4-0} = Rd; 5814} 5815 5816let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5817class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5818 bits<2> size2, RegisterOperand regtype, 5819 string asm, string dstkind, string srckind, 5820 list<dag> pattern> 5821 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5822 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5823 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5824 Sched<[!if(Q, WriteVq, WriteVd)]> { 5825 bits<5> Rd; 5826 bits<5> Rn; 5827 let Inst{31} = 0; 5828 let Inst{30} = Q; 5829 let Inst{29} = U; 5830 let Inst{28-24} = 0b01110; 5831 let Inst{23-22} = size; 5832 let Inst{21} = 0b1; 5833 let Inst{20-19} = size2; 5834 let Inst{18-17} = 0b00; 5835 let Inst{16-12} = opcode; 5836 let Inst{11-10} = 0b10; 5837 let Inst{9-5} = Rn; 5838 let Inst{4-0} = Rd; 5839} 5840 5841// Supports B, H, and S element sizes. 5842multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5843 SDPatternOperator OpNode> { 5844 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5845 asm, ".8b", ".8b", 5846 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5847 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5848 asm, ".16b", ".16b", 5849 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5850 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5851 asm, ".4h", ".4h", 5852 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5853 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5854 asm, ".8h", ".8h", 5855 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5856 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5857 asm, ".2s", ".2s", 5858 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5859 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5860 asm, ".4s", ".4s", 5861 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5862} 5863 5864class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5865 RegisterOperand regtype, string asm, string dstkind, 5866 string srckind, string amount> 5867 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5868 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5869 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5870 Sched<[WriteVq]> { 5871 bits<5> Rd; 5872 bits<5> Rn; 5873 let Inst{31} = 0; 5874 let Inst{30} = Q; 5875 let Inst{29-24} = 0b101110; 5876 let Inst{23-22} = size; 5877 let Inst{21-10} = 0b100001001110; 5878 let Inst{9-5} = Rn; 5879 let Inst{4-0} = Rd; 5880} 5881 5882multiclass SIMDVectorLShiftLongBySizeBHS { 5883 let hasSideEffects = 0 in { 5884 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5885 "shll", ".8h", ".8b", "8">; 5886 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5887 "shll2", ".8h", ".16b", "8">; 5888 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5889 "shll", ".4s", ".4h", "16">; 5890 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5891 "shll2", ".4s", ".8h", "16">; 5892 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5893 "shll", ".2d", ".2s", "32">; 5894 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5895 "shll2", ".2d", ".4s", "32">; 5896 } 5897} 5898 5899// Supports all element sizes. 5900multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5901 SDPatternOperator OpNode> { 5902 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5903 asm, ".4h", ".8b", 5904 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5905 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5906 asm, ".8h", ".16b", 5907 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5908 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5909 asm, ".2s", ".4h", 5910 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5911 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5912 asm, ".4s", ".8h", 5913 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5914 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5915 asm, ".1d", ".2s", 5916 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5917 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5918 asm, ".2d", ".4s", 5919 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5920} 5921 5922multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5923 SDPatternOperator OpNode> { 5924 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5925 asm, ".4h", ".8b", 5926 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5927 (v8i8 V64:$Rn)))]>; 5928 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5929 asm, ".8h", ".16b", 5930 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5931 (v16i8 V128:$Rn)))]>; 5932 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5933 asm, ".2s", ".4h", 5934 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5935 (v4i16 V64:$Rn)))]>; 5936 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5937 asm, ".4s", ".8h", 5938 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5939 (v8i16 V128:$Rn)))]>; 5940 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5941 asm, ".1d", ".2s", 5942 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5943 (v2i32 V64:$Rn)))]>; 5944 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5945 asm, ".2d", ".4s", 5946 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5947 (v4i32 V128:$Rn)))]>; 5948} 5949 5950// Supports all element sizes, except 1xD. 5951multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5952 SDPatternOperator OpNode> { 5953 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5954 asm, ".8b", ".8b", 5955 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5956 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5957 asm, ".16b", ".16b", 5958 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5959 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5960 asm, ".4h", ".4h", 5961 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5962 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5963 asm, ".8h", ".8h", 5964 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5965 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5966 asm, ".2s", ".2s", 5967 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5968 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5969 asm, ".4s", ".4s", 5970 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5971 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5972 asm, ".2d", ".2d", 5973 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5974} 5975 5976multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5977 SDPatternOperator OpNode = null_frag> { 5978 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5979 asm, ".8b", ".8b", 5980 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5981 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5982 asm, ".16b", ".16b", 5983 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5984 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5985 asm, ".4h", ".4h", 5986 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5987 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5988 asm, ".8h", ".8h", 5989 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5990 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5991 asm, ".2s", ".2s", 5992 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5993 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5994 asm, ".4s", ".4s", 5995 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5996 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5997 asm, ".2d", ".2d", 5998 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5999} 6000 6001 6002// Supports only B element sizes. 6003multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6004 SDPatternOperator OpNode> { 6005 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6006 asm, ".8b", ".8b", 6007 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6008 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6009 asm, ".16b", ".16b", 6010 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6011 6012} 6013 6014// Supports only B and H element sizes. 6015multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6016 SDPatternOperator OpNode> { 6017 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6018 asm, ".8b", ".8b", 6019 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6020 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6021 asm, ".16b", ".16b", 6022 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6023 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6024 asm, ".4h", ".4h", 6025 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6026 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6027 asm, ".8h", ".8h", 6028 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6029} 6030 6031// Supports H, S and D element sizes, uses high bit of the size field 6032// as an extra opcode bit. 6033multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6034 SDPatternOperator OpNode, 6035 int fpexceptions = 1> { 6036 let mayRaiseFPException = fpexceptions in { 6037 let Predicates = [HasNEON, HasFullFP16] in { 6038 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6039 asm, ".4h", ".4h", 6040 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6041 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6042 asm, ".8h", ".8h", 6043 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6044 } // Predicates = [HasNEON, HasFullFP16] 6045 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6046 asm, ".2s", ".2s", 6047 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6048 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6049 asm, ".4s", ".4s", 6050 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6051 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6052 asm, ".2d", ".2d", 6053 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6054 } 6055} 6056 6057multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6058 SDPatternOperator OpNode> 6059 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6060 6061// Supports only S and D element sizes 6062let mayRaiseFPException = 1 in 6063multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6064 SDPatternOperator OpNode = null_frag> { 6065 6066 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6067 asm, ".2s", ".2s", 6068 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6069 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6070 asm, ".4s", ".4s", 6071 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6072 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6073 asm, ".2d", ".2d", 6074 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6075} 6076 6077multiclass FRIntNNTVector<bit U, bit op, string asm, 6078 SDPatternOperator OpNode = null_frag> : 6079 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6080 6081// Supports only S element size. 6082multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6083 SDPatternOperator OpNode> { 6084 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6085 asm, ".2s", ".2s", 6086 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6087 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6088 asm, ".4s", ".4s", 6089 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6090} 6091 6092let mayRaiseFPException = 1 in 6093multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6094 SDPatternOperator OpNode> { 6095 let Predicates = [HasNEON, HasFullFP16] in { 6096 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6097 asm, ".4h", ".4h", 6098 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6099 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6100 asm, ".8h", ".8h", 6101 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6102 } // Predicates = [HasNEON, HasFullFP16] 6103 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6104 asm, ".2s", ".2s", 6105 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6106 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6107 asm, ".4s", ".4s", 6108 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6109 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6110 asm, ".2d", ".2d", 6111 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6112} 6113 6114let mayRaiseFPException = 1 in 6115multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6116 SDPatternOperator OpNode> { 6117 let Predicates = [HasNEON, HasFullFP16] in { 6118 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6119 asm, ".4h", ".4h", 6120 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6121 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6122 asm, ".8h", ".8h", 6123 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6124 } // Predicates = [HasNEON, HasFullFP16] 6125 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6126 asm, ".2s", ".2s", 6127 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6128 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6129 asm, ".4s", ".4s", 6130 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6131 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6132 asm, ".2d", ".2d", 6133 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6134} 6135 6136let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6137class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6138 RegisterOperand inreg, RegisterOperand outreg, 6139 string asm, string outkind, string inkind, 6140 list<dag> pattern> 6141 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6142 "{\t$Rd" # outkind # ", $Rn" # inkind # 6143 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6144 Sched<[WriteVq]> { 6145 bits<5> Rd; 6146 bits<5> Rn; 6147 let Inst{31} = 0; 6148 let Inst{30} = Q; 6149 let Inst{29} = U; 6150 let Inst{28-24} = 0b01110; 6151 let Inst{23-22} = size; 6152 let Inst{21-17} = 0b10000; 6153 let Inst{16-12} = opcode; 6154 let Inst{11-10} = 0b10; 6155 let Inst{9-5} = Rn; 6156 let Inst{4-0} = Rd; 6157} 6158 6159let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6160class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6161 RegisterOperand inreg, RegisterOperand outreg, 6162 string asm, string outkind, string inkind, 6163 list<dag> pattern> 6164 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6165 "{\t$Rd" # outkind # ", $Rn" # inkind # 6166 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6167 Sched<[WriteVq]> { 6168 bits<5> Rd; 6169 bits<5> Rn; 6170 let Inst{31} = 0; 6171 let Inst{30} = Q; 6172 let Inst{29} = U; 6173 let Inst{28-24} = 0b01110; 6174 let Inst{23-22} = size; 6175 let Inst{21-17} = 0b10000; 6176 let Inst{16-12} = opcode; 6177 let Inst{11-10} = 0b10; 6178 let Inst{9-5} = Rn; 6179 let Inst{4-0} = Rd; 6180} 6181 6182multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6183 SDPatternOperator OpNode> { 6184 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6185 asm, ".8b", ".8h", 6186 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6187 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6188 asm#"2", ".16b", ".8h", []>; 6189 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6190 asm, ".4h", ".4s", 6191 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6192 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6193 asm#"2", ".8h", ".4s", []>; 6194 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6195 asm, ".2s", ".2d", 6196 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6197 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6198 asm#"2", ".4s", ".2d", []>; 6199 6200 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6201 (!cast<Instruction>(NAME # "v16i8") 6202 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6203 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6204 (!cast<Instruction>(NAME # "v8i16") 6205 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6206 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6207 (!cast<Instruction>(NAME # "v4i32") 6208 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6209} 6210 6211class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6212 bits<5> opcode, RegisterOperand regtype, string asm, 6213 string kind, string zero, ValueType dty, 6214 ValueType sty, SDNode OpNode> 6215 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6216 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6217 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6218 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6219 Sched<[!if(Q, WriteVq, WriteVd)]> { 6220 bits<5> Rd; 6221 bits<5> Rn; 6222 let Inst{31} = 0; 6223 let Inst{30} = Q; 6224 let Inst{29} = U; 6225 let Inst{28-24} = 0b01110; 6226 let Inst{23-22} = size; 6227 let Inst{21} = 0b1; 6228 let Inst{20-19} = size2; 6229 let Inst{18-17} = 0b00; 6230 let Inst{16-12} = opcode; 6231 let Inst{11-10} = 0b10; 6232 let Inst{9-5} = Rn; 6233 let Inst{4-0} = Rd; 6234} 6235 6236// Comparisons support all element sizes, except 1xD. 6237multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6238 SDNode OpNode> { 6239 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6240 asm, ".8b", "0", 6241 v8i8, v8i8, OpNode>; 6242 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6243 asm, ".16b", "0", 6244 v16i8, v16i8, OpNode>; 6245 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6246 asm, ".4h", "0", 6247 v4i16, v4i16, OpNode>; 6248 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6249 asm, ".8h", "0", 6250 v8i16, v8i16, OpNode>; 6251 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6252 asm, ".2s", "0", 6253 v2i32, v2i32, OpNode>; 6254 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6255 asm, ".4s", "0", 6256 v4i32, v4i32, OpNode>; 6257 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6258 asm, ".2d", "0", 6259 v2i64, v2i64, OpNode>; 6260} 6261 6262// FP Comparisons support only S and D element sizes (and H for v8.2a). 6263multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6264 string asm, SDNode OpNode> { 6265 6266 let mayRaiseFPException = 1 in { 6267 let Predicates = [HasNEON, HasFullFP16] in { 6268 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6269 asm, ".4h", "0.0", 6270 v4i16, v4f16, OpNode>; 6271 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6272 asm, ".8h", "0.0", 6273 v8i16, v8f16, OpNode>; 6274 } // Predicates = [HasNEON, HasFullFP16] 6275 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6276 asm, ".2s", "0.0", 6277 v2i32, v2f32, OpNode>; 6278 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6279 asm, ".4s", "0.0", 6280 v4i32, v4f32, OpNode>; 6281 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6282 asm, ".2d", "0.0", 6283 v2i64, v2f64, OpNode>; 6284 } 6285 6286 let Predicates = [HasNEON, HasFullFP16] in { 6287 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6288 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6289 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6290 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6291 } 6292 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6293 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6294 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6295 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6296 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6297 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6298 let Predicates = [HasNEON, HasFullFP16] in { 6299 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6300 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6301 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6302 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6303 } 6304 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6305 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6306 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6307 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6308 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6309 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6310} 6311 6312let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 6313class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6314 RegisterOperand outtype, RegisterOperand intype, 6315 string asm, string VdTy, string VnTy, 6316 list<dag> pattern> 6317 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6318 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6319 Sched<[WriteVq]> { 6320 bits<5> Rd; 6321 bits<5> Rn; 6322 let Inst{31} = 0; 6323 let Inst{30} = Q; 6324 let Inst{29} = U; 6325 let Inst{28-24} = 0b01110; 6326 let Inst{23-22} = size; 6327 let Inst{21-17} = 0b10000; 6328 let Inst{16-12} = opcode; 6329 let Inst{11-10} = 0b10; 6330 let Inst{9-5} = Rn; 6331 let Inst{4-0} = Rd; 6332} 6333 6334let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 6335class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6336 RegisterOperand outtype, RegisterOperand intype, 6337 string asm, string VdTy, string VnTy, 6338 list<dag> pattern> 6339 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6340 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6341 Sched<[WriteVq]> { 6342 bits<5> Rd; 6343 bits<5> Rn; 6344 let Inst{31} = 0; 6345 let Inst{30} = Q; 6346 let Inst{29} = U; 6347 let Inst{28-24} = 0b01110; 6348 let Inst{23-22} = size; 6349 let Inst{21-17} = 0b10000; 6350 let Inst{16-12} = opcode; 6351 let Inst{11-10} = 0b10; 6352 let Inst{9-5} = Rn; 6353 let Inst{4-0} = Rd; 6354} 6355 6356multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6357 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6358 asm, ".4s", ".4h", []>; 6359 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6360 asm#"2", ".4s", ".8h", []>; 6361 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6362 asm, ".2d", ".2s", []>; 6363 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6364 asm#"2", ".2d", ".4s", []>; 6365} 6366 6367multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6368 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6369 asm, ".4h", ".4s", []>; 6370 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6371 asm#"2", ".8h", ".4s", []>; 6372 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6373 asm, ".2s", ".2d", []>; 6374 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6375 asm#"2", ".4s", ".2d", []>; 6376} 6377 6378multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6379 Intrinsic OpNode> { 6380 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6381 asm, ".2s", ".2d", 6382 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6383 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6384 asm#"2", ".4s", ".2d", []>; 6385 6386 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6387 (!cast<Instruction>(NAME # "v4f32") 6388 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6389} 6390 6391//---------------------------------------------------------------------------- 6392// AdvSIMD three register different-size vector instructions. 6393//---------------------------------------------------------------------------- 6394 6395let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6396class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6397 RegisterOperand outtype, RegisterOperand intype1, 6398 RegisterOperand intype2, string asm, 6399 string outkind, string inkind1, string inkind2, 6400 list<dag> pattern> 6401 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6402 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6403 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6404 Sched<[WriteVq]> { 6405 bits<5> Rd; 6406 bits<5> Rn; 6407 bits<5> Rm; 6408 let Inst{31} = 0; 6409 let Inst{30} = size{0}; 6410 let Inst{29} = U; 6411 let Inst{28-24} = 0b01110; 6412 let Inst{23-22} = size{2-1}; 6413 let Inst{21} = 1; 6414 let Inst{20-16} = Rm; 6415 let Inst{15-12} = opcode; 6416 let Inst{11-10} = 0b00; 6417 let Inst{9-5} = Rn; 6418 let Inst{4-0} = Rd; 6419} 6420 6421let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6422class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6423 RegisterOperand outtype, RegisterOperand intype1, 6424 RegisterOperand intype2, string asm, 6425 string outkind, string inkind1, string inkind2, 6426 list<dag> pattern> 6427 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6428 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6429 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6430 Sched<[WriteVq]> { 6431 bits<5> Rd; 6432 bits<5> Rn; 6433 bits<5> Rm; 6434 let Inst{31} = 0; 6435 let Inst{30} = size{0}; 6436 let Inst{29} = U; 6437 let Inst{28-24} = 0b01110; 6438 let Inst{23-22} = size{2-1}; 6439 let Inst{21} = 1; 6440 let Inst{20-16} = Rm; 6441 let Inst{15-12} = opcode; 6442 let Inst{11-10} = 0b00; 6443 let Inst{9-5} = Rn; 6444 let Inst{4-0} = Rd; 6445} 6446 6447// FIXME: TableGen doesn't know how to deal with expanded types that also 6448// change the element count (in this case, placing the results in 6449// the high elements of the result register rather than the low 6450// elements). Until that's fixed, we can't code-gen those. 6451multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6452 Intrinsic IntOp> { 6453 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6454 V64, V128, V128, 6455 asm, ".8b", ".8h", ".8h", 6456 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6457 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6458 V128, V128, V128, 6459 asm#"2", ".16b", ".8h", ".8h", 6460 []>; 6461 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6462 V64, V128, V128, 6463 asm, ".4h", ".4s", ".4s", 6464 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6465 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6466 V128, V128, V128, 6467 asm#"2", ".8h", ".4s", ".4s", 6468 []>; 6469 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6470 V64, V128, V128, 6471 asm, ".2s", ".2d", ".2d", 6472 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6473 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6474 V128, V128, V128, 6475 asm#"2", ".4s", ".2d", ".2d", 6476 []>; 6477 6478 6479 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6480 // a version attached to an instruction. 6481 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6482 (v8i16 V128:$Rm))), 6483 (!cast<Instruction>(NAME # "v8i16_v16i8") 6484 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6485 V128:$Rn, V128:$Rm)>; 6486 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6487 (v4i32 V128:$Rm))), 6488 (!cast<Instruction>(NAME # "v4i32_v8i16") 6489 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6490 V128:$Rn, V128:$Rm)>; 6491 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6492 (v2i64 V128:$Rm))), 6493 (!cast<Instruction>(NAME # "v2i64_v4i32") 6494 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6495 V128:$Rn, V128:$Rm)>; 6496} 6497 6498multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6499 Intrinsic IntOp> { 6500 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6501 V128, V64, V64, 6502 asm, ".8h", ".8b", ".8b", 6503 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6504 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6505 V128, V128, V128, 6506 asm#"2", ".8h", ".16b", ".16b", []>; 6507 let Predicates = [HasAES] in { 6508 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6509 V128, V64, V64, 6510 asm, ".1q", ".1d", ".1d", []>; 6511 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6512 V128, V128, V128, 6513 asm#"2", ".1q", ".2d", ".2d", []>; 6514 } 6515 6516 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6517 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6518 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6519} 6520 6521multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6522 SDPatternOperator OpNode> { 6523 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6524 V128, V64, V64, 6525 asm, ".4s", ".4h", ".4h", 6526 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6527 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6528 V128, V128, V128, 6529 asm#"2", ".4s", ".8h", ".8h", 6530 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6531 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6532 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6533 V128, V64, V64, 6534 asm, ".2d", ".2s", ".2s", 6535 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6536 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6537 V128, V128, V128, 6538 asm#"2", ".2d", ".4s", ".4s", 6539 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6540 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6541} 6542 6543multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6544 SDPatternOperator OpNode = null_frag> { 6545 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6546 V128, V64, V64, 6547 asm, ".8h", ".8b", ".8b", 6548 [(set (v8i16 V128:$Rd), 6549 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6550 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6551 V128, V128, V128, 6552 asm#"2", ".8h", ".16b", ".16b", 6553 [(set (v8i16 V128:$Rd), 6554 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6555 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 6556 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6557 V128, V64, V64, 6558 asm, ".4s", ".4h", ".4h", 6559 [(set (v4i32 V128:$Rd), 6560 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6561 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6562 V128, V128, V128, 6563 asm#"2", ".4s", ".8h", ".8h", 6564 [(set (v4i32 V128:$Rd), 6565 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6566 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6567 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6568 V128, V64, V64, 6569 asm, ".2d", ".2s", ".2s", 6570 [(set (v2i64 V128:$Rd), 6571 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6572 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6573 V128, V128, V128, 6574 asm#"2", ".2d", ".4s", ".4s", 6575 [(set (v2i64 V128:$Rd), 6576 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6577 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6578} 6579 6580multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6581 string asm, 6582 SDPatternOperator OpNode> { 6583 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6584 V128, V64, V64, 6585 asm, ".8h", ".8b", ".8b", 6586 [(set (v8i16 V128:$dst), 6587 (add (v8i16 V128:$Rd), 6588 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6589 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6590 V128, V128, V128, 6591 asm#"2", ".8h", ".16b", ".16b", 6592 [(set (v8i16 V128:$dst), 6593 (add (v8i16 V128:$Rd), 6594 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6595 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 6596 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6597 V128, V64, V64, 6598 asm, ".4s", ".4h", ".4h", 6599 [(set (v4i32 V128:$dst), 6600 (add (v4i32 V128:$Rd), 6601 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6602 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6603 V128, V128, V128, 6604 asm#"2", ".4s", ".8h", ".8h", 6605 [(set (v4i32 V128:$dst), 6606 (add (v4i32 V128:$Rd), 6607 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6608 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 6609 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6610 V128, V64, V64, 6611 asm, ".2d", ".2s", ".2s", 6612 [(set (v2i64 V128:$dst), 6613 (add (v2i64 V128:$Rd), 6614 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6615 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6616 V128, V128, V128, 6617 asm#"2", ".2d", ".4s", ".4s", 6618 [(set (v2i64 V128:$dst), 6619 (add (v2i64 V128:$Rd), 6620 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6621 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 6622} 6623 6624multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6625 SDPatternOperator OpNode = null_frag> { 6626 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6627 V128, V64, V64, 6628 asm, ".8h", ".8b", ".8b", 6629 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6630 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6631 V128, V128, V128, 6632 asm#"2", ".8h", ".16b", ".16b", 6633 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6634 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6635 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6636 V128, V64, V64, 6637 asm, ".4s", ".4h", ".4h", 6638 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6639 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6640 V128, V128, V128, 6641 asm#"2", ".4s", ".8h", ".8h", 6642 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6643 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6644 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6645 V128, V64, V64, 6646 asm, ".2d", ".2s", ".2s", 6647 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6648 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6649 V128, V128, V128, 6650 asm#"2", ".2d", ".4s", ".4s", 6651 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6652 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6653} 6654 6655multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6656 string asm, 6657 SDPatternOperator OpNode> { 6658 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6659 V128, V64, V64, 6660 asm, ".8h", ".8b", ".8b", 6661 [(set (v8i16 V128:$dst), 6662 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6663 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6664 V128, V128, V128, 6665 asm#"2", ".8h", ".16b", ".16b", 6666 [(set (v8i16 V128:$dst), 6667 (OpNode (v8i16 V128:$Rd), 6668 (extract_high_v16i8 (v16i8 V128:$Rn)), 6669 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6670 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6671 V128, V64, V64, 6672 asm, ".4s", ".4h", ".4h", 6673 [(set (v4i32 V128:$dst), 6674 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6675 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6676 V128, V128, V128, 6677 asm#"2", ".4s", ".8h", ".8h", 6678 [(set (v4i32 V128:$dst), 6679 (OpNode (v4i32 V128:$Rd), 6680 (extract_high_v8i16 (v8i16 V128:$Rn)), 6681 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6682 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6683 V128, V64, V64, 6684 asm, ".2d", ".2s", ".2s", 6685 [(set (v2i64 V128:$dst), 6686 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6687 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6688 V128, V128, V128, 6689 asm#"2", ".2d", ".4s", ".4s", 6690 [(set (v2i64 V128:$dst), 6691 (OpNode (v2i64 V128:$Rd), 6692 (extract_high_v4i32 (v4i32 V128:$Rn)), 6693 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6694} 6695 6696multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6697 SDPatternOperator Accum> { 6698 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6699 V128, V64, V64, 6700 asm, ".4s", ".4h", ".4h", 6701 [(set (v4i32 V128:$dst), 6702 (Accum (v4i32 V128:$Rd), 6703 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6704 (v4i16 V64:$Rm)))))]>; 6705 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6706 V128, V128, V128, 6707 asm#"2", ".4s", ".8h", ".8h", 6708 [(set (v4i32 V128:$dst), 6709 (Accum (v4i32 V128:$Rd), 6710 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 6711 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6712 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6713 V128, V64, V64, 6714 asm, ".2d", ".2s", ".2s", 6715 [(set (v2i64 V128:$dst), 6716 (Accum (v2i64 V128:$Rd), 6717 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6718 (v2i32 V64:$Rm)))))]>; 6719 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6720 V128, V128, V128, 6721 asm#"2", ".2d", ".4s", ".4s", 6722 [(set (v2i64 V128:$dst), 6723 (Accum (v2i64 V128:$Rd), 6724 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 6725 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6726} 6727 6728multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6729 SDPatternOperator OpNode> { 6730 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6731 V128, V128, V64, 6732 asm, ".8h", ".8h", ".8b", 6733 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6734 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6735 V128, V128, V128, 6736 asm#"2", ".8h", ".8h", ".16b", 6737 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6738 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6739 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6740 V128, V128, V64, 6741 asm, ".4s", ".4s", ".4h", 6742 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6743 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6744 V128, V128, V128, 6745 asm#"2", ".4s", ".4s", ".8h", 6746 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6747 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6748 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6749 V128, V128, V64, 6750 asm, ".2d", ".2d", ".2s", 6751 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6752 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6753 V128, V128, V128, 6754 asm#"2", ".2d", ".2d", ".4s", 6755 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6756 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6757} 6758 6759//---------------------------------------------------------------------------- 6760// AdvSIMD bitwise extract from vector 6761//---------------------------------------------------------------------------- 6762 6763class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6764 string asm, string kind> 6765 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6766 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6767 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6768 [(set (vty regtype:$Rd), 6769 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6770 Sched<[!if(size, WriteVq, WriteVd)]> { 6771 bits<5> Rd; 6772 bits<5> Rn; 6773 bits<5> Rm; 6774 bits<4> imm; 6775 let Inst{31} = 0; 6776 let Inst{30} = size; 6777 let Inst{29-21} = 0b101110000; 6778 let Inst{20-16} = Rm; 6779 let Inst{15} = 0; 6780 let Inst{14-11} = imm; 6781 let Inst{10} = 0; 6782 let Inst{9-5} = Rn; 6783 let Inst{4-0} = Rd; 6784} 6785 6786 6787multiclass SIMDBitwiseExtract<string asm> { 6788 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6789 let imm{3} = 0; 6790 } 6791 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6792} 6793 6794//---------------------------------------------------------------------------- 6795// AdvSIMD zip vector 6796//---------------------------------------------------------------------------- 6797 6798class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6799 string asm, string kind, SDNode OpNode, ValueType valty> 6800 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6801 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6802 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6803 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6804 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 6805 bits<5> Rd; 6806 bits<5> Rn; 6807 bits<5> Rm; 6808 let Inst{31} = 0; 6809 let Inst{30} = size{0}; 6810 let Inst{29-24} = 0b001110; 6811 let Inst{23-22} = size{2-1}; 6812 let Inst{21} = 0; 6813 let Inst{20-16} = Rm; 6814 let Inst{15} = 0; 6815 let Inst{14-12} = opc; 6816 let Inst{11-10} = 0b10; 6817 let Inst{9-5} = Rn; 6818 let Inst{4-0} = Rd; 6819} 6820 6821multiclass SIMDZipVector<bits<3>opc, string asm, 6822 SDNode OpNode> { 6823 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6824 asm, ".8b", OpNode, v8i8>; 6825 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6826 asm, ".16b", OpNode, v16i8>; 6827 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6828 asm, ".4h", OpNode, v4i16>; 6829 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6830 asm, ".8h", OpNode, v8i16>; 6831 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6832 asm, ".2s", OpNode, v2i32>; 6833 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6834 asm, ".4s", OpNode, v4i32>; 6835 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6836 asm, ".2d", OpNode, v2i64>; 6837 6838 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6839 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6840 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6841 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6842 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6843 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6844 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6845 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6846 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6847 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6848} 6849 6850//---------------------------------------------------------------------------- 6851// AdvSIMD three register scalar instructions 6852//---------------------------------------------------------------------------- 6853 6854let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6855class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6856 RegisterClass regtype, string asm, 6857 list<dag> pattern> 6858 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6859 "\t$Rd, $Rn, $Rm", "", pattern>, 6860 Sched<[WriteVd]> { 6861 bits<5> Rd; 6862 bits<5> Rn; 6863 bits<5> Rm; 6864 let Inst{31-30} = 0b01; 6865 let Inst{29} = U; 6866 let Inst{28-24} = 0b11110; 6867 let Inst{23-21} = size; 6868 let Inst{20-16} = Rm; 6869 let Inst{15-11} = opcode; 6870 let Inst{10} = 1; 6871 let Inst{9-5} = Rn; 6872 let Inst{4-0} = Rd; 6873} 6874 6875let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6876class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6877 dag oops, dag iops, string asm, 6878 list<dag> pattern> 6879 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6880 Sched<[WriteVd]> { 6881 bits<5> Rd; 6882 bits<5> Rn; 6883 bits<5> Rm; 6884 let Inst{31-30} = 0b01; 6885 let Inst{29} = U; 6886 let Inst{28-24} = 0b11110; 6887 let Inst{23-22} = size; 6888 let Inst{21} = R; 6889 let Inst{20-16} = Rm; 6890 let Inst{15-11} = opcode; 6891 let Inst{10} = 1; 6892 let Inst{9-5} = Rn; 6893 let Inst{4-0} = Rd; 6894} 6895 6896multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6897 SDPatternOperator OpNode> { 6898 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6899 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6900} 6901 6902multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6903 SDPatternOperator OpNode> { 6904 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6905 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6906 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6907 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6908 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6909 6910 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6911 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6912 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6913 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6914} 6915 6916multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6917 SDPatternOperator OpNode> { 6918 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6919 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6920 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6921} 6922 6923multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 6924 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6925 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6926 asm, []>; 6927 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6928 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6929 asm, []>; 6930} 6931 6932multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6933 SDPatternOperator OpNode = null_frag, 6934 Predicate pred = HasNEON> { 6935 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in { 6936 let Predicates = [pred] in { 6937 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6938 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6939 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6940 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6941 } 6942 let Predicates = [pred, HasFullFP16] in { 6943 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6944 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6945 } 6946 } 6947 6948 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6949 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6950} 6951 6952multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6953 SDPatternOperator OpNode = null_frag> { 6954 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in { 6955 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6956 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6957 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6958 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6959 let Predicates = [HasNEON, HasFullFP16] in { 6960 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6961 []>; 6962 } // Predicates = [HasNEON, HasFullFP16] 6963 } 6964 6965 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6966 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6967} 6968 6969class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6970 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6971 : I<oops, iops, asm, 6972 "\t$Rd, $Rn, $Rm", cstr, pat>, 6973 Sched<[WriteVd]> { 6974 bits<5> Rd; 6975 bits<5> Rn; 6976 bits<5> Rm; 6977 let Inst{31-30} = 0b01; 6978 let Inst{29} = U; 6979 let Inst{28-24} = 0b11110; 6980 let Inst{23-22} = size; 6981 let Inst{21} = 1; 6982 let Inst{20-16} = Rm; 6983 let Inst{15-11} = opcode; 6984 let Inst{10} = 0; 6985 let Inst{9-5} = Rn; 6986 let Inst{4-0} = Rd; 6987} 6988 6989let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6990multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6991 SDPatternOperator OpNode = null_frag> { 6992 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6993 (outs FPR32:$Rd), 6994 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6995 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6996 (outs FPR64:$Rd), 6997 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6998 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6999} 7000 7001let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7002multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7003 SDPatternOperator OpNode = null_frag> { 7004 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7005 (outs FPR32:$dst), 7006 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7007 asm, "$Rd = $dst", []>; 7008 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7009 (outs FPR64:$dst), 7010 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7011 asm, "$Rd = $dst", 7012 [(set (i64 FPR64:$dst), 7013 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7014} 7015 7016//---------------------------------------------------------------------------- 7017// AdvSIMD two register scalar instructions 7018//---------------------------------------------------------------------------- 7019 7020let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7021class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7022 RegisterClass regtype, RegisterClass regtype2, 7023 string asm, list<dag> pat> 7024 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7025 "\t$Rd, $Rn", "", pat>, 7026 Sched<[WriteVd]> { 7027 bits<5> Rd; 7028 bits<5> Rn; 7029 let Inst{31-30} = 0b01; 7030 let Inst{29} = U; 7031 let Inst{28-24} = 0b11110; 7032 let Inst{23-22} = size; 7033 let Inst{21} = 0b1; 7034 let Inst{20-19} = size2; 7035 let Inst{18-17} = 0b00; 7036 let Inst{16-12} = opcode; 7037 let Inst{11-10} = 0b10; 7038 let Inst{9-5} = Rn; 7039 let Inst{4-0} = Rd; 7040} 7041 7042let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7043class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7044 RegisterClass regtype, RegisterClass regtype2, 7045 string asm, list<dag> pat> 7046 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7047 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7048 Sched<[WriteVd]> { 7049 bits<5> Rd; 7050 bits<5> Rn; 7051 let Inst{31-30} = 0b01; 7052 let Inst{29} = U; 7053 let Inst{28-24} = 0b11110; 7054 let Inst{23-22} = size; 7055 let Inst{21-17} = 0b10000; 7056 let Inst{16-12} = opcode; 7057 let Inst{11-10} = 0b10; 7058 let Inst{9-5} = Rn; 7059 let Inst{4-0} = Rd; 7060} 7061 7062 7063let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7064class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7065 RegisterClass regtype, string asm, string zero> 7066 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7067 "\t$Rd, $Rn, #" # zero, "", []>, 7068 Sched<[WriteVd]> { 7069 bits<5> Rd; 7070 bits<5> Rn; 7071 let Inst{31-30} = 0b01; 7072 let Inst{29} = U; 7073 let Inst{28-24} = 0b11110; 7074 let Inst{23-22} = size; 7075 let Inst{21} = 0b1; 7076 let Inst{20-19} = size2; 7077 let Inst{18-17} = 0b00; 7078 let Inst{16-12} = opcode; 7079 let Inst{11-10} = 0b10; 7080 let Inst{9-5} = Rn; 7081 let Inst{4-0} = Rd; 7082} 7083 7084let mayRaiseFPException = 1 in 7085class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7086 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7087 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7088 Sched<[WriteVd]> { 7089 bits<5> Rd; 7090 bits<5> Rn; 7091 let Inst{31-17} = 0b011111100110000; 7092 let Inst{16-12} = opcode; 7093 let Inst{11-10} = 0b10; 7094 let Inst{9-5} = Rn; 7095 let Inst{4-0} = Rd; 7096} 7097 7098multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7099 SDPatternOperator OpNode> { 7100 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7101 7102 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7103 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7104} 7105 7106multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7107 SDPatternOperator OpNode> { 7108 let mayRaiseFPException = 1 in { 7109 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7110 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7111 let Predicates = [HasNEON, HasFullFP16] in { 7112 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7113 } 7114 } 7115 7116 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7117 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7118 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7119 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7120 let Predicates = [HasNEON, HasFullFP16] in { 7121 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7122 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7123 } 7124 7125 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7126 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7127} 7128 7129multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7130 SDPatternOperator OpNode = null_frag> { 7131 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7132 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7133 7134 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7135 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7136} 7137 7138let mayRaiseFPException = 1 in 7139multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7140 Predicate pred = HasNEON> { 7141 let Predicates = [pred] in { 7142 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7143 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7144 } 7145 let Predicates = [pred, HasFullFP16] in { 7146 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7147 } 7148} 7149 7150let mayRaiseFPException = 1 in 7151multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7152 SDPatternOperator OpNode> { 7153 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7154 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7155 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7156 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7157 let Predicates = [HasNEON, HasFullFP16] in { 7158 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7159 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7160 } 7161} 7162 7163multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7164 SDPatternOperator OpNode = null_frag> { 7165 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7166 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7167 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7168 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7169 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7170 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7171 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7172 } 7173 7174 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7175 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7176} 7177 7178multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7179 Intrinsic OpNode> { 7180 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7181 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7182 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7183 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7184 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7185 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7186 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7187 } 7188 7189 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7190 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7191} 7192 7193 7194 7195let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7196multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7197 SDPatternOperator OpNode = null_frag> { 7198 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7199 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7200 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7201 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7202} 7203 7204//---------------------------------------------------------------------------- 7205// AdvSIMD scalar pairwise instructions 7206//---------------------------------------------------------------------------- 7207 7208let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7209class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7210 RegisterOperand regtype, RegisterOperand vectype, 7211 string asm, string kind> 7212 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7213 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7214 Sched<[WriteVd]> { 7215 bits<5> Rd; 7216 bits<5> Rn; 7217 let Inst{31-30} = 0b01; 7218 let Inst{29} = U; 7219 let Inst{28-24} = 0b11110; 7220 let Inst{23-22} = size; 7221 let Inst{21-17} = 0b11000; 7222 let Inst{16-12} = opcode; 7223 let Inst{11-10} = 0b10; 7224 let Inst{9-5} = Rn; 7225 let Inst{4-0} = Rd; 7226} 7227 7228multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7229 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7230 asm, ".2d">; 7231} 7232 7233let mayRaiseFPException = 1 in 7234multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7235 let Predicates = [HasNEON, HasFullFP16] in { 7236 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7237 asm, ".2h">; 7238 } 7239 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7240 asm, ".2s">; 7241 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7242 asm, ".2d">; 7243} 7244 7245//---------------------------------------------------------------------------- 7246// AdvSIMD across lanes instructions 7247//---------------------------------------------------------------------------- 7248 7249let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7250class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7251 RegisterClass regtype, RegisterOperand vectype, 7252 string asm, string kind, list<dag> pattern> 7253 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7254 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7255 Sched<[!if(Q, WriteVq, WriteVd)]> { 7256 bits<5> Rd; 7257 bits<5> Rn; 7258 let Inst{31} = 0; 7259 let Inst{30} = Q; 7260 let Inst{29} = U; 7261 let Inst{28-24} = 0b01110; 7262 let Inst{23-22} = size; 7263 let Inst{21-17} = 0b11000; 7264 let Inst{16-12} = opcode; 7265 let Inst{11-10} = 0b10; 7266 let Inst{9-5} = Rn; 7267 let Inst{4-0} = Rd; 7268} 7269 7270multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7271 string asm> { 7272 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7273 asm, ".8b", []>; 7274 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7275 asm, ".16b", []>; 7276 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7277 asm, ".4h", []>; 7278 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7279 asm, ".8h", []>; 7280 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7281 asm, ".4s", []>; 7282} 7283 7284multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7285 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7286 asm, ".8b", []>; 7287 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7288 asm, ".16b", []>; 7289 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7290 asm, ".4h", []>; 7291 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7292 asm, ".8h", []>; 7293 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7294 asm, ".4s", []>; 7295} 7296 7297let mayRaiseFPException = 1 in 7298multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7299 Intrinsic intOp> { 7300 let Predicates = [HasNEON, HasFullFP16] in { 7301 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7302 asm, ".4h", 7303 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7304 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7305 asm, ".8h", 7306 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7307 } // Predicates = [HasNEON, HasFullFP16] 7308 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7309 asm, ".4s", 7310 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7311} 7312 7313//---------------------------------------------------------------------------- 7314// AdvSIMD INS/DUP instructions 7315//---------------------------------------------------------------------------- 7316 7317// FIXME: There has got to be a better way to factor these. ugh. 7318 7319class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7320 string operands, string constraints, list<dag> pattern> 7321 : I<outs, ins, asm, operands, constraints, pattern>, 7322 Sched<[!if(Q, WriteVq, WriteVd)]> { 7323 bits<5> Rd; 7324 bits<5> Rn; 7325 let Inst{31} = 0; 7326 let Inst{30} = Q; 7327 let Inst{29} = op; 7328 let Inst{28-21} = 0b01110000; 7329 let Inst{15} = 0; 7330 let Inst{10} = 1; 7331 let Inst{9-5} = Rn; 7332 let Inst{4-0} = Rd; 7333} 7334 7335class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7336 RegisterOperand vecreg, RegisterClass regtype> 7337 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7338 "{\t$Rd" # size # ", $Rn" # 7339 "|" # size # "\t$Rd, $Rn}", "", 7340 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7341 let Inst{20-16} = imm5; 7342 let Inst{14-11} = 0b0001; 7343} 7344 7345class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7346 ValueType vectype, ValueType insreg, 7347 RegisterOperand vecreg, Operand idxtype, 7348 SDNode OpNode> 7349 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7350 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7351 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7352 [(set (vectype vecreg:$Rd), 7353 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7354 let Inst{14-11} = 0b0000; 7355} 7356 7357class SIMDDup64FromElement 7358 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7359 VectorIndexD, AArch64duplane64> { 7360 bits<1> idx; 7361 let Inst{20} = idx; 7362 let Inst{19-16} = 0b1000; 7363} 7364 7365class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7366 RegisterOperand vecreg> 7367 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7368 VectorIndexS, AArch64duplane32> { 7369 bits<2> idx; 7370 let Inst{20-19} = idx; 7371 let Inst{18-16} = 0b100; 7372} 7373 7374class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7375 RegisterOperand vecreg> 7376 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7377 VectorIndexH, AArch64duplane16> { 7378 bits<3> idx; 7379 let Inst{20-18} = idx; 7380 let Inst{17-16} = 0b10; 7381} 7382 7383class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7384 RegisterOperand vecreg> 7385 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7386 VectorIndexB, AArch64duplane8> { 7387 bits<4> idx; 7388 let Inst{20-17} = idx; 7389 let Inst{16} = 1; 7390} 7391 7392class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7393 Operand idxtype, string asm, list<dag> pattern> 7394 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7395 "{\t$Rd, $Rn" # size # "$idx" # 7396 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7397 let Inst{14-11} = imm4; 7398} 7399 7400class SIMDSMov<bit Q, string size, RegisterClass regtype, 7401 Operand idxtype> 7402 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7403class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7404 Operand idxtype> 7405 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7406 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7407 7408class SIMDMovAlias<string asm, string size, Instruction inst, 7409 RegisterClass regtype, Operand idxtype> 7410 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7411 "|" # size # "\t$dst, $src$idx}", 7412 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7413 7414multiclass SMov { 7415 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7416 // streaming mode. 7417 let Predicates = [HasNEONorSME] in { 7418 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7419 let Inst{20-16} = 0b00001; 7420 } 7421 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7422 let Inst{20-16} = 0b00001; 7423 } 7424 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7425 let Inst{20-16} = 0b00010; 7426 } 7427 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7428 let Inst{20-16} = 0b00010; 7429 } 7430 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7431 let Inst{20-16} = 0b00100; 7432 } 7433 } 7434 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7435 bits<4> idx; 7436 let Inst{20-17} = idx; 7437 let Inst{16} = 1; 7438 } 7439 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7440 bits<4> idx; 7441 let Inst{20-17} = idx; 7442 let Inst{16} = 1; 7443 } 7444 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7445 bits<3> idx; 7446 let Inst{20-18} = idx; 7447 let Inst{17-16} = 0b10; 7448 } 7449 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7450 bits<3> idx; 7451 let Inst{20-18} = idx; 7452 let Inst{17-16} = 0b10; 7453 } 7454 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7455 bits<2> idx; 7456 let Inst{20-19} = idx; 7457 let Inst{18-16} = 0b100; 7458 } 7459} 7460 7461multiclass UMov { 7462 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7463 // streaming mode. 7464 let Predicates = [HasNEONorSME] in { 7465 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7466 let Inst{20-16} = 0b00001; 7467 } 7468 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7469 let Inst{20-16} = 0b00010; 7470 } 7471 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7472 let Inst{20-16} = 0b00100; 7473 } 7474 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7475 let Inst{20-16} = 0b01000; 7476 } 7477 def : SIMDMovAlias<"mov", ".s", 7478 !cast<Instruction>(NAME # vi32_idx0), 7479 GPR32, VectorIndex0>; 7480 def : SIMDMovAlias<"mov", ".d", 7481 !cast<Instruction>(NAME # vi64_idx0), 7482 GPR64, VectorIndex0>; 7483 } 7484 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7485 bits<4> idx; 7486 let Inst{20-17} = idx; 7487 let Inst{16} = 1; 7488 } 7489 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7490 bits<3> idx; 7491 let Inst{20-18} = idx; 7492 let Inst{17-16} = 0b10; 7493 } 7494 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7495 bits<2> idx; 7496 let Inst{20-19} = idx; 7497 let Inst{18-16} = 0b100; 7498 } 7499 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7500 bits<1> idx; 7501 let Inst{20} = idx; 7502 let Inst{19-16} = 0b1000; 7503 } 7504 def : SIMDMovAlias<"mov", ".s", 7505 !cast<Instruction>(NAME#"vi32"), 7506 GPR32, VectorIndexS>; 7507 def : SIMDMovAlias<"mov", ".d", 7508 !cast<Instruction>(NAME#"vi64"), 7509 GPR64, VectorIndexD>; 7510} 7511 7512class SIMDInsFromMain<string size, ValueType vectype, 7513 RegisterClass regtype, Operand idxtype> 7514 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7515 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7516 "{\t$Rd" # size # "$idx, $Rn" # 7517 "|" # size # "\t$Rd$idx, $Rn}", 7518 "$Rd = $dst", 7519 [(set V128:$dst, 7520 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7521 let Inst{14-11} = 0b0011; 7522} 7523 7524class SIMDInsFromElement<string size, ValueType vectype, 7525 ValueType elttype, Operand idxtype> 7526 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7527 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7528 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7529 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7530 "$Rd = $dst", 7531 [(set V128:$dst, 7532 (vector_insert 7533 (vectype V128:$Rd), 7534 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7535 idxtype:$idx))]>; 7536 7537class SIMDInsMainMovAlias<string size, Instruction inst, 7538 RegisterClass regtype, Operand idxtype> 7539 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7540 "|" # size #"\t$dst$idx, $src}", 7541 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7542class SIMDInsElementMovAlias<string size, Instruction inst, 7543 Operand idxtype> 7544 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7545 # "|" # size #"\t$dst$idx, $src$idx2}", 7546 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7547 7548 7549multiclass SIMDIns { 7550 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7551 bits<4> idx; 7552 let Inst{20-17} = idx; 7553 let Inst{16} = 1; 7554 } 7555 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7556 bits<3> idx; 7557 let Inst{20-18} = idx; 7558 let Inst{17-16} = 0b10; 7559 } 7560 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7561 bits<2> idx; 7562 let Inst{20-19} = idx; 7563 let Inst{18-16} = 0b100; 7564 } 7565 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7566 bits<1> idx; 7567 let Inst{20} = idx; 7568 let Inst{19-16} = 0b1000; 7569 } 7570 7571 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7572 bits<4> idx; 7573 bits<4> idx2; 7574 let Inst{20-17} = idx; 7575 let Inst{16} = 1; 7576 let Inst{14-11} = idx2; 7577 } 7578 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7579 bits<3> idx; 7580 bits<3> idx2; 7581 let Inst{20-18} = idx; 7582 let Inst{17-16} = 0b10; 7583 let Inst{14-12} = idx2; 7584 let Inst{11} = {?}; 7585 } 7586 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7587 bits<2> idx; 7588 bits<2> idx2; 7589 let Inst{20-19} = idx; 7590 let Inst{18-16} = 0b100; 7591 let Inst{14-13} = idx2; 7592 let Inst{12-11} = {?,?}; 7593 } 7594 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7595 bits<1> idx; 7596 bits<1> idx2; 7597 let Inst{20} = idx; 7598 let Inst{19-16} = 0b1000; 7599 let Inst{14} = idx2; 7600 let Inst{13-11} = {?,?,?}; 7601 } 7602 7603 // For all forms of the INS instruction, the "mov" mnemonic is the 7604 // preferred alias. Why they didn't just call the instruction "mov" in 7605 // the first place is a very good question indeed... 7606 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7607 GPR32, VectorIndexB>; 7608 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7609 GPR32, VectorIndexH>; 7610 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7611 GPR32, VectorIndexS>; 7612 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7613 GPR64, VectorIndexD>; 7614 7615 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7616 VectorIndexB>; 7617 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7618 VectorIndexH>; 7619 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7620 VectorIndexS>; 7621 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7622 VectorIndexD>; 7623} 7624 7625//---------------------------------------------------------------------------- 7626// AdvSIMD TBL/TBX 7627//---------------------------------------------------------------------------- 7628 7629let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7630class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7631 RegisterOperand listtype, string asm, string kind> 7632 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7633 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7634 Sched<[!if(Q, WriteVq, WriteVd)]> { 7635 bits<5> Vd; 7636 bits<5> Vn; 7637 bits<5> Vm; 7638 let Inst{31} = 0; 7639 let Inst{30} = Q; 7640 let Inst{29-21} = 0b001110000; 7641 let Inst{20-16} = Vm; 7642 let Inst{15} = 0; 7643 let Inst{14-13} = len; 7644 let Inst{12} = op; 7645 let Inst{11-10} = 0b00; 7646 let Inst{9-5} = Vn; 7647 let Inst{4-0} = Vd; 7648} 7649 7650let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7651class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7652 RegisterOperand listtype, string asm, string kind> 7653 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7654 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7655 Sched<[!if(Q, WriteVq, WriteVd)]> { 7656 bits<5> Vd; 7657 bits<5> Vn; 7658 bits<5> Vm; 7659 let Inst{31} = 0; 7660 let Inst{30} = Q; 7661 let Inst{29-21} = 0b001110000; 7662 let Inst{20-16} = Vm; 7663 let Inst{15} = 0; 7664 let Inst{14-13} = len; 7665 let Inst{12} = op; 7666 let Inst{11-10} = 0b00; 7667 let Inst{9-5} = Vn; 7668 let Inst{4-0} = Vd; 7669} 7670 7671class SIMDTableLookupAlias<string asm, Instruction inst, 7672 RegisterOperand vectype, RegisterOperand listtype> 7673 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7674 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7675 7676multiclass SIMDTableLookup<bit op, string asm> { 7677 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7678 asm, ".8b">; 7679 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7680 asm, ".8b">; 7681 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7682 asm, ".8b">; 7683 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7684 asm, ".8b">; 7685 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7686 asm, ".16b">; 7687 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7688 asm, ".16b">; 7689 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7690 asm, ".16b">; 7691 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7692 asm, ".16b">; 7693 7694 def : SIMDTableLookupAlias<asm # ".8b", 7695 !cast<Instruction>(NAME#"v8i8One"), 7696 V64, VecListOne128>; 7697 def : SIMDTableLookupAlias<asm # ".8b", 7698 !cast<Instruction>(NAME#"v8i8Two"), 7699 V64, VecListTwo128>; 7700 def : SIMDTableLookupAlias<asm # ".8b", 7701 !cast<Instruction>(NAME#"v8i8Three"), 7702 V64, VecListThree128>; 7703 def : SIMDTableLookupAlias<asm # ".8b", 7704 !cast<Instruction>(NAME#"v8i8Four"), 7705 V64, VecListFour128>; 7706 def : SIMDTableLookupAlias<asm # ".16b", 7707 !cast<Instruction>(NAME#"v16i8One"), 7708 V128, VecListOne128>; 7709 def : SIMDTableLookupAlias<asm # ".16b", 7710 !cast<Instruction>(NAME#"v16i8Two"), 7711 V128, VecListTwo128>; 7712 def : SIMDTableLookupAlias<asm # ".16b", 7713 !cast<Instruction>(NAME#"v16i8Three"), 7714 V128, VecListThree128>; 7715 def : SIMDTableLookupAlias<asm # ".16b", 7716 !cast<Instruction>(NAME#"v16i8Four"), 7717 V128, VecListFour128>; 7718} 7719 7720multiclass SIMDTableLookupTied<bit op, string asm> { 7721 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7722 asm, ".8b">; 7723 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7724 asm, ".8b">; 7725 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7726 asm, ".8b">; 7727 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7728 asm, ".8b">; 7729 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7730 asm, ".16b">; 7731 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7732 asm, ".16b">; 7733 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7734 asm, ".16b">; 7735 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7736 asm, ".16b">; 7737 7738 def : SIMDTableLookupAlias<asm # ".8b", 7739 !cast<Instruction>(NAME#"v8i8One"), 7740 V64, VecListOne128>; 7741 def : SIMDTableLookupAlias<asm # ".8b", 7742 !cast<Instruction>(NAME#"v8i8Two"), 7743 V64, VecListTwo128>; 7744 def : SIMDTableLookupAlias<asm # ".8b", 7745 !cast<Instruction>(NAME#"v8i8Three"), 7746 V64, VecListThree128>; 7747 def : SIMDTableLookupAlias<asm # ".8b", 7748 !cast<Instruction>(NAME#"v8i8Four"), 7749 V64, VecListFour128>; 7750 def : SIMDTableLookupAlias<asm # ".16b", 7751 !cast<Instruction>(NAME#"v16i8One"), 7752 V128, VecListOne128>; 7753 def : SIMDTableLookupAlias<asm # ".16b", 7754 !cast<Instruction>(NAME#"v16i8Two"), 7755 V128, VecListTwo128>; 7756 def : SIMDTableLookupAlias<asm # ".16b", 7757 !cast<Instruction>(NAME#"v16i8Three"), 7758 V128, VecListThree128>; 7759 def : SIMDTableLookupAlias<asm # ".16b", 7760 !cast<Instruction>(NAME#"v16i8Four"), 7761 V128, VecListFour128>; 7762} 7763 7764 7765//---------------------------------------------------------------------------- 7766// AdvSIMD scalar DUP 7767//---------------------------------------------------------------------------- 7768let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7769class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 7770 string asm, string kind, Operand idxtype> 7771 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 7772 "{\t$dst, $src" # kind # "$idx" # 7773 "|\t$dst, $src$idx}", "", []>, 7774 Sched<[WriteVd]> { 7775 bits<5> dst; 7776 bits<5> src; 7777 let Inst{31-21} = 0b01011110000; 7778 let Inst{15-10} = 0b000001; 7779 let Inst{9-5} = src; 7780 let Inst{4-0} = dst; 7781} 7782 7783class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 7784 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7785 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7786 # "|\t$dst, $src$index}", 7787 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7788 7789 7790multiclass SIMDScalarDUP<string asm> { 7791 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 7792 bits<4> idx; 7793 let Inst{20-17} = idx; 7794 let Inst{16} = 1; 7795 } 7796 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 7797 bits<3> idx; 7798 let Inst{20-18} = idx; 7799 let Inst{17-16} = 0b10; 7800 } 7801 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 7802 bits<2> idx; 7803 let Inst{20-19} = idx; 7804 let Inst{18-16} = 0b100; 7805 } 7806 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 7807 bits<1> idx; 7808 let Inst{20} = idx; 7809 let Inst{19-16} = 0b1000; 7810 } 7811 7812 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7813 VectorIndexD:$idx)))), 7814 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7815 7816 // 'DUP' mnemonic aliases. 7817 def : SIMDScalarDUPAlias<"dup", ".b", 7818 !cast<Instruction>(NAME#"i8"), 7819 FPR8, V128, VectorIndexB>; 7820 def : SIMDScalarDUPAlias<"dup", ".h", 7821 !cast<Instruction>(NAME#"i16"), 7822 FPR16, V128, VectorIndexH>; 7823 def : SIMDScalarDUPAlias<"dup", ".s", 7824 !cast<Instruction>(NAME#"i32"), 7825 FPR32, V128, VectorIndexS>; 7826 def : SIMDScalarDUPAlias<"dup", ".d", 7827 !cast<Instruction>(NAME#"i64"), 7828 FPR64, V128, VectorIndexD>; 7829} 7830 7831//---------------------------------------------------------------------------- 7832// AdvSIMD modified immediate instructions 7833//---------------------------------------------------------------------------- 7834 7835class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7836 string asm, string op_string, 7837 string cstr, list<dag> pattern> 7838 : I<oops, iops, asm, op_string, cstr, pattern>, 7839 Sched<[!if(Q, WriteVq, WriteVd)]> { 7840 bits<5> Rd; 7841 bits<8> imm8; 7842 let Inst{31} = 0; 7843 let Inst{30} = Q; 7844 let Inst{29} = op; 7845 let Inst{28-19} = 0b0111100000; 7846 let Inst{18-16} = imm8{7-5}; 7847 let Inst{11} = op2; 7848 let Inst{10} = 1; 7849 let Inst{9-5} = imm8{4-0}; 7850 let Inst{4-0} = Rd; 7851} 7852 7853class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7854 Operand immtype, dag opt_shift_iop, 7855 string opt_shift, string asm, string kind, 7856 list<dag> pattern> 7857 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7858 !con((ins immtype:$imm8), opt_shift_iop), asm, 7859 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7860 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7861 "", pattern> { 7862 let DecoderMethod = "DecodeModImmInstruction"; 7863} 7864 7865class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7866 Operand immtype, dag opt_shift_iop, 7867 string opt_shift, string asm, string kind, 7868 list<dag> pattern> 7869 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7870 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7871 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7872 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7873 "$Rd = $dst", pattern> { 7874 let DecoderMethod = "DecodeModImmTiedInstruction"; 7875} 7876 7877class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7878 RegisterOperand vectype, string asm, 7879 string kind, list<dag> pattern> 7880 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7881 (ins logical_vec_shift:$shift), 7882 "$shift", asm, kind, pattern> { 7883 bits<2> shift; 7884 let Inst{15} = b15_b12{1}; 7885 let Inst{14-13} = shift; 7886 let Inst{12} = b15_b12{0}; 7887} 7888 7889class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7890 RegisterOperand vectype, string asm, 7891 string kind, list<dag> pattern> 7892 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7893 (ins logical_vec_shift:$shift), 7894 "$shift", asm, kind, pattern> { 7895 bits<2> shift; 7896 let Inst{15} = b15_b12{1}; 7897 let Inst{14-13} = shift; 7898 let Inst{12} = b15_b12{0}; 7899} 7900 7901 7902class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7903 RegisterOperand vectype, string asm, 7904 string kind, list<dag> pattern> 7905 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7906 (ins logical_vec_hw_shift:$shift), 7907 "$shift", asm, kind, pattern> { 7908 bits<2> shift; 7909 let Inst{15} = b15_b12{1}; 7910 let Inst{14} = 0; 7911 let Inst{13} = shift{0}; 7912 let Inst{12} = b15_b12{0}; 7913} 7914 7915class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7916 RegisterOperand vectype, string asm, 7917 string kind, list<dag> pattern> 7918 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7919 (ins logical_vec_hw_shift:$shift), 7920 "$shift", asm, kind, pattern> { 7921 bits<2> shift; 7922 let Inst{15} = b15_b12{1}; 7923 let Inst{14} = 0; 7924 let Inst{13} = shift{0}; 7925 let Inst{12} = b15_b12{0}; 7926} 7927 7928multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7929 string asm> { 7930 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7931 asm, ".4h", []>; 7932 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7933 asm, ".8h", []>; 7934 7935 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7936 asm, ".2s", []>; 7937 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7938 asm, ".4s", []>; 7939} 7940 7941multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7942 bits<2> w_cmode, string asm, 7943 SDNode OpNode> { 7944 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7945 asm, ".4h", 7946 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7947 imm0_255:$imm8, 7948 (i32 imm:$shift)))]>; 7949 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7950 asm, ".8h", 7951 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7952 imm0_255:$imm8, 7953 (i32 imm:$shift)))]>; 7954 7955 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7956 asm, ".2s", 7957 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7958 imm0_255:$imm8, 7959 (i32 imm:$shift)))]>; 7960 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7961 asm, ".4s", 7962 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7963 imm0_255:$imm8, 7964 (i32 imm:$shift)))]>; 7965} 7966 7967class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7968 RegisterOperand vectype, string asm, 7969 string kind, list<dag> pattern> 7970 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7971 (ins move_vec_shift:$shift), 7972 "$shift", asm, kind, pattern> { 7973 bits<1> shift; 7974 let Inst{15-13} = cmode{3-1}; 7975 let Inst{12} = shift; 7976} 7977 7978class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7979 RegisterOperand vectype, 7980 Operand imm_type, string asm, 7981 string kind, list<dag> pattern> 7982 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7983 asm, kind, pattern> { 7984 let Inst{15-12} = cmode; 7985} 7986 7987class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7988 list<dag> pattern> 7989 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7990 "\t$Rd, $imm8", "", pattern> { 7991 let Inst{15-12} = cmode; 7992 let DecoderMethod = "DecodeModImmInstruction"; 7993} 7994 7995//---------------------------------------------------------------------------- 7996// AdvSIMD indexed element 7997//---------------------------------------------------------------------------- 7998 7999let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8000class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8001 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8002 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8003 string apple_kind, string dst_kind, string lhs_kind, 8004 string rhs_kind, list<dag> pattern> 8005 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8006 asm, 8007 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8008 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8009 Sched<[WriteVd]> { 8010 bits<5> Rd; 8011 bits<5> Rn; 8012 bits<5> Rm; 8013 8014 let Inst{31} = 0; 8015 let Inst{30} = Q; 8016 let Inst{29} = U; 8017 let Inst{28} = Scalar; 8018 let Inst{27-24} = 0b1111; 8019 let Inst{23-22} = size; 8020 // Bit 21 must be set by the derived class. 8021 let Inst{20-16} = Rm; 8022 let Inst{15-12} = opc; 8023 // Bit 11 must be set by the derived class. 8024 let Inst{10} = 0; 8025 let Inst{9-5} = Rn; 8026 let Inst{4-0} = Rd; 8027} 8028 8029let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8030class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8031 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8032 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8033 string apple_kind, string dst_kind, string lhs_kind, 8034 string rhs_kind, list<dag> pattern> 8035 : I<(outs dst_reg:$dst), 8036 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8037 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8038 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8039 Sched<[WriteVd]> { 8040 bits<5> Rd; 8041 bits<5> Rn; 8042 bits<5> Rm; 8043 8044 let Inst{31} = 0; 8045 let Inst{30} = Q; 8046 let Inst{29} = U; 8047 let Inst{28} = Scalar; 8048 let Inst{27-24} = 0b1111; 8049 let Inst{23-22} = size; 8050 // Bit 21 must be set by the derived class. 8051 let Inst{20-16} = Rm; 8052 let Inst{15-12} = opc; 8053 // Bit 11 must be set by the derived class. 8054 let Inst{10} = 0; 8055 let Inst{9-5} = Rn; 8056 let Inst{4-0} = Rd; 8057} 8058 8059 8060//---------------------------------------------------------------------------- 8061// Armv8.6 BFloat16 Extension 8062//---------------------------------------------------------------------------- 8063let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8064 8065class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8066 string kind2, RegisterOperand RegType, 8067 ValueType AccumType, ValueType InputType> 8068 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8069 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8070 (InputType RegType:$Rn), 8071 (InputType RegType:$Rm)))]> { 8072 let AsmString = !strconcat(asm, 8073 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8074 ", $Rm" # kind2 # "}"); 8075} 8076 8077multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8078 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8079 v2f32, v4bf16>; 8080 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8081 v4f32, v8bf16>; 8082} 8083 8084class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8085 string dst_kind, string lhs_kind, 8086 string rhs_kind, 8087 RegisterOperand RegType, 8088 ValueType AccumType, 8089 ValueType InputType> 8090 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8091 RegType, RegType, V128, VectorIndexS, 8092 asm, "", dst_kind, lhs_kind, rhs_kind, 8093 [(set (AccumType RegType:$dst), 8094 (AccumType (int_aarch64_neon_bfdot 8095 (AccumType RegType:$Rd), 8096 (InputType RegType:$Rn), 8097 (InputType (bitconvert (AccumType 8098 (AArch64duplane32 (v4f32 V128:$Rm), 8099 VectorIndexS:$idx)))))))]> { 8100 8101 bits<2> idx; 8102 let Inst{21} = idx{0}; // L 8103 let Inst{11} = idx{1}; // H 8104} 8105 8106multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8107 8108 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8109 ".2h", V64, v2f32, v4bf16>; 8110 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8111 ".2h", V128, v4f32, v8bf16>; 8112} 8113 8114let mayRaiseFPException = 1 in 8115class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8116 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8117 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8118 (v8bf16 V128:$Rn), 8119 (v8bf16 V128:$Rm)))]> { 8120 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8121} 8122 8123let mayRaiseFPException = 1 in 8124class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8125 : I<(outs V128:$dst), 8126 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8127 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8128 [(set (v4f32 V128:$dst), 8129 (v4f32 (OpNode (v4f32 V128:$Rd), 8130 (v8bf16 V128:$Rn), 8131 (v8bf16 8132 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8133 VectorIndexH:$idx)))))]>, 8134 Sched<[WriteVq]> { 8135 bits<5> Rd; 8136 bits<5> Rn; 8137 bits<4> Rm; 8138 bits<3> idx; 8139 8140 let Inst{31} = 0; 8141 let Inst{30} = Q; 8142 let Inst{29-22} = 0b00111111; 8143 let Inst{21-20} = idx{1-0}; 8144 let Inst{19-16} = Rm; 8145 let Inst{15-12} = 0b1111; 8146 let Inst{11} = idx{2}; // H 8147 let Inst{10} = 0; 8148 let Inst{9-5} = Rn; 8149 let Inst{4-0} = Rd; 8150} 8151 8152class SIMDThreeSameVectorBF16MatrixMul<string asm> 8153 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8154 V128, asm, ".4s", 8155 [(set (v4f32 V128:$dst), 8156 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8157 (v8bf16 V128:$Rn), 8158 (v8bf16 V128:$Rm)))]> { 8159 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8160 ", $Rm", ".8h", "}"); 8161} 8162 8163let mayRaiseFPException = 1 in 8164class SIMD_BFCVTN 8165 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8166 "bfcvtn", ".4h", ".4s", 8167 [(set (v8bf16 V128:$Rd), 8168 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8169 8170let mayRaiseFPException = 1 in 8171class SIMD_BFCVTN2 8172 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8173 "bfcvtn2", ".8h", ".4s", 8174 [(set (v8bf16 V128:$dst), 8175 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8176 8177let mayRaiseFPException = 1 in 8178class BF16ToSinglePrecision<string asm> 8179 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8180 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8181 Sched<[WriteFCvt]> { 8182 bits<5> Rd; 8183 bits<5> Rn; 8184 let Inst{31-10} = 0b0001111001100011010000; 8185 let Inst{9-5} = Rn; 8186 let Inst{4-0} = Rd; 8187} 8188} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8189 8190//---------------------------------------------------------------------------- 8191// Armv8.6 Matrix Multiply Extension 8192//---------------------------------------------------------------------------- 8193 8194class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8195 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8196 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8197 (v16i8 V128:$Rn), 8198 (v16i8 V128:$Rm)))]> { 8199 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8200} 8201 8202//---------------------------------------------------------------------------- 8203// ARMv8.2-A Dot Product Instructions (Indexed) 8204class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8205 string dst_kind, string lhs_kind, string rhs_kind, 8206 RegisterOperand RegType, 8207 ValueType AccumType, ValueType InputType, 8208 SDPatternOperator OpNode> : 8209 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8210 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8211 [(set (AccumType RegType:$dst), 8212 (AccumType (OpNode (AccumType RegType:$Rd), 8213 (InputType RegType:$Rn), 8214 (InputType (bitconvert (AccumType 8215 (AArch64duplane32 (v4i32 V128:$Rm), 8216 VectorIndexS:$idx)))))))]> { 8217 bits<2> idx; 8218 let Inst{21} = idx{0}; // L 8219 let Inst{11} = idx{1}; // H 8220} 8221 8222multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8223 SDPatternOperator OpNode> { 8224 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8225 V64, v2i32, v8i8, OpNode>; 8226 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8227 V128, v4i32, v16i8, OpNode>; 8228} 8229 8230// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8231let mayRaiseFPException = 1 in 8232class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8233 string dst_kind, string lhs_kind, 8234 string rhs_kind, RegisterOperand RegType, 8235 ValueType AccumType, ValueType InputType, 8236 SDPatternOperator OpNode> : 8237 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8238 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8239 [(set (AccumType RegType:$dst), 8240 (AccumType (OpNode (AccumType RegType:$Rd), 8241 (InputType RegType:$Rn), 8242 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8243 VectorIndexH:$idx)))))]> { 8244 // idx = H:L:M 8245 bits<3> idx; 8246 let Inst{11} = idx{2}; // H 8247 let Inst{21} = idx{1}; // L 8248 let Inst{20} = idx{0}; // M 8249} 8250 8251multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8252 SDPatternOperator OpNode> { 8253 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8254 V64, v2f32, v4f16, OpNode>; 8255 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8256 V128, v4f32, v8f16, OpNode>; 8257} 8258 8259let mayRaiseFPException = 1 in 8260multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8261 SDPatternOperator OpNode> { 8262 let Predicates = [HasNEON, HasFullFP16] in { 8263 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8264 V64, V64, 8265 V128_lo, VectorIndexH, 8266 asm, ".4h", ".4h", ".4h", ".h", 8267 [(set (v4f16 V64:$Rd), 8268 (OpNode (v4f16 V64:$Rn), 8269 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8270 bits<3> idx; 8271 let Inst{11} = idx{2}; 8272 let Inst{21} = idx{1}; 8273 let Inst{20} = idx{0}; 8274 } 8275 8276 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8277 V128, V128, 8278 V128_lo, VectorIndexH, 8279 asm, ".8h", ".8h", ".8h", ".h", 8280 [(set (v8f16 V128:$Rd), 8281 (OpNode (v8f16 V128:$Rn), 8282 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8283 bits<3> idx; 8284 let Inst{11} = idx{2}; 8285 let Inst{21} = idx{1}; 8286 let Inst{20} = idx{0}; 8287 } 8288 } // Predicates = [HasNEON, HasFullFP16] 8289 8290 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8291 V64, V64, 8292 V128, VectorIndexS, 8293 asm, ".2s", ".2s", ".2s", ".s", 8294 [(set (v2f32 V64:$Rd), 8295 (OpNode (v2f32 V64:$Rn), 8296 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8297 bits<2> idx; 8298 let Inst{11} = idx{1}; 8299 let Inst{21} = idx{0}; 8300 } 8301 8302 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8303 V128, V128, 8304 V128, VectorIndexS, 8305 asm, ".4s", ".4s", ".4s", ".s", 8306 [(set (v4f32 V128:$Rd), 8307 (OpNode (v4f32 V128:$Rn), 8308 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8309 bits<2> idx; 8310 let Inst{11} = idx{1}; 8311 let Inst{21} = idx{0}; 8312 } 8313 8314 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8315 V128, V128, 8316 V128, VectorIndexD, 8317 asm, ".2d", ".2d", ".2d", ".d", 8318 [(set (v2f64 V128:$Rd), 8319 (OpNode (v2f64 V128:$Rn), 8320 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8321 bits<1> idx; 8322 let Inst{11} = idx{0}; 8323 let Inst{21} = 0; 8324 } 8325 8326 let Predicates = [HasNEON, HasFullFP16] in { 8327 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8328 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8329 asm, ".h", "", "", ".h", 8330 [(set (f16 FPR16Op:$Rd), 8331 (OpNode (f16 FPR16Op:$Rn), 8332 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8333 VectorIndexH:$idx))))]> { 8334 bits<3> idx; 8335 let Inst{11} = idx{2}; 8336 let Inst{21} = idx{1}; 8337 let Inst{20} = idx{0}; 8338 } 8339 } // Predicates = [HasNEON, HasFullFP16] 8340 8341 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8342 FPR32Op, FPR32Op, V128, VectorIndexS, 8343 asm, ".s", "", "", ".s", 8344 [(set (f32 FPR32Op:$Rd), 8345 (OpNode (f32 FPR32Op:$Rn), 8346 (f32 (vector_extract (v4f32 V128:$Rm), 8347 VectorIndexS:$idx))))]> { 8348 bits<2> idx; 8349 let Inst{11} = idx{1}; 8350 let Inst{21} = idx{0}; 8351 } 8352 8353 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8354 FPR64Op, FPR64Op, V128, VectorIndexD, 8355 asm, ".d", "", "", ".d", 8356 [(set (f64 FPR64Op:$Rd), 8357 (OpNode (f64 FPR64Op:$Rn), 8358 (f64 (vector_extract (v2f64 V128:$Rm), 8359 VectorIndexD:$idx))))]> { 8360 bits<1> idx; 8361 let Inst{11} = idx{0}; 8362 let Inst{21} = 0; 8363 } 8364} 8365 8366multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8367 let Predicates = [HasNEON, HasFullFP16] in { 8368 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8369 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8370 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8371 VectorIndexH:$idx))), 8372 (!cast<Instruction>(INST # "v8i16_indexed") 8373 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8374 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8375 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8376 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8377 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8378 8379 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8380 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8381 VectorIndexH:$idx))), 8382 (!cast<Instruction>(INST # "v4i16_indexed") 8383 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8384 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8385 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8386 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8387 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8388 8389 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8390 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8391 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8392 V128_lo:$Rm, VectorIndexH:$idx)>; 8393 } // Predicates = [HasNEON, HasFullFP16] 8394 8395 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8396 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8397 (AArch64duplane32 (v4f32 V128:$Rm), 8398 VectorIndexS:$idx))), 8399 (!cast<Instruction>(INST # v2i32_indexed) 8400 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8401 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8402 (AArch64dup (f32 FPR32Op:$Rm)))), 8403 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8404 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8405 8406 8407 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8408 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8409 (AArch64duplane32 (v4f32 V128:$Rm), 8410 VectorIndexS:$idx))), 8411 (!cast<Instruction>(INST # "v4i32_indexed") 8412 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8413 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8414 (AArch64dup (f32 FPR32Op:$Rm)))), 8415 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8416 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8417 8418 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8419 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8420 (AArch64duplane64 (v2f64 V128:$Rm), 8421 VectorIndexD:$idx))), 8422 (!cast<Instruction>(INST # "v2i64_indexed") 8423 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8424 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8425 (AArch64dup (f64 FPR64Op:$Rm)))), 8426 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8427 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8428 8429 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8430 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8431 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8432 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8433 V128:$Rm, VectorIndexS:$idx)>; 8434 8435 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8436 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8437 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8438 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8439 V128:$Rm, VectorIndexD:$idx)>; 8440} 8441 8442let mayRaiseFPException = 1 in 8443multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8444 let Predicates = [HasNEON, HasFullFP16] in { 8445 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8446 V128_lo, VectorIndexH, 8447 asm, ".4h", ".4h", ".4h", ".h", []> { 8448 bits<3> idx; 8449 let Inst{11} = idx{2}; 8450 let Inst{21} = idx{1}; 8451 let Inst{20} = idx{0}; 8452 } 8453 8454 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8455 V128, V128, 8456 V128_lo, VectorIndexH, 8457 asm, ".8h", ".8h", ".8h", ".h", []> { 8458 bits<3> idx; 8459 let Inst{11} = idx{2}; 8460 let Inst{21} = idx{1}; 8461 let Inst{20} = idx{0}; 8462 } 8463 } // Predicates = [HasNEON, HasFullFP16] 8464 8465 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8466 V128, VectorIndexS, 8467 asm, ".2s", ".2s", ".2s", ".s", []> { 8468 bits<2> idx; 8469 let Inst{11} = idx{1}; 8470 let Inst{21} = idx{0}; 8471 } 8472 8473 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8474 V128, V128, 8475 V128, VectorIndexS, 8476 asm, ".4s", ".4s", ".4s", ".s", []> { 8477 bits<2> idx; 8478 let Inst{11} = idx{1}; 8479 let Inst{21} = idx{0}; 8480 } 8481 8482 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8483 V128, V128, 8484 V128, VectorIndexD, 8485 asm, ".2d", ".2d", ".2d", ".d", []> { 8486 bits<1> idx; 8487 let Inst{11} = idx{0}; 8488 let Inst{21} = 0; 8489 } 8490 8491 let Predicates = [HasNEON, HasFullFP16] in { 8492 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8493 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8494 asm, ".h", "", "", ".h", []> { 8495 bits<3> idx; 8496 let Inst{11} = idx{2}; 8497 let Inst{21} = idx{1}; 8498 let Inst{20} = idx{0}; 8499 } 8500 } // Predicates = [HasNEON, HasFullFP16] 8501 8502 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8503 FPR32Op, FPR32Op, V128, VectorIndexS, 8504 asm, ".s", "", "", ".s", []> { 8505 bits<2> idx; 8506 let Inst{11} = idx{1}; 8507 let Inst{21} = idx{0}; 8508 } 8509 8510 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8511 FPR64Op, FPR64Op, V128, VectorIndexD, 8512 asm, ".d", "", "", ".d", []> { 8513 bits<1> idx; 8514 let Inst{11} = idx{0}; 8515 let Inst{21} = 0; 8516 } 8517} 8518 8519multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8520 SDPatternOperator OpNodeLaneQ> { 8521 8522 def : Pat<(v4i16 (OpNodeLane 8523 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8524 VectorIndexS32b:$idx)), 8525 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8526 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8527 (UImmS1XForm $idx))>; 8528 8529 def : Pat<(v4i16 (OpNodeLaneQ 8530 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8531 VectorIndexH32b:$idx)), 8532 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8533 (UImmS1XForm $idx))>; 8534 8535 def : Pat<(v8i16 (OpNodeLane 8536 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8537 VectorIndexS32b:$idx)), 8538 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8539 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8540 (UImmS1XForm $idx))>; 8541 8542 def : Pat<(v8i16 (OpNodeLaneQ 8543 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8544 VectorIndexH32b:$idx)), 8545 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8546 (UImmS1XForm $idx))>; 8547 8548 def : Pat<(v2i32 (OpNodeLane 8549 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8550 VectorIndexD32b:$idx)), 8551 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8552 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8553 (UImmS1XForm $idx))>; 8554 8555 def : Pat<(v2i32 (OpNodeLaneQ 8556 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8557 VectorIndexS32b:$idx)), 8558 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8559 (UImmS1XForm $idx))>; 8560 8561 def : Pat<(v4i32 (OpNodeLane 8562 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8563 VectorIndexD32b:$idx)), 8564 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8565 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8566 (UImmS1XForm $idx))>; 8567 8568 def : Pat<(v4i32 (OpNodeLaneQ 8569 (v4i32 V128:$Rn), 8570 (v4i32 V128:$Rm), 8571 VectorIndexS32b:$idx)), 8572 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8573 (UImmS1XForm $idx))>; 8574 8575} 8576 8577multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8578 SDPatternOperator OpNode> { 8579 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8580 V128_lo, VectorIndexH, 8581 asm, ".4h", ".4h", ".4h", ".h", 8582 [(set (v4i16 V64:$Rd), 8583 (OpNode (v4i16 V64:$Rn), 8584 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8585 bits<3> idx; 8586 let Inst{11} = idx{2}; 8587 let Inst{21} = idx{1}; 8588 let Inst{20} = idx{0}; 8589 } 8590 8591 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8592 V128, V128, 8593 V128_lo, VectorIndexH, 8594 asm, ".8h", ".8h", ".8h", ".h", 8595 [(set (v8i16 V128:$Rd), 8596 (OpNode (v8i16 V128:$Rn), 8597 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8598 bits<3> idx; 8599 let Inst{11} = idx{2}; 8600 let Inst{21} = idx{1}; 8601 let Inst{20} = idx{0}; 8602 } 8603 8604 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8605 V64, V64, 8606 V128, VectorIndexS, 8607 asm, ".2s", ".2s", ".2s", ".s", 8608 [(set (v2i32 V64:$Rd), 8609 (OpNode (v2i32 V64:$Rn), 8610 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8611 bits<2> idx; 8612 let Inst{11} = idx{1}; 8613 let Inst{21} = idx{0}; 8614 } 8615 8616 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8617 V128, V128, 8618 V128, VectorIndexS, 8619 asm, ".4s", ".4s", ".4s", ".s", 8620 [(set (v4i32 V128:$Rd), 8621 (OpNode (v4i32 V128:$Rn), 8622 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8623 bits<2> idx; 8624 let Inst{11} = idx{1}; 8625 let Inst{21} = idx{0}; 8626 } 8627 8628 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8629 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8630 asm, ".h", "", "", ".h", []> { 8631 bits<3> idx; 8632 let Inst{11} = idx{2}; 8633 let Inst{21} = idx{1}; 8634 let Inst{20} = idx{0}; 8635 } 8636 8637 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8638 FPR32Op, FPR32Op, V128, VectorIndexS, 8639 asm, ".s", "", "", ".s", 8640 [(set (i32 FPR32Op:$Rd), 8641 (OpNode FPR32Op:$Rn, 8642 (i32 (vector_extract (v4i32 V128:$Rm), 8643 VectorIndexS:$idx))))]> { 8644 bits<2> idx; 8645 let Inst{11} = idx{1}; 8646 let Inst{21} = idx{0}; 8647 } 8648} 8649 8650multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8651 SDPatternOperator OpNode> { 8652 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8653 V64, V64, 8654 V128_lo, VectorIndexH, 8655 asm, ".4h", ".4h", ".4h", ".h", 8656 [(set (v4i16 V64:$Rd), 8657 (OpNode (v4i16 V64:$Rn), 8658 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8659 bits<3> idx; 8660 let Inst{11} = idx{2}; 8661 let Inst{21} = idx{1}; 8662 let Inst{20} = idx{0}; 8663 } 8664 8665 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8666 V128, V128, 8667 V128_lo, VectorIndexH, 8668 asm, ".8h", ".8h", ".8h", ".h", 8669 [(set (v8i16 V128:$Rd), 8670 (OpNode (v8i16 V128:$Rn), 8671 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8672 bits<3> idx; 8673 let Inst{11} = idx{2}; 8674 let Inst{21} = idx{1}; 8675 let Inst{20} = idx{0}; 8676 } 8677 8678 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8679 V64, V64, 8680 V128, VectorIndexS, 8681 asm, ".2s", ".2s", ".2s", ".s", 8682 [(set (v2i32 V64:$Rd), 8683 (OpNode (v2i32 V64:$Rn), 8684 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8685 bits<2> idx; 8686 let Inst{11} = idx{1}; 8687 let Inst{21} = idx{0}; 8688 } 8689 8690 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8691 V128, V128, 8692 V128, VectorIndexS, 8693 asm, ".4s", ".4s", ".4s", ".s", 8694 [(set (v4i32 V128:$Rd), 8695 (OpNode (v4i32 V128:$Rn), 8696 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8697 bits<2> idx; 8698 let Inst{11} = idx{1}; 8699 let Inst{21} = idx{0}; 8700 } 8701} 8702 8703multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8704 SDPatternOperator OpNode> { 8705 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8706 V128_lo, VectorIndexH, 8707 asm, ".4h", ".4h", ".4h", ".h", 8708 [(set (v4i16 V64:$dst), 8709 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8710 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8711 bits<3> idx; 8712 let Inst{11} = idx{2}; 8713 let Inst{21} = idx{1}; 8714 let Inst{20} = idx{0}; 8715 } 8716 8717 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8718 V128, V128, 8719 V128_lo, VectorIndexH, 8720 asm, ".8h", ".8h", ".8h", ".h", 8721 [(set (v8i16 V128:$dst), 8722 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8723 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8724 bits<3> idx; 8725 let Inst{11} = idx{2}; 8726 let Inst{21} = idx{1}; 8727 let Inst{20} = idx{0}; 8728 } 8729 8730 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8731 V64, V64, 8732 V128, VectorIndexS, 8733 asm, ".2s", ".2s", ".2s", ".s", 8734 [(set (v2i32 V64:$dst), 8735 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8736 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8737 bits<2> idx; 8738 let Inst{11} = idx{1}; 8739 let Inst{21} = idx{0}; 8740 } 8741 8742 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8743 V128, V128, 8744 V128, VectorIndexS, 8745 asm, ".4s", ".4s", ".4s", ".s", 8746 [(set (v4i32 V128:$dst), 8747 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8748 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8749 bits<2> idx; 8750 let Inst{11} = idx{1}; 8751 let Inst{21} = idx{0}; 8752 } 8753} 8754 8755multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8756 SDPatternOperator OpNode> { 8757 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8758 V128, V64, 8759 V128_lo, VectorIndexH, 8760 asm, ".4s", ".4s", ".4h", ".h", 8761 [(set (v4i32 V128:$Rd), 8762 (OpNode (v4i16 V64:$Rn), 8763 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8764 bits<3> idx; 8765 let Inst{11} = idx{2}; 8766 let Inst{21} = idx{1}; 8767 let Inst{20} = idx{0}; 8768 } 8769 8770 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8771 V128, V128, 8772 V128_lo, VectorIndexH, 8773 asm#"2", ".4s", ".4s", ".8h", ".h", 8774 [(set (v4i32 V128:$Rd), 8775 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 8776 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8777 8778 bits<3> idx; 8779 let Inst{11} = idx{2}; 8780 let Inst{21} = idx{1}; 8781 let Inst{20} = idx{0}; 8782 } 8783 8784 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8785 V128, V64, 8786 V128, VectorIndexS, 8787 asm, ".2d", ".2d", ".2s", ".s", 8788 [(set (v2i64 V128:$Rd), 8789 (OpNode (v2i32 V64:$Rn), 8790 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8791 bits<2> idx; 8792 let Inst{11} = idx{1}; 8793 let Inst{21} = idx{0}; 8794 } 8795 8796 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8797 V128, V128, 8798 V128, VectorIndexS, 8799 asm#"2", ".2d", ".2d", ".4s", ".s", 8800 [(set (v2i64 V128:$Rd), 8801 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 8802 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8803 bits<2> idx; 8804 let Inst{11} = idx{1}; 8805 let Inst{21} = idx{0}; 8806 } 8807 8808 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8809 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8810 asm, ".h", "", "", ".h", []> { 8811 bits<3> idx; 8812 let Inst{11} = idx{2}; 8813 let Inst{21} = idx{1}; 8814 let Inst{20} = idx{0}; 8815 } 8816 8817 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8818 FPR64Op, FPR32Op, V128, VectorIndexS, 8819 asm, ".s", "", "", ".s", []> { 8820 bits<2> idx; 8821 let Inst{11} = idx{1}; 8822 let Inst{21} = idx{0}; 8823 } 8824} 8825 8826multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8827 SDPatternOperator Accum> { 8828 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8829 V128, V64, 8830 V128_lo, VectorIndexH, 8831 asm, ".4s", ".4s", ".4h", ".h", 8832 [(set (v4i32 V128:$dst), 8833 (Accum (v4i32 V128:$Rd), 8834 (v4i32 (int_aarch64_neon_sqdmull 8835 (v4i16 V64:$Rn), 8836 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8837 VectorIndexH:$idx))))))]> { 8838 bits<3> idx; 8839 let Inst{11} = idx{2}; 8840 let Inst{21} = idx{1}; 8841 let Inst{20} = idx{0}; 8842 } 8843 8844 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8845 // intermediate EXTRACT_SUBREG would be untyped. 8846 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8847 (i32 (vector_extract (v4i32 8848 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8849 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8850 VectorIndexH:$idx)))), 8851 (i64 0))))), 8852 (EXTRACT_SUBREG 8853 (!cast<Instruction>(NAME # v4i16_indexed) 8854 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8855 V128_lo:$Rm, VectorIndexH:$idx), 8856 ssub)>; 8857 8858 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8859 V128, V128, 8860 V128_lo, VectorIndexH, 8861 asm#"2", ".4s", ".4s", ".8h", ".h", 8862 [(set (v4i32 V128:$dst), 8863 (Accum (v4i32 V128:$Rd), 8864 (v4i32 (int_aarch64_neon_sqdmull 8865 (extract_high_v8i16 (v8i16 V128:$Rn)), 8866 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 8867 bits<3> idx; 8868 let Inst{11} = idx{2}; 8869 let Inst{21} = idx{1}; 8870 let Inst{20} = idx{0}; 8871 } 8872 8873 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8874 V128, V64, 8875 V128, VectorIndexS, 8876 asm, ".2d", ".2d", ".2s", ".s", 8877 [(set (v2i64 V128:$dst), 8878 (Accum (v2i64 V128:$Rd), 8879 (v2i64 (int_aarch64_neon_sqdmull 8880 (v2i32 V64:$Rn), 8881 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8882 VectorIndexS:$idx))))))]> { 8883 bits<2> idx; 8884 let Inst{11} = idx{1}; 8885 let Inst{21} = idx{0}; 8886 } 8887 8888 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8889 V128, V128, 8890 V128, VectorIndexS, 8891 asm#"2", ".2d", ".2d", ".4s", ".s", 8892 [(set (v2i64 V128:$dst), 8893 (Accum (v2i64 V128:$Rd), 8894 (v2i64 (int_aarch64_neon_sqdmull 8895 (extract_high_v4i32 (v4i32 V128:$Rn)), 8896 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 8897 bits<2> idx; 8898 let Inst{11} = idx{1}; 8899 let Inst{21} = idx{0}; 8900 } 8901 8902 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8903 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8904 asm, ".h", "", "", ".h", []> { 8905 bits<3> idx; 8906 let Inst{11} = idx{2}; 8907 let Inst{21} = idx{1}; 8908 let Inst{20} = idx{0}; 8909 } 8910 8911 8912 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8913 FPR64Op, FPR32Op, V128, VectorIndexS, 8914 asm, ".s", "", "", ".s", 8915 [(set (i64 FPR64Op:$dst), 8916 (Accum (i64 FPR64Op:$Rd), 8917 (i64 (int_aarch64_neon_sqdmulls_scalar 8918 (i32 FPR32Op:$Rn), 8919 (i32 (vector_extract (v4i32 V128:$Rm), 8920 VectorIndexS:$idx))))))]> { 8921 8922 bits<2> idx; 8923 let Inst{11} = idx{1}; 8924 let Inst{21} = idx{0}; 8925 } 8926} 8927 8928multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8929 SDPatternOperator OpNode> { 8930 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8931 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8932 V128, V64, 8933 V128_lo, VectorIndexH, 8934 asm, ".4s", ".4s", ".4h", ".h", 8935 [(set (v4i32 V128:$Rd), 8936 (OpNode (v4i16 V64:$Rn), 8937 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8938 bits<3> idx; 8939 let Inst{11} = idx{2}; 8940 let Inst{21} = idx{1}; 8941 let Inst{20} = idx{0}; 8942 } 8943 8944 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8945 V128, V128, 8946 V128_lo, VectorIndexH, 8947 asm#"2", ".4s", ".4s", ".8h", ".h", 8948 [(set (v4i32 V128:$Rd), 8949 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 8950 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8951 8952 bits<3> idx; 8953 let Inst{11} = idx{2}; 8954 let Inst{21} = idx{1}; 8955 let Inst{20} = idx{0}; 8956 } 8957 8958 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8959 V128, V64, 8960 V128, VectorIndexS, 8961 asm, ".2d", ".2d", ".2s", ".s", 8962 [(set (v2i64 V128:$Rd), 8963 (OpNode (v2i32 V64:$Rn), 8964 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8965 bits<2> idx; 8966 let Inst{11} = idx{1}; 8967 let Inst{21} = idx{0}; 8968 } 8969 8970 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8971 V128, V128, 8972 V128, VectorIndexS, 8973 asm#"2", ".2d", ".2d", ".4s", ".s", 8974 [(set (v2i64 V128:$Rd), 8975 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 8976 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8977 bits<2> idx; 8978 let Inst{11} = idx{1}; 8979 let Inst{21} = idx{0}; 8980 } 8981 } 8982} 8983 8984multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8985 SDPatternOperator OpNode> { 8986 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8987 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8988 V128, V64, 8989 V128_lo, VectorIndexH, 8990 asm, ".4s", ".4s", ".4h", ".h", 8991 [(set (v4i32 V128:$dst), 8992 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8993 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8994 bits<3> idx; 8995 let Inst{11} = idx{2}; 8996 let Inst{21} = idx{1}; 8997 let Inst{20} = idx{0}; 8998 } 8999 9000 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9001 V128, V128, 9002 V128_lo, VectorIndexH, 9003 asm#"2", ".4s", ".4s", ".8h", ".h", 9004 [(set (v4i32 V128:$dst), 9005 (OpNode (v4i32 V128:$Rd), 9006 (extract_high_v8i16 (v8i16 V128:$Rn)), 9007 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9008 bits<3> idx; 9009 let Inst{11} = idx{2}; 9010 let Inst{21} = idx{1}; 9011 let Inst{20} = idx{0}; 9012 } 9013 9014 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9015 V128, V64, 9016 V128, VectorIndexS, 9017 asm, ".2d", ".2d", ".2s", ".s", 9018 [(set (v2i64 V128:$dst), 9019 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9020 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9021 bits<2> idx; 9022 let Inst{11} = idx{1}; 9023 let Inst{21} = idx{0}; 9024 } 9025 9026 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9027 V128, V128, 9028 V128, VectorIndexS, 9029 asm#"2", ".2d", ".2d", ".4s", ".s", 9030 [(set (v2i64 V128:$dst), 9031 (OpNode (v2i64 V128:$Rd), 9032 (extract_high_v4i32 (v4i32 V128:$Rn)), 9033 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9034 bits<2> idx; 9035 let Inst{11} = idx{1}; 9036 let Inst{21} = idx{0}; 9037 } 9038 } 9039} 9040 9041//---------------------------------------------------------------------------- 9042// AdvSIMD scalar shift by immediate 9043//---------------------------------------------------------------------------- 9044 9045let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9046class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9047 RegisterClass regtype1, RegisterClass regtype2, 9048 Operand immtype, string asm, list<dag> pattern> 9049 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9050 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9051 Sched<[WriteVd]> { 9052 bits<5> Rd; 9053 bits<5> Rn; 9054 bits<7> imm; 9055 let Inst{31-30} = 0b01; 9056 let Inst{29} = U; 9057 let Inst{28-23} = 0b111110; 9058 let Inst{22-16} = fixed_imm; 9059 let Inst{15-11} = opc; 9060 let Inst{10} = 1; 9061 let Inst{9-5} = Rn; 9062 let Inst{4-0} = Rd; 9063} 9064 9065let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9066class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9067 RegisterClass regtype1, RegisterClass regtype2, 9068 Operand immtype, string asm, list<dag> pattern> 9069 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9070 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9071 Sched<[WriteVd]> { 9072 bits<5> Rd; 9073 bits<5> Rn; 9074 bits<7> imm; 9075 let Inst{31-30} = 0b01; 9076 let Inst{29} = U; 9077 let Inst{28-23} = 0b111110; 9078 let Inst{22-16} = fixed_imm; 9079 let Inst{15-11} = opc; 9080 let Inst{10} = 1; 9081 let Inst{9-5} = Rn; 9082 let Inst{4-0} = Rd; 9083} 9084 9085 9086multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9087 let Predicates = [HasNEON, HasFullFP16] in { 9088 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9089 FPR16, FPR16, vecshiftR16, asm, []> { 9090 let Inst{19-16} = imm{3-0}; 9091 } 9092 } // Predicates = [HasNEON, HasFullFP16] 9093 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9094 FPR32, FPR32, vecshiftR32, asm, []> { 9095 let Inst{20-16} = imm{4-0}; 9096 } 9097 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9098 FPR64, FPR64, vecshiftR64, asm, []> { 9099 let Inst{21-16} = imm{5-0}; 9100 } 9101} 9102 9103multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9104 SDPatternOperator OpNode> { 9105 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9106 FPR64, FPR64, vecshiftR64, asm, 9107 [(set (i64 FPR64:$Rd), 9108 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9109 let Inst{21-16} = imm{5-0}; 9110 } 9111 9112 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9113 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9114} 9115 9116multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9117 SDPatternOperator OpNode = null_frag> { 9118 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9119 FPR64, FPR64, vecshiftR64, asm, 9120 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9121 (i32 vecshiftR64:$imm)))]> { 9122 let Inst{21-16} = imm{5-0}; 9123 } 9124 9125 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9126 (i32 vecshiftR64:$imm))), 9127 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9128 vecshiftR64:$imm)>; 9129} 9130 9131multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9132 SDPatternOperator OpNode> { 9133 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9134 FPR64, FPR64, vecshiftL64, asm, 9135 [(set (i64 FPR64:$Rd), 9136 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9137 let Inst{21-16} = imm{5-0}; 9138 } 9139 9140 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9141 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9142} 9143 9144let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9145multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9146 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9147 FPR64, FPR64, vecshiftL64, asm, []> { 9148 let Inst{21-16} = imm{5-0}; 9149 } 9150} 9151 9152let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9153multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9154 SDPatternOperator OpNode = null_frag> { 9155 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9156 FPR8, FPR16, vecshiftR8, asm, []> { 9157 let Inst{18-16} = imm{2-0}; 9158 } 9159 9160 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9161 FPR16, FPR32, vecshiftR16, asm, []> { 9162 let Inst{19-16} = imm{3-0}; 9163 } 9164 9165 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9166 FPR32, FPR64, vecshiftR32, asm, 9167 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9168 let Inst{20-16} = imm{4-0}; 9169 } 9170} 9171 9172multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9173 SDPatternOperator OpNode> { 9174 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9175 FPR8, FPR8, vecshiftL8, asm, []> { 9176 let Inst{18-16} = imm{2-0}; 9177 } 9178 9179 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9180 FPR16, FPR16, vecshiftL16, asm, []> { 9181 let Inst{19-16} = imm{3-0}; 9182 } 9183 9184 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9185 FPR32, FPR32, vecshiftL32, asm, 9186 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9187 let Inst{20-16} = imm{4-0}; 9188 } 9189 9190 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9191 FPR64, FPR64, vecshiftL64, asm, 9192 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9193 let Inst{21-16} = imm{5-0}; 9194 } 9195 9196 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9197 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9198} 9199 9200multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9201 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9202 FPR8, FPR8, vecshiftR8, asm, []> { 9203 let Inst{18-16} = imm{2-0}; 9204 } 9205 9206 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9207 FPR16, FPR16, vecshiftR16, asm, []> { 9208 let Inst{19-16} = imm{3-0}; 9209 } 9210 9211 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9212 FPR32, FPR32, vecshiftR32, asm, []> { 9213 let Inst{20-16} = imm{4-0}; 9214 } 9215 9216 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9217 FPR64, FPR64, vecshiftR64, asm, []> { 9218 let Inst{21-16} = imm{5-0}; 9219 } 9220} 9221 9222//---------------------------------------------------------------------------- 9223// AdvSIMD vector x indexed element 9224//---------------------------------------------------------------------------- 9225 9226let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9227class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9228 RegisterOperand dst_reg, RegisterOperand src_reg, 9229 Operand immtype, 9230 string asm, string dst_kind, string src_kind, 9231 list<dag> pattern> 9232 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9233 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9234 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9235 Sched<[!if(Q, WriteVq, WriteVd)]> { 9236 bits<5> Rd; 9237 bits<5> Rn; 9238 let Inst{31} = 0; 9239 let Inst{30} = Q; 9240 let Inst{29} = U; 9241 let Inst{28-23} = 0b011110; 9242 let Inst{22-16} = fixed_imm; 9243 let Inst{15-11} = opc; 9244 let Inst{10} = 1; 9245 let Inst{9-5} = Rn; 9246 let Inst{4-0} = Rd; 9247} 9248 9249let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9250class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9251 RegisterOperand vectype1, RegisterOperand vectype2, 9252 Operand immtype, 9253 string asm, string dst_kind, string src_kind, 9254 list<dag> pattern> 9255 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9256 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9257 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9258 Sched<[!if(Q, WriteVq, WriteVd)]> { 9259 bits<5> Rd; 9260 bits<5> Rn; 9261 let Inst{31} = 0; 9262 let Inst{30} = Q; 9263 let Inst{29} = U; 9264 let Inst{28-23} = 0b011110; 9265 let Inst{22-16} = fixed_imm; 9266 let Inst{15-11} = opc; 9267 let Inst{10} = 1; 9268 let Inst{9-5} = Rn; 9269 let Inst{4-0} = Rd; 9270} 9271 9272multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9273 Intrinsic OpNode> { 9274 let Predicates = [HasNEON, HasFullFP16] in { 9275 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9276 V64, V64, vecshiftR16, 9277 asm, ".4h", ".4h", 9278 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9279 bits<4> imm; 9280 let Inst{19-16} = imm; 9281 } 9282 9283 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9284 V128, V128, vecshiftR16, 9285 asm, ".8h", ".8h", 9286 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9287 bits<4> imm; 9288 let Inst{19-16} = imm; 9289 } 9290 } // Predicates = [HasNEON, HasFullFP16] 9291 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9292 V64, V64, vecshiftR32, 9293 asm, ".2s", ".2s", 9294 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9295 bits<5> imm; 9296 let Inst{20-16} = imm; 9297 } 9298 9299 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9300 V128, V128, vecshiftR32, 9301 asm, ".4s", ".4s", 9302 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9303 bits<5> imm; 9304 let Inst{20-16} = imm; 9305 } 9306 9307 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9308 V128, V128, vecshiftR64, 9309 asm, ".2d", ".2d", 9310 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9311 bits<6> imm; 9312 let Inst{21-16} = imm; 9313 } 9314} 9315 9316multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9317 Intrinsic OpNode> { 9318 let Predicates = [HasNEON, HasFullFP16] in { 9319 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9320 V64, V64, vecshiftR16, 9321 asm, ".4h", ".4h", 9322 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9323 bits<4> imm; 9324 let Inst{19-16} = imm; 9325 } 9326 9327 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9328 V128, V128, vecshiftR16, 9329 asm, ".8h", ".8h", 9330 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9331 bits<4> imm; 9332 let Inst{19-16} = imm; 9333 } 9334 } // Predicates = [HasNEON, HasFullFP16] 9335 9336 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9337 V64, V64, vecshiftR32, 9338 asm, ".2s", ".2s", 9339 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9340 bits<5> imm; 9341 let Inst{20-16} = imm; 9342 } 9343 9344 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9345 V128, V128, vecshiftR32, 9346 asm, ".4s", ".4s", 9347 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9348 bits<5> imm; 9349 let Inst{20-16} = imm; 9350 } 9351 9352 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9353 V128, V128, vecshiftR64, 9354 asm, ".2d", ".2d", 9355 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9356 bits<6> imm; 9357 let Inst{21-16} = imm; 9358 } 9359} 9360 9361multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9362 SDPatternOperator OpNode> { 9363 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9364 V64, V128, vecshiftR16Narrow, 9365 asm, ".8b", ".8h", 9366 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9367 bits<3> imm; 9368 let Inst{18-16} = imm; 9369 } 9370 9371 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9372 V128, V128, vecshiftR16Narrow, 9373 asm#"2", ".16b", ".8h", []> { 9374 bits<3> imm; 9375 let Inst{18-16} = imm; 9376 let hasSideEffects = 0; 9377 } 9378 9379 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9380 V64, V128, vecshiftR32Narrow, 9381 asm, ".4h", ".4s", 9382 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9383 bits<4> imm; 9384 let Inst{19-16} = imm; 9385 } 9386 9387 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9388 V128, V128, vecshiftR32Narrow, 9389 asm#"2", ".8h", ".4s", []> { 9390 bits<4> imm; 9391 let Inst{19-16} = imm; 9392 let hasSideEffects = 0; 9393 } 9394 9395 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9396 V64, V128, vecshiftR64Narrow, 9397 asm, ".2s", ".2d", 9398 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9399 bits<5> imm; 9400 let Inst{20-16} = imm; 9401 } 9402 9403 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9404 V128, V128, vecshiftR64Narrow, 9405 asm#"2", ".4s", ".2d", []> { 9406 bits<5> imm; 9407 let Inst{20-16} = imm; 9408 let hasSideEffects = 0; 9409 } 9410 9411 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9412 // themselves, so put them here instead. 9413 9414 // Patterns involving what's effectively an insert high and a normal 9415 // intrinsic, represented by CONCAT_VECTORS. 9416 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9417 vecshiftR16Narrow:$imm)), 9418 (!cast<Instruction>(NAME # "v16i8_shift") 9419 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9420 V128:$Rn, vecshiftR16Narrow:$imm)>; 9421 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9422 vecshiftR32Narrow:$imm)), 9423 (!cast<Instruction>(NAME # "v8i16_shift") 9424 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9425 V128:$Rn, vecshiftR32Narrow:$imm)>; 9426 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9427 vecshiftR64Narrow:$imm)), 9428 (!cast<Instruction>(NAME # "v4i32_shift") 9429 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9430 V128:$Rn, vecshiftR64Narrow:$imm)>; 9431} 9432 9433multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9434 SDPatternOperator OpNode> { 9435 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9436 V64, V64, vecshiftL8, 9437 asm, ".8b", ".8b", 9438 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9439 (i32 vecshiftL8:$imm)))]> { 9440 bits<3> imm; 9441 let Inst{18-16} = imm; 9442 } 9443 9444 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9445 V128, V128, vecshiftL8, 9446 asm, ".16b", ".16b", 9447 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9448 (i32 vecshiftL8:$imm)))]> { 9449 bits<3> imm; 9450 let Inst{18-16} = imm; 9451 } 9452 9453 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9454 V64, V64, vecshiftL16, 9455 asm, ".4h", ".4h", 9456 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9457 (i32 vecshiftL16:$imm)))]> { 9458 bits<4> imm; 9459 let Inst{19-16} = imm; 9460 } 9461 9462 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9463 V128, V128, vecshiftL16, 9464 asm, ".8h", ".8h", 9465 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9466 (i32 vecshiftL16:$imm)))]> { 9467 bits<4> imm; 9468 let Inst{19-16} = imm; 9469 } 9470 9471 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9472 V64, V64, vecshiftL32, 9473 asm, ".2s", ".2s", 9474 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9475 (i32 vecshiftL32:$imm)))]> { 9476 bits<5> imm; 9477 let Inst{20-16} = imm; 9478 } 9479 9480 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9481 V128, V128, vecshiftL32, 9482 asm, ".4s", ".4s", 9483 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9484 (i32 vecshiftL32:$imm)))]> { 9485 bits<5> imm; 9486 let Inst{20-16} = imm; 9487 } 9488 9489 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9490 V128, V128, vecshiftL64, 9491 asm, ".2d", ".2d", 9492 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9493 (i32 vecshiftL64:$imm)))]> { 9494 bits<6> imm; 9495 let Inst{21-16} = imm; 9496 } 9497} 9498 9499multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9500 SDPatternOperator OpNode> { 9501 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9502 V64, V64, vecshiftR8, 9503 asm, ".8b", ".8b", 9504 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9505 (i32 vecshiftR8:$imm)))]> { 9506 bits<3> imm; 9507 let Inst{18-16} = imm; 9508 } 9509 9510 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9511 V128, V128, vecshiftR8, 9512 asm, ".16b", ".16b", 9513 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9514 (i32 vecshiftR8:$imm)))]> { 9515 bits<3> imm; 9516 let Inst{18-16} = imm; 9517 } 9518 9519 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9520 V64, V64, vecshiftR16, 9521 asm, ".4h", ".4h", 9522 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9523 (i32 vecshiftR16:$imm)))]> { 9524 bits<4> imm; 9525 let Inst{19-16} = imm; 9526 } 9527 9528 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9529 V128, V128, vecshiftR16, 9530 asm, ".8h", ".8h", 9531 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9532 (i32 vecshiftR16:$imm)))]> { 9533 bits<4> imm; 9534 let Inst{19-16} = imm; 9535 } 9536 9537 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9538 V64, V64, vecshiftR32, 9539 asm, ".2s", ".2s", 9540 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9541 (i32 vecshiftR32:$imm)))]> { 9542 bits<5> imm; 9543 let Inst{20-16} = imm; 9544 } 9545 9546 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9547 V128, V128, vecshiftR32, 9548 asm, ".4s", ".4s", 9549 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9550 (i32 vecshiftR32:$imm)))]> { 9551 bits<5> imm; 9552 let Inst{20-16} = imm; 9553 } 9554 9555 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9556 V128, V128, vecshiftR64, 9557 asm, ".2d", ".2d", 9558 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9559 (i32 vecshiftR64:$imm)))]> { 9560 bits<6> imm; 9561 let Inst{21-16} = imm; 9562 } 9563} 9564 9565let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9566multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9567 SDPatternOperator OpNode = null_frag> { 9568 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9569 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9570 [(set (v8i8 V64:$dst), 9571 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9572 (i32 vecshiftR8:$imm)))]> { 9573 bits<3> imm; 9574 let Inst{18-16} = imm; 9575 } 9576 9577 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9578 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9579 [(set (v16i8 V128:$dst), 9580 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9581 (i32 vecshiftR8:$imm)))]> { 9582 bits<3> imm; 9583 let Inst{18-16} = imm; 9584 } 9585 9586 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9587 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9588 [(set (v4i16 V64:$dst), 9589 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9590 (i32 vecshiftR16:$imm)))]> { 9591 bits<4> imm; 9592 let Inst{19-16} = imm; 9593 } 9594 9595 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9596 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9597 [(set (v8i16 V128:$dst), 9598 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9599 (i32 vecshiftR16:$imm)))]> { 9600 bits<4> imm; 9601 let Inst{19-16} = imm; 9602 } 9603 9604 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9605 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9606 [(set (v2i32 V64:$dst), 9607 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9608 (i32 vecshiftR32:$imm)))]> { 9609 bits<5> imm; 9610 let Inst{20-16} = imm; 9611 } 9612 9613 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9614 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9615 [(set (v4i32 V128:$dst), 9616 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9617 (i32 vecshiftR32:$imm)))]> { 9618 bits<5> imm; 9619 let Inst{20-16} = imm; 9620 } 9621 9622 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9623 V128, V128, vecshiftR64, 9624 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9625 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9626 (i32 vecshiftR64:$imm)))]> { 9627 bits<6> imm; 9628 let Inst{21-16} = imm; 9629 } 9630} 9631 9632multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9633 SDPatternOperator OpNode = null_frag> { 9634 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9635 V64, V64, vecshiftL8, 9636 asm, ".8b", ".8b", 9637 [(set (v8i8 V64:$dst), 9638 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9639 (i32 vecshiftL8:$imm)))]> { 9640 bits<3> imm; 9641 let Inst{18-16} = imm; 9642 } 9643 9644 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9645 V128, V128, vecshiftL8, 9646 asm, ".16b", ".16b", 9647 [(set (v16i8 V128:$dst), 9648 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9649 (i32 vecshiftL8:$imm)))]> { 9650 bits<3> imm; 9651 let Inst{18-16} = imm; 9652 } 9653 9654 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9655 V64, V64, vecshiftL16, 9656 asm, ".4h", ".4h", 9657 [(set (v4i16 V64:$dst), 9658 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9659 (i32 vecshiftL16:$imm)))]> { 9660 bits<4> imm; 9661 let Inst{19-16} = imm; 9662 } 9663 9664 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9665 V128, V128, vecshiftL16, 9666 asm, ".8h", ".8h", 9667 [(set (v8i16 V128:$dst), 9668 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9669 (i32 vecshiftL16:$imm)))]> { 9670 bits<4> imm; 9671 let Inst{19-16} = imm; 9672 } 9673 9674 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9675 V64, V64, vecshiftL32, 9676 asm, ".2s", ".2s", 9677 [(set (v2i32 V64:$dst), 9678 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9679 (i32 vecshiftL32:$imm)))]> { 9680 bits<5> imm; 9681 let Inst{20-16} = imm; 9682 } 9683 9684 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9685 V128, V128, vecshiftL32, 9686 asm, ".4s", ".4s", 9687 [(set (v4i32 V128:$dst), 9688 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9689 (i32 vecshiftL32:$imm)))]> { 9690 bits<5> imm; 9691 let Inst{20-16} = imm; 9692 } 9693 9694 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9695 V128, V128, vecshiftL64, 9696 asm, ".2d", ".2d", 9697 [(set (v2i64 V128:$dst), 9698 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9699 (i32 vecshiftL64:$imm)))]> { 9700 bits<6> imm; 9701 let Inst{21-16} = imm; 9702 } 9703} 9704 9705multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9706 SDPatternOperator OpNode> { 9707 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9708 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9709 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9710 bits<3> imm; 9711 let Inst{18-16} = imm; 9712 } 9713 9714 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9715 V128, V128, vecshiftL8, 9716 asm#"2", ".8h", ".16b", 9717 [(set (v8i16 V128:$Rd), 9718 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 9719 bits<3> imm; 9720 let Inst{18-16} = imm; 9721 } 9722 9723 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9724 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9725 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9726 bits<4> imm; 9727 let Inst{19-16} = imm; 9728 } 9729 9730 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9731 V128, V128, vecshiftL16, 9732 asm#"2", ".4s", ".8h", 9733 [(set (v4i32 V128:$Rd), 9734 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 9735 9736 bits<4> imm; 9737 let Inst{19-16} = imm; 9738 } 9739 9740 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9741 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9742 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9743 bits<5> imm; 9744 let Inst{20-16} = imm; 9745 } 9746 9747 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9748 V128, V128, vecshiftL32, 9749 asm#"2", ".2d", ".4s", 9750 [(set (v2i64 V128:$Rd), 9751 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 9752 bits<5> imm; 9753 let Inst{20-16} = imm; 9754 } 9755} 9756 9757 9758//--- 9759// Vector load/store 9760//--- 9761// SIMD ldX/stX no-index memory references don't allow the optional 9762// ", #0" constant and handle post-indexing explicitly, so we use 9763// a more specialized parse method for them. Otherwise, it's the same as 9764// the general GPR64sp handling. 9765 9766class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9767 string asm, dag oops, dag iops, list<dag> pattern> 9768 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9769 bits<5> Vt; 9770 bits<5> Rn; 9771 let Inst{31} = 0; 9772 let Inst{30} = Q; 9773 let Inst{29-23} = 0b0011000; 9774 let Inst{22} = L; 9775 let Inst{21-16} = 0b000000; 9776 let Inst{15-12} = opcode; 9777 let Inst{11-10} = size; 9778 let Inst{9-5} = Rn; 9779 let Inst{4-0} = Vt; 9780} 9781 9782class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9783 string asm, dag oops, dag iops> 9784 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9785 bits<5> Vt; 9786 bits<5> Rn; 9787 bits<5> Xm; 9788 let Inst{31} = 0; 9789 let Inst{30} = Q; 9790 let Inst{29-23} = 0b0011001; 9791 let Inst{22} = L; 9792 let Inst{21} = 0; 9793 let Inst{20-16} = Xm; 9794 let Inst{15-12} = opcode; 9795 let Inst{11-10} = size; 9796 let Inst{9-5} = Rn; 9797 let Inst{4-0} = Vt; 9798} 9799 9800// The immediate form of AdvSIMD post-indexed addressing is encoded with 9801// register post-index addressing from the zero register. 9802multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9803 int Offset, int Size> { 9804 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9805 // "ld1\t$Vt, [$Rn], #16" 9806 // may get mapped to 9807 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9808 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9809 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9810 GPR64sp:$Rn, 9811 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9812 XZR), 1>; 9813 9814 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9815 // "ld1.8b\t$Vt, [$Rn], #16" 9816 // may get mapped to 9817 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9818 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9819 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9820 GPR64sp:$Rn, 9821 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9822 XZR), 0>; 9823 9824 // E.g. "ld1.8b { v0, v1 }, [x1]" 9825 // "ld1\t$Vt, [$Rn]" 9826 // may get mapped to 9827 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9828 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9829 (!cast<Instruction>(BaseName # Count # "v" # layout) 9830 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9831 GPR64sp:$Rn), 0>; 9832 9833 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9834 // "ld1\t$Vt, [$Rn], $Xm" 9835 // may get mapped to 9836 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9837 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9838 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9839 GPR64sp:$Rn, 9840 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9841 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9842} 9843 9844multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9845 int Offset128, int Offset64, bits<4> opcode> { 9846 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9847 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9848 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9849 (ins GPR64sp:$Rn), []>; 9850 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9851 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9852 (ins GPR64sp:$Rn), []>; 9853 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9854 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9855 (ins GPR64sp:$Rn), []>; 9856 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9857 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9858 (ins GPR64sp:$Rn), []>; 9859 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9860 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9861 (ins GPR64sp:$Rn), []>; 9862 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9863 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9864 (ins GPR64sp:$Rn), []>; 9865 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9866 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9867 (ins GPR64sp:$Rn), []>; 9868 9869 9870 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9871 (outs GPR64sp:$wback, 9872 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9873 (ins GPR64sp:$Rn, 9874 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9875 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9876 (outs GPR64sp:$wback, 9877 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9878 (ins GPR64sp:$Rn, 9879 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9880 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9881 (outs GPR64sp:$wback, 9882 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9883 (ins GPR64sp:$Rn, 9884 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9885 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9886 (outs GPR64sp:$wback, 9887 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9888 (ins GPR64sp:$Rn, 9889 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9890 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9891 (outs GPR64sp:$wback, 9892 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9893 (ins GPR64sp:$Rn, 9894 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9895 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9896 (outs GPR64sp:$wback, 9897 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9898 (ins GPR64sp:$Rn, 9899 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9900 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9901 (outs GPR64sp:$wback, 9902 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9903 (ins GPR64sp:$Rn, 9904 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9905 } 9906 9907 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9908 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9909 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9910 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9911 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9912 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9913 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9914} 9915 9916// Only ld1/st1 has a v1d version. 9917multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9918 int Offset128, int Offset64, bits<4> opcode> { 9919 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9920 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9921 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9922 GPR64sp:$Rn), []>; 9923 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9924 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9925 GPR64sp:$Rn), []>; 9926 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9927 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9928 GPR64sp:$Rn), []>; 9929 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9930 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9931 GPR64sp:$Rn), []>; 9932 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9933 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9934 GPR64sp:$Rn), []>; 9935 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9936 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9937 GPR64sp:$Rn), []>; 9938 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9939 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9940 GPR64sp:$Rn), []>; 9941 9942 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9943 (outs GPR64sp:$wback), 9944 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9945 GPR64sp:$Rn, 9946 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9947 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9948 (outs GPR64sp:$wback), 9949 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9950 GPR64sp:$Rn, 9951 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9952 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9953 (outs GPR64sp:$wback), 9954 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9955 GPR64sp:$Rn, 9956 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9957 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9958 (outs GPR64sp:$wback), 9959 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9960 GPR64sp:$Rn, 9961 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9962 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9963 (outs GPR64sp:$wback), 9964 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9965 GPR64sp:$Rn, 9966 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9967 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9968 (outs GPR64sp:$wback), 9969 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9970 GPR64sp:$Rn, 9971 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9972 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9973 (outs GPR64sp:$wback), 9974 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9975 GPR64sp:$Rn, 9976 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9977 } 9978 9979 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9980 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9981 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9982 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9983 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9984 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9985 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9986} 9987 9988multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9989 int Offset128, int Offset64, bits<4> opcode> 9990 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9991 9992 // LD1 instructions have extra "1d" variants. 9993 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9994 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9995 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9996 (ins GPR64sp:$Rn), []>; 9997 9998 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9999 (outs GPR64sp:$wback, 10000 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10001 (ins GPR64sp:$Rn, 10002 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10003 } 10004 10005 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10006} 10007 10008multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10009 int Offset128, int Offset64, bits<4> opcode> 10010 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10011 10012 // ST1 instructions have extra "1d" variants. 10013 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10014 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10015 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10016 GPR64sp:$Rn), []>; 10017 10018 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10019 (outs GPR64sp:$wback), 10020 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10021 GPR64sp:$Rn, 10022 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10023 } 10024 10025 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10026} 10027 10028multiclass SIMDLd1Multiple<string asm> { 10029 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10030 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10031 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10032 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10033} 10034 10035multiclass SIMDSt1Multiple<string asm> { 10036 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10037 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10038 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10039 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10040} 10041 10042multiclass SIMDLd2Multiple<string asm> { 10043 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10044} 10045 10046multiclass SIMDSt2Multiple<string asm> { 10047 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10048} 10049 10050multiclass SIMDLd3Multiple<string asm> { 10051 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10052} 10053 10054multiclass SIMDSt3Multiple<string asm> { 10055 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10056} 10057 10058multiclass SIMDLd4Multiple<string asm> { 10059 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10060} 10061 10062multiclass SIMDSt4Multiple<string asm> { 10063 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10064} 10065 10066//--- 10067// AdvSIMD Load/store single-element 10068//--- 10069 10070class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10071 string asm, string operands, string cst, 10072 dag oops, dag iops, list<dag> pattern> 10073 : I<oops, iops, asm, operands, cst, pattern> { 10074 bits<5> Vt; 10075 bits<5> Rn; 10076 let Inst{31} = 0; 10077 let Inst{29-24} = 0b001101; 10078 let Inst{22} = L; 10079 let Inst{21} = R; 10080 let Inst{15-13} = opcode; 10081 let Inst{9-5} = Rn; 10082 let Inst{4-0} = Vt; 10083} 10084 10085class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10086 string asm, string operands, string cst, 10087 dag oops, dag iops, list<dag> pattern> 10088 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10089 bits<5> Vt; 10090 bits<5> Rn; 10091 let Inst{31} = 0; 10092 let Inst{29-24} = 0b001101; 10093 let Inst{22} = L; 10094 let Inst{21} = R; 10095 let Inst{15-13} = opcode; 10096 let Inst{9-5} = Rn; 10097 let Inst{4-0} = Vt; 10098} 10099 10100 10101let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10102class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10103 DAGOperand listtype> 10104 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10105 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10106 []> { 10107 let Inst{30} = Q; 10108 let Inst{23} = 0; 10109 let Inst{20-16} = 0b00000; 10110 let Inst{12} = S; 10111 let Inst{11-10} = size; 10112} 10113let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10114class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10115 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10116 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10117 "$Rn = $wback", 10118 (outs GPR64sp:$wback, listtype:$Vt), 10119 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10120 bits<5> Xm; 10121 let Inst{30} = Q; 10122 let Inst{23} = 1; 10123 let Inst{20-16} = Xm; 10124 let Inst{12} = S; 10125 let Inst{11-10} = size; 10126} 10127 10128multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10129 int Offset, int Size> { 10130 // E.g. "ld1r { v0.8b }, [x1], #1" 10131 // "ld1r.8b\t$Vt, [$Rn], #1" 10132 // may get mapped to 10133 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10134 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10135 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10136 GPR64sp:$Rn, 10137 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10138 XZR), 1>; 10139 10140 // E.g. "ld1r.8b { v0 }, [x1], #1" 10141 // "ld1r.8b\t$Vt, [$Rn], #1" 10142 // may get mapped to 10143 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10144 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10145 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10146 GPR64sp:$Rn, 10147 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10148 XZR), 0>; 10149 10150 // E.g. "ld1r.8b { v0 }, [x1]" 10151 // "ld1r.8b\t$Vt, [$Rn]" 10152 // may get mapped to 10153 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10154 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10155 (!cast<Instruction>(BaseName # "v" # layout) 10156 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10157 GPR64sp:$Rn), 0>; 10158 10159 // E.g. "ld1r.8b { v0 }, [x1], x2" 10160 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10161 // may get mapped to 10162 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10163 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10164 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10165 GPR64sp:$Rn, 10166 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10167 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10168} 10169 10170multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10171 int Offset1, int Offset2, int Offset4, int Offset8> { 10172 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10173 !cast<DAGOperand>("VecList" # Count # "8b")>; 10174 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10175 !cast<DAGOperand>("VecList" # Count #"16b")>; 10176 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10177 !cast<DAGOperand>("VecList" # Count #"4h")>; 10178 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10179 !cast<DAGOperand>("VecList" # Count #"8h")>; 10180 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10181 !cast<DAGOperand>("VecList" # Count #"2s")>; 10182 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10183 !cast<DAGOperand>("VecList" # Count #"4s")>; 10184 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10185 !cast<DAGOperand>("VecList" # Count #"1d")>; 10186 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10187 !cast<DAGOperand>("VecList" # Count #"2d")>; 10188 10189 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10190 !cast<DAGOperand>("VecList" # Count # "8b"), 10191 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10192 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10193 !cast<DAGOperand>("VecList" # Count # "16b"), 10194 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10195 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10196 !cast<DAGOperand>("VecList" # Count # "4h"), 10197 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10198 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10199 !cast<DAGOperand>("VecList" # Count # "8h"), 10200 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10201 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10202 !cast<DAGOperand>("VecList" # Count # "2s"), 10203 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10204 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10205 !cast<DAGOperand>("VecList" # Count # "4s"), 10206 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10207 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10208 !cast<DAGOperand>("VecList" # Count # "1d"), 10209 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10210 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10211 !cast<DAGOperand>("VecList" # Count # "2d"), 10212 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10213 10214 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10215 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10216 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10217 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10218 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10219 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10220 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10221 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10222} 10223 10224class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10225 dag oops, dag iops, list<dag> pattern> 10226 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10227 pattern> { 10228 // idx encoded in Q:S:size fields. 10229 bits<4> idx; 10230 let Inst{30} = idx{3}; 10231 let Inst{23} = 0; 10232 let Inst{20-16} = 0b00000; 10233 let Inst{12} = idx{2}; 10234 let Inst{11-10} = idx{1-0}; 10235} 10236class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, 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:S:size fields. 10241 bits<4> idx; 10242 let Inst{30} = idx{3}; 10243 let Inst{23} = 0; 10244 let Inst{20-16} = 0b00000; 10245 let Inst{12} = idx{2}; 10246 let Inst{11-10} = idx{1-0}; 10247} 10248class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10249 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:S:size fields. 10253 bits<4> idx; 10254 bits<5> Xm; 10255 let Inst{30} = idx{3}; 10256 let Inst{23} = 1; 10257 let Inst{20-16} = Xm; 10258 let Inst{12} = idx{2}; 10259 let Inst{11-10} = idx{1-0}; 10260} 10261class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10262 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:S:size fields. 10266 bits<4> idx; 10267 bits<5> Xm; 10268 let Inst{30} = idx{3}; 10269 let Inst{23} = 1; 10270 let Inst{20-16} = Xm; 10271 let Inst{12} = idx{2}; 10272 let Inst{11-10} = idx{1-0}; 10273} 10274 10275class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10276 dag oops, dag iops, list<dag> pattern> 10277 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10278 pattern> { 10279 // idx encoded in Q:S:size<1> fields. 10280 bits<3> idx; 10281 let Inst{30} = idx{2}; 10282 let Inst{23} = 0; 10283 let Inst{20-16} = 0b00000; 10284 let Inst{12} = idx{1}; 10285 let Inst{11} = idx{0}; 10286 let Inst{10} = size; 10287} 10288class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10289 dag oops, dag iops, list<dag> pattern> 10290 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10291 oops, iops, pattern> { 10292 // idx encoded in Q:S:size<1> fields. 10293 bits<3> idx; 10294 let Inst{30} = idx{2}; 10295 let Inst{23} = 0; 10296 let Inst{20-16} = 0b00000; 10297 let Inst{12} = idx{1}; 10298 let Inst{11} = idx{0}; 10299 let Inst{10} = size; 10300} 10301 10302class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10303 dag oops, dag iops> 10304 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10305 "$Rn = $wback", oops, iops, []> { 10306 // idx encoded in Q:S:size<1> fields. 10307 bits<3> idx; 10308 bits<5> Xm; 10309 let Inst{30} = idx{2}; 10310 let Inst{23} = 1; 10311 let Inst{20-16} = Xm; 10312 let Inst{12} = idx{1}; 10313 let Inst{11} = idx{0}; 10314 let Inst{10} = size; 10315} 10316class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10317 dag oops, dag iops> 10318 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10319 "$Rn = $wback", oops, iops, []> { 10320 // idx encoded in Q:S:size<1> fields. 10321 bits<3> idx; 10322 bits<5> Xm; 10323 let Inst{30} = idx{2}; 10324 let Inst{23} = 1; 10325 let Inst{20-16} = Xm; 10326 let Inst{12} = idx{1}; 10327 let Inst{11} = idx{0}; 10328 let Inst{10} = size; 10329} 10330class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10331 dag oops, dag iops, list<dag> pattern> 10332 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10333 pattern> { 10334 // idx encoded in Q:S fields. 10335 bits<2> idx; 10336 let Inst{30} = idx{1}; 10337 let Inst{23} = 0; 10338 let Inst{20-16} = 0b00000; 10339 let Inst{12} = idx{0}; 10340 let Inst{11-10} = size; 10341} 10342class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10343 dag oops, dag iops, list<dag> pattern> 10344 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10345 oops, iops, pattern> { 10346 // idx encoded in Q:S fields. 10347 bits<2> idx; 10348 let Inst{30} = idx{1}; 10349 let Inst{23} = 0; 10350 let Inst{20-16} = 0b00000; 10351 let Inst{12} = idx{0}; 10352 let Inst{11-10} = size; 10353} 10354class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10355 string asm, dag oops, dag iops> 10356 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10357 "$Rn = $wback", oops, iops, []> { 10358 // idx encoded in Q:S fields. 10359 bits<2> idx; 10360 bits<5> Xm; 10361 let Inst{30} = idx{1}; 10362 let Inst{23} = 1; 10363 let Inst{20-16} = Xm; 10364 let Inst{12} = idx{0}; 10365 let Inst{11-10} = size; 10366} 10367class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10368 string asm, dag oops, dag iops> 10369 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10370 "$Rn = $wback", oops, iops, []> { 10371 // idx encoded in Q:S fields. 10372 bits<2> idx; 10373 bits<5> Xm; 10374 let Inst{30} = idx{1}; 10375 let Inst{23} = 1; 10376 let Inst{20-16} = Xm; 10377 let Inst{12} = idx{0}; 10378 let Inst{11-10} = size; 10379} 10380class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10381 dag oops, dag iops, list<dag> pattern> 10382 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10383 pattern> { 10384 // idx encoded in Q field. 10385 bits<1> idx; 10386 let Inst{30} = idx; 10387 let Inst{23} = 0; 10388 let Inst{20-16} = 0b00000; 10389 let Inst{12} = 0; 10390 let Inst{11-10} = size; 10391} 10392class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10393 dag oops, dag iops, list<dag> pattern> 10394 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10395 oops, iops, pattern> { 10396 // idx encoded in Q field. 10397 bits<1> idx; 10398 let Inst{30} = idx; 10399 let Inst{23} = 0; 10400 let Inst{20-16} = 0b00000; 10401 let Inst{12} = 0; 10402 let Inst{11-10} = size; 10403} 10404class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10405 string asm, dag oops, dag iops> 10406 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10407 "$Rn = $wback", oops, iops, []> { 10408 // idx encoded in Q field. 10409 bits<1> idx; 10410 bits<5> Xm; 10411 let Inst{30} = idx; 10412 let Inst{23} = 1; 10413 let Inst{20-16} = Xm; 10414 let Inst{12} = 0; 10415 let Inst{11-10} = size; 10416} 10417class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10418 string asm, dag oops, dag iops> 10419 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10420 "$Rn = $wback", oops, iops, []> { 10421 // idx encoded in Q field. 10422 bits<1> idx; 10423 bits<5> Xm; 10424 let Inst{30} = idx; 10425 let Inst{23} = 1; 10426 let Inst{20-16} = Xm; 10427 let Inst{12} = 0; 10428 let Inst{11-10} = size; 10429} 10430 10431let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10432multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10433 RegisterOperand listtype, 10434 RegisterOperand GPR64pi> { 10435 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10436 (outs listtype:$dst), 10437 (ins listtype:$Vt, VectorIndexB:$idx, 10438 GPR64sp:$Rn), []>; 10439 10440 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10441 (outs GPR64sp:$wback, listtype:$dst), 10442 (ins listtype:$Vt, VectorIndexB:$idx, 10443 GPR64sp:$Rn, GPR64pi:$Xm)>; 10444} 10445let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10446multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10447 RegisterOperand listtype, 10448 RegisterOperand GPR64pi> { 10449 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10450 (outs listtype:$dst), 10451 (ins listtype:$Vt, VectorIndexH:$idx, 10452 GPR64sp:$Rn), []>; 10453 10454 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10455 (outs GPR64sp:$wback, listtype:$dst), 10456 (ins listtype:$Vt, VectorIndexH:$idx, 10457 GPR64sp:$Rn, GPR64pi:$Xm)>; 10458} 10459let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10460multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10461 RegisterOperand listtype, 10462 RegisterOperand GPR64pi> { 10463 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10464 (outs listtype:$dst), 10465 (ins listtype:$Vt, VectorIndexS:$idx, 10466 GPR64sp:$Rn), []>; 10467 10468 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10469 (outs GPR64sp:$wback, listtype:$dst), 10470 (ins listtype:$Vt, VectorIndexS:$idx, 10471 GPR64sp:$Rn, GPR64pi:$Xm)>; 10472} 10473let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10474multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10475 RegisterOperand listtype, RegisterOperand GPR64pi> { 10476 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10477 (outs listtype:$dst), 10478 (ins listtype:$Vt, VectorIndexD:$idx, 10479 GPR64sp:$Rn), []>; 10480 10481 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10482 (outs GPR64sp:$wback, listtype:$dst), 10483 (ins listtype:$Vt, VectorIndexD:$idx, 10484 GPR64sp:$Rn, GPR64pi:$Xm)>; 10485} 10486let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10487multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10488 RegisterOperand listtype, RegisterOperand GPR64pi> { 10489 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10490 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10491 GPR64sp:$Rn), []>; 10492 10493 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10494 (outs GPR64sp:$wback), 10495 (ins listtype:$Vt, VectorIndexB:$idx, 10496 GPR64sp:$Rn, GPR64pi:$Xm)>; 10497} 10498let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10499multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10500 RegisterOperand listtype, RegisterOperand GPR64pi> { 10501 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10502 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10503 GPR64sp:$Rn), []>; 10504 10505 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10506 (outs GPR64sp:$wback), 10507 (ins listtype:$Vt, VectorIndexH:$idx, 10508 GPR64sp:$Rn, GPR64pi:$Xm)>; 10509} 10510let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10511multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10512 RegisterOperand listtype, RegisterOperand GPR64pi> { 10513 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10514 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10515 GPR64sp:$Rn), []>; 10516 10517 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10518 (outs GPR64sp:$wback), 10519 (ins listtype:$Vt, VectorIndexS:$idx, 10520 GPR64sp:$Rn, GPR64pi:$Xm)>; 10521} 10522let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10523multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10524 RegisterOperand listtype, RegisterOperand GPR64pi> { 10525 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10526 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10527 GPR64sp:$Rn), []>; 10528 10529 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10530 (outs GPR64sp:$wback), 10531 (ins listtype:$Vt, VectorIndexD:$idx, 10532 GPR64sp:$Rn, GPR64pi:$Xm)>; 10533} 10534 10535multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10536 string Count, int Offset, Operand idxtype> { 10537 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10538 // "ld1\t$Vt, [$Rn], #1" 10539 // may get mapped to 10540 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10541 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10542 (!cast<Instruction>(NAME # Type # "_POST") 10543 GPR64sp:$Rn, 10544 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10545 idxtype:$idx, XZR), 1>; 10546 10547 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10548 // "ld1.8b\t$Vt, [$Rn], #1" 10549 // may get mapped to 10550 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10551 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10552 (!cast<Instruction>(NAME # Type # "_POST") 10553 GPR64sp:$Rn, 10554 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10555 idxtype:$idx, XZR), 0>; 10556 10557 // E.g. "ld1.8b { v0 }[0], [x1]" 10558 // "ld1.8b\t$Vt, [$Rn]" 10559 // may get mapped to 10560 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10561 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10562 (!cast<Instruction>(NAME # Type) 10563 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10564 idxtype:$idx, GPR64sp:$Rn), 0>; 10565 10566 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10567 // "ld1.8b\t$Vt, [$Rn], $Xm" 10568 // may get mapped to 10569 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10570 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10571 (!cast<Instruction>(NAME # Type # "_POST") 10572 GPR64sp:$Rn, 10573 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10574 idxtype:$idx, 10575 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10576} 10577 10578multiclass SIMDLdSt1SingleAliases<string asm> { 10579 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10580 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10581 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10582 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10583} 10584 10585multiclass SIMDLdSt2SingleAliases<string asm> { 10586 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10587 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10588 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10589 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10590} 10591 10592multiclass SIMDLdSt3SingleAliases<string asm> { 10593 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10594 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10595 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10596 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10597} 10598 10599multiclass SIMDLdSt4SingleAliases<string asm> { 10600 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10601 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10602 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10603 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10604} 10605} // end of 'let Predicates = [HasNEON]' 10606 10607//---------------------------------------------------------------------------- 10608// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10609//---------------------------------------------------------------------------- 10610 10611let Predicates = [HasNEON, HasRDM] in { 10612 10613class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10614 RegisterOperand regtype, string asm, 10615 string kind, list<dag> pattern> 10616 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10617 pattern> { 10618} 10619multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10620 SDPatternOperator op> { 10621 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10622 [(set (v4i16 V64:$dst), 10623 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 10624 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10625 [(set (v8i16 V128:$dst), 10626 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 10627 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10628 [(set (v2i32 V64:$dst), 10629 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 10630 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10631 [(set (v4i32 V128:$dst), 10632 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 10633} 10634 10635multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10636 SDPatternOperator op> { 10637 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10638 V64, V64, V128_lo, VectorIndexH, 10639 asm, ".4h", ".4h", ".4h", ".h", 10640 [(set (v4i16 V64:$dst), 10641 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10642 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10643 VectorIndexH:$idx)))))]> { 10644 bits<3> idx; 10645 let Inst{11} = idx{2}; 10646 let Inst{21} = idx{1}; 10647 let Inst{20} = idx{0}; 10648 } 10649 10650 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10651 V128, V128, V128_lo, VectorIndexH, 10652 asm, ".8h", ".8h", ".8h", ".h", 10653 [(set (v8i16 V128:$dst), 10654 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10655 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10656 VectorIndexH:$idx)))))]> { 10657 bits<3> idx; 10658 let Inst{11} = idx{2}; 10659 let Inst{21} = idx{1}; 10660 let Inst{20} = idx{0}; 10661 } 10662 10663 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10664 V64, V64, V128, VectorIndexS, 10665 asm, ".2s", ".2s", ".2s", ".s", 10666 [(set (v2i32 V64:$dst), 10667 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10668 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10669 VectorIndexS:$idx)))))]> { 10670 bits<2> idx; 10671 let Inst{11} = idx{1}; 10672 let Inst{21} = idx{0}; 10673 } 10674 10675 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10676 V128, V128, V128, VectorIndexS, 10677 asm, ".4s", ".4s", ".4s", ".s", 10678 [(set (v4i32 V128:$dst), 10679 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10680 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10681 VectorIndexS:$idx)))))]> { 10682 bits<2> idx; 10683 let Inst{11} = idx{1}; 10684 let Inst{21} = idx{0}; 10685 } 10686 10687 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10688 FPR16Op, FPR16Op, V128_lo, 10689 VectorIndexH, asm, ".h", "", "", ".h", 10690 []> { 10691 bits<3> idx; 10692 let Inst{11} = idx{2}; 10693 let Inst{21} = idx{1}; 10694 let Inst{20} = idx{0}; 10695 } 10696 10697 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10698 FPR32Op, FPR32Op, V128, VectorIndexS, 10699 asm, ".s", "", "", ".s", 10700 [(set (i32 FPR32Op:$dst), 10701 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 10702 (i32 (vector_extract (v4i32 V128:$Rm), 10703 VectorIndexS:$idx)))))]> { 10704 bits<2> idx; 10705 let Inst{11} = idx{1}; 10706 let Inst{21} = idx{0}; 10707 } 10708} 10709} // let Predicates = [HasNeon, HasRDM] 10710 10711//---------------------------------------------------------------------------- 10712// ARMv8.3 Complex ADD/MLA instructions 10713//---------------------------------------------------------------------------- 10714 10715class ComplexRotationOperand<int Angle, int Remainder, string Type> 10716 : AsmOperandClass { 10717 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10718 let DiagnosticType = "InvalidComplexRotation" # Type; 10719 let Name = "ComplexRotation" # Type; 10720} 10721def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10722 SDNodeXForm<imm, [{ 10723 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10724}]>> { 10725 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10726 let PrintMethod = "printComplexRotationOp<90, 0>"; 10727} 10728def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10729 SDNodeXForm<imm, [{ 10730 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10731}]>> { 10732 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10733 let PrintMethod = "printComplexRotationOp<180, 90>"; 10734} 10735let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10736class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10737 RegisterOperand regtype, Operand rottype, 10738 string asm, string kind, list<dag> pattern> 10739 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10740 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10741 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10742 Sched<[!if(Q, WriteVq, WriteVd)]> { 10743 bits<5> Rd; 10744 bits<5> Rn; 10745 bits<5> Rm; 10746 bits<1> rot; 10747 let Inst{31} = 0; 10748 let Inst{30} = Q; 10749 let Inst{29} = U; 10750 let Inst{28-24} = 0b01110; 10751 let Inst{23-22} = size; 10752 let Inst{21} = 0; 10753 let Inst{20-16} = Rm; 10754 let Inst{15-13} = opcode; 10755 // Non-tied version (FCADD) only has one rotation bit 10756 let Inst{12} = rot; 10757 let Inst{11} = 0; 10758 let Inst{10} = 1; 10759 let Inst{9-5} = Rn; 10760 let Inst{4-0} = Rd; 10761} 10762 10763//8.3 CompNum - Floating-point complex number support 10764multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10765 string asm, SDPatternOperator OpNode>{ 10766 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10767 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10768 asm, ".4h", 10769 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10770 (v4f16 V64:$Rn), 10771 (v4f16 V64:$Rm), 10772 (i32 rottype:$rot)))]>; 10773 10774 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10775 asm, ".8h", 10776 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10777 (v8f16 V128:$Rn), 10778 (v8f16 V128:$Rm), 10779 (i32 rottype:$rot)))]>; 10780 } 10781 10782 let Predicates = [HasComplxNum, HasNEON] in { 10783 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10784 asm, ".2s", 10785 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10786 (v2f32 V64:$Rn), 10787 (v2f32 V64:$Rm), 10788 (i32 rottype:$rot)))]>; 10789 10790 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10791 asm, ".4s", 10792 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10793 (v4f32 V128:$Rn), 10794 (v4f32 V128:$Rm), 10795 (i32 rottype:$rot)))]>; 10796 10797 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10798 asm, ".2d", 10799 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10800 (v2f64 V128:$Rn), 10801 (v2f64 V128:$Rm), 10802 (i32 rottype:$rot)))]>; 10803 } 10804} 10805 10806let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10807class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10808 bits<3> opcode, 10809 RegisterOperand regtype, 10810 Operand rottype, string asm, 10811 string kind, list<dag> pattern> 10812 : I<(outs regtype:$dst), 10813 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10814 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10815 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10816 Sched<[!if(Q, WriteVq, WriteVd)]> { 10817 bits<5> Rd; 10818 bits<5> Rn; 10819 bits<5> Rm; 10820 bits<2> rot; 10821 let Inst{31} = 0; 10822 let Inst{30} = Q; 10823 let Inst{29} = U; 10824 let Inst{28-24} = 0b01110; 10825 let Inst{23-22} = size; 10826 let Inst{21} = 0; 10827 let Inst{20-16} = Rm; 10828 let Inst{15-13} = opcode; 10829 let Inst{12-11} = rot; 10830 let Inst{10} = 1; 10831 let Inst{9-5} = Rn; 10832 let Inst{4-0} = Rd; 10833} 10834 10835multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10836 Operand rottype, string asm, 10837 SDPatternOperator OpNode> { 10838 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10839 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10840 rottype, asm, ".4h", 10841 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10842 (v4f16 V64:$Rn), 10843 (v4f16 V64:$Rm), 10844 (i32 rottype:$rot)))]>; 10845 10846 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10847 rottype, asm, ".8h", 10848 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10849 (v8f16 V128:$Rn), 10850 (v8f16 V128:$Rm), 10851 (i32 rottype:$rot)))]>; 10852 } 10853 10854 let Predicates = [HasComplxNum, HasNEON] in { 10855 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10856 rottype, asm, ".2s", 10857 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10858 (v2f32 V64:$Rn), 10859 (v2f32 V64:$Rm), 10860 (i32 rottype:$rot)))]>; 10861 10862 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10863 rottype, asm, ".4s", 10864 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10865 (v4f32 V128:$Rn), 10866 (v4f32 V128:$Rm), 10867 (i32 rottype:$rot)))]>; 10868 10869 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10870 rottype, asm, ".2d", 10871 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10872 (v2f64 V128:$Rn), 10873 (v2f64 V128:$Rm), 10874 (i32 rottype:$rot)))]>; 10875 } 10876} 10877 10878let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10879class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10880 bit opc1, bit opc2, RegisterOperand dst_reg, 10881 RegisterOperand lhs_reg, 10882 RegisterOperand rhs_reg, Operand vec_idx, 10883 Operand rottype, string asm, string apple_kind, 10884 string dst_kind, string lhs_kind, 10885 string rhs_kind, list<dag> pattern> 10886 : I<(outs dst_reg:$dst), 10887 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10888 asm, 10889 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10890 "$idx, $rot" # "|" # apple_kind # 10891 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10892 Sched<[!if(Q, WriteVq, WriteVd)]> { 10893 bits<5> Rd; 10894 bits<5> Rn; 10895 bits<5> Rm; 10896 bits<2> rot; 10897 10898 let Inst{31} = 0; 10899 let Inst{30} = Q; 10900 let Inst{29} = U; 10901 let Inst{28} = Scalar; 10902 let Inst{27-24} = 0b1111; 10903 let Inst{23-22} = size; 10904 // Bit 21 must be set by the derived class. 10905 let Inst{20-16} = Rm; 10906 let Inst{15} = opc1; 10907 let Inst{14-13} = rot; 10908 let Inst{12} = opc2; 10909 // Bit 11 must be set by the derived class. 10910 let Inst{10} = 0; 10911 let Inst{9-5} = Rn; 10912 let Inst{4-0} = Rd; 10913} 10914 10915// The complex instructions index by pairs of elements, so the VectorIndexes 10916// don't match the lane types, and the index bits are different to the other 10917// classes. 10918multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 10919 string asm> { 10920 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10921 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10922 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10923 ".4h", ".h", []> { 10924 bits<1> idx; 10925 let Inst{11} = 0; 10926 let Inst{21} = idx{0}; 10927 } 10928 10929 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10930 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10931 ".8h", ".8h", ".h", []> { 10932 bits<2> idx; 10933 let Inst{11} = idx{1}; 10934 let Inst{21} = idx{0}; 10935 } 10936 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10937 10938 let Predicates = [HasComplxNum, HasNEON] in { 10939 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10940 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10941 ".4s", ".4s", ".s", []> { 10942 bits<1> idx; 10943 let Inst{11} = idx{0}; 10944 let Inst{21} = 0; 10945 } 10946 } // Predicates = [HasComplxNum, HasNEON] 10947} 10948 10949//---------------------------------------------------------------------------- 10950// Crypto extensions 10951//---------------------------------------------------------------------------- 10952 10953let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10954class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10955 list<dag> pat> 10956 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10957 Sched<[WriteVq]>{ 10958 bits<5> Rd; 10959 bits<5> Rn; 10960 let Inst{31-16} = 0b0100111000101000; 10961 let Inst{15-12} = opc; 10962 let Inst{11-10} = 0b10; 10963 let Inst{9-5} = Rn; 10964 let Inst{4-0} = Rd; 10965} 10966 10967class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10968 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10969 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10970 10971class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10972 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10973 "$Rd = $dst", 10974 [(set (v16i8 V128:$dst), 10975 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10976 10977let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10978class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10979 dag oops, dag iops, list<dag> pat> 10980 : I<oops, iops, asm, 10981 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10982 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10983 Sched<[WriteVq]>{ 10984 bits<5> Rd; 10985 bits<5> Rn; 10986 bits<5> Rm; 10987 let Inst{31-21} = 0b01011110000; 10988 let Inst{20-16} = Rm; 10989 let Inst{15} = 0; 10990 let Inst{14-12} = opc; 10991 let Inst{11-10} = 0b00; 10992 let Inst{9-5} = Rn; 10993 let Inst{4-0} = Rd; 10994} 10995 10996class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10997 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10998 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10999 [(set (v4i32 FPR128:$dst), 11000 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11001 (v4i32 V128:$Rm)))]>; 11002 11003class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11004 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11005 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11006 [(set (v4i32 V128:$dst), 11007 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11008 (v4i32 V128:$Rm)))]>; 11009 11010class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11011 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11012 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11013 [(set (v4i32 FPR128:$dst), 11014 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11015 (v4i32 V128:$Rm)))]>; 11016 11017let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11018class SHA2OpInst<bits<4> opc, string asm, string kind, 11019 string cstr, dag oops, dag iops, 11020 list<dag> pat> 11021 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11022 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11023 Sched<[WriteVq]>{ 11024 bits<5> Rd; 11025 bits<5> Rn; 11026 let Inst{31-16} = 0b0101111000101000; 11027 let Inst{15-12} = opc; 11028 let Inst{11-10} = 0b10; 11029 let Inst{9-5} = Rn; 11030 let Inst{4-0} = Rd; 11031} 11032 11033class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11034 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11035 (ins V128:$Rd, V128:$Rn), 11036 [(set (v4i32 V128:$dst), 11037 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11038 11039class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11040 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11041 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11042 11043// Armv8.2-A Crypto extensions 11044class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11045 list<dag> pattern> 11046 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11047 bits<5> Vd; 11048 bits<5> Vn; 11049 let Inst{31-25} = 0b1100111; 11050 let Inst{9-5} = Vn; 11051 let Inst{4-0} = Vd; 11052} 11053 11054class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11055 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11056 "$Vd = $Vdst", []> { 11057 let Inst{31-25} = 0b1100111; 11058 let Inst{24-21} = 0b0110; 11059 let Inst{20-15} = 0b000001; 11060 let Inst{14} = op0; 11061 let Inst{13-12} = 0b00; 11062 let Inst{11-10} = op1; 11063} 11064class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11065 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11066class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11067 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11068 11069class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11070 string asmops, string cst> 11071 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11072 bits<5> Vm; 11073 let Inst{24-21} = 0b0011; 11074 let Inst{20-16} = Vm; 11075 let Inst{15} = 0b1; 11076 let Inst{14} = op0; 11077 let Inst{13-12} = 0b00; 11078 let Inst{11-10} = op1; 11079} 11080class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11081 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11082 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11083class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11084 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11085 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11086class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11087 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11088 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11089class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11090 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11091 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11092class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11093 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11094 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11095 11096class CryptoRRRR<bits<2>op0, string asm, string asmops> 11097 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11098 asmops, "", []> { 11099 bits<5> Vm; 11100 bits<5> Va; 11101 let Inst{24-23} = 0b00; 11102 let Inst{22-21} = op0; 11103 let Inst{20-16} = Vm; 11104 let Inst{15} = 0b0; 11105 let Inst{14-10} = Va; 11106} 11107class CryptoRRRR_16B<bits<2>op0, string asm> 11108 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11109 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11110} 11111class CryptoRRRR_4S<bits<2>op0, string asm> 11112 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11113 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11114} 11115 11116class CryptoRRRi6<string asm> 11117 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11118 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11119 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11120 bits<6> imm; 11121 bits<5> Vm; 11122 let Inst{24-21} = 0b0100; 11123 let Inst{20-16} = Vm; 11124 let Inst{15-10} = imm; 11125 let Inst{9-5} = Vn; 11126 let Inst{4-0} = Vd; 11127} 11128 11129class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11130 : BaseCryptoV82<(outs V128:$Vdst), 11131 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11132 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11133 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11134 bits<2> imm; 11135 bits<5> Vm; 11136 let Inst{24-21} = 0b0010; 11137 let Inst{20-16} = Vm; 11138 let Inst{15} = 0b1; 11139 let Inst{14} = op0; 11140 let Inst{13-12} = imm; 11141 let Inst{11-10} = op1; 11142} 11143 11144//---------------------------------------------------------------------------- 11145// v8.1 atomic instructions extension: 11146// * CAS 11147// * CASP 11148// * SWP 11149// * LDOPregister<OP>, and aliases STOPregister<OP> 11150 11151// Instruction encodings: 11152// 11153// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11154// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11155// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11156// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11157// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11158// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11159 11160// Instruction syntax: 11161// 11162// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11163// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11164// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11165// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11166// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11167// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11168// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11169// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11170// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11171// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11172 11173let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11174class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11175 string cstr, list<dag> pattern> 11176 : I<oops, iops, asm, operands, cstr, pattern> { 11177 bits<2> Sz; 11178 bit NP; 11179 bit Acq; 11180 bit Rel; 11181 bits<5> Rs; 11182 bits<5> Rn; 11183 bits<5> Rt; 11184 let Inst{31-30} = Sz; 11185 let Inst{29-24} = 0b001000; 11186 let Inst{23} = NP; 11187 let Inst{22} = Acq; 11188 let Inst{21} = 0b1; 11189 let Inst{20-16} = Rs; 11190 let Inst{15} = Rel; 11191 let Inst{14-10} = 0b11111; 11192 let Inst{9-5} = Rn; 11193 let Inst{4-0} = Rt; 11194 let Predicates = [HasLSE]; 11195} 11196 11197class BaseCAS<string order, string size, RegisterClass RC> 11198 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11199 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11200 "$out = $Rs",[]>, 11201 Sched<[WriteAtomic]> { 11202 let NP = 1; 11203} 11204 11205multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11206 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11207 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11208 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11209 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11210} 11211 11212class BaseCASP<string order, string size, RegisterOperand RC> 11213 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11214 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11215 "$out = $Rs",[]>, 11216 Sched<[WriteAtomic]> { 11217 let NP = 0; 11218} 11219 11220multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11221 let Sz = 0b00, Acq = Acq, Rel = Rel in 11222 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11223 let Sz = 0b01, Acq = Acq, Rel = Rel in 11224 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11225} 11226 11227let Predicates = [HasLSE] in 11228class BaseSWP<string order, string size, RegisterClass RC> 11229 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11230 "\t$Rs, $Rt, [$Rn]","",[]>, 11231 Sched<[WriteAtomic]> { 11232 bits<2> Sz; 11233 bit Acq; 11234 bit Rel; 11235 bits<5> Rs; 11236 bits<3> opc = 0b000; 11237 bits<5> Rn; 11238 bits<5> Rt; 11239 let Inst{31-30} = Sz; 11240 let Inst{29-24} = 0b111000; 11241 let Inst{23} = Acq; 11242 let Inst{22} = Rel; 11243 let Inst{21} = 0b1; 11244 let Inst{20-16} = Rs; 11245 let Inst{15} = 0b1; 11246 let Inst{14-12} = opc; 11247 let Inst{11-10} = 0b00; 11248 let Inst{9-5} = Rn; 11249 let Inst{4-0} = Rt; 11250 let Predicates = [HasLSE]; 11251} 11252 11253multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11254 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11255 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11256 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11257 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11258} 11259 11260let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11261class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11262 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11263 "\t$Rs, $Rt, [$Rn]","",[]>, 11264 Sched<[WriteAtomic]> { 11265 bits<2> Sz; 11266 bit Acq; 11267 bit Rel; 11268 bits<5> Rs; 11269 bits<3> opc; 11270 bits<5> Rn; 11271 bits<5> Rt; 11272 let Inst{31-30} = Sz; 11273 let Inst{29-24} = 0b111000; 11274 let Inst{23} = Acq; 11275 let Inst{22} = Rel; 11276 let Inst{21} = 0b1; 11277 let Inst{20-16} = Rs; 11278 let Inst{15} = 0b0; 11279 let Inst{14-12} = opc; 11280 let Inst{11-10} = 0b00; 11281 let Inst{9-5} = Rn; 11282 let Inst{4-0} = Rt; 11283 let Predicates = [HasLSE]; 11284} 11285 11286multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11287 string order> { 11288 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11289 def B : BaseLDOPregister<op, order, "b", GPR32>; 11290 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11291 def H : BaseLDOPregister<op, order, "h", GPR32>; 11292 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11293 def W : BaseLDOPregister<op, order, "", GPR32>; 11294 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11295 def X : BaseLDOPregister<op, order, "", GPR64>; 11296} 11297 11298// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11299// complex DAG for DstRHS. 11300let Predicates = [HasLSE] in 11301multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11302 string size, dag SrcRHS, dag DstRHS> { 11303 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11304 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11305 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11306 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11307 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11308 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11309 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11310 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11311 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11312 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11313} 11314 11315multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11316 string size, dag RHS> { 11317 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11318} 11319 11320multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11321 string size, dag LHS, dag RHS> { 11322 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11323} 11324 11325multiclass LDOPregister_patterns<string inst, string op> { 11326 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11327 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11328 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11329 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11330} 11331 11332multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11333 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11334 (i64 GPR64:$Rm), 11335 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11336 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11337 (i32 GPR32:$Rm), 11338 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11339 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11340 (i32 GPR32:$Rm), 11341 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11342 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11343 (i32 GPR32:$Rm), 11344 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11345} 11346 11347let Predicates = [HasLSE] in 11348multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11349 string size, dag OLD, dag NEW> { 11350 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11351 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11352 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11353 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11354 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11355 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11356 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11357 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11358 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11359 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11360} 11361 11362multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11363 string size, dag OLD, dag NEW> { 11364 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11365} 11366 11367multiclass CASregister_patterns<string inst, string op> { 11368 defm : CASregister_patterns_ord<inst, "X", op, "64", 11369 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11370 defm : CASregister_patterns_ord<inst, "W", op, "32", 11371 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11372 defm : CASregister_patterns_ord<inst, "H", op, "16", 11373 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11374 defm : CASregister_patterns_ord<inst, "B", op, "8", 11375 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11376} 11377 11378let Predicates = [HasLSE] in 11379class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11380 Instruction inst> : 11381 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11382 11383multiclass STOPregister<string asm, string instr> { 11384 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11385 !cast<Instruction>(instr # "LB")>; 11386 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11387 !cast<Instruction>(instr # "LH")>; 11388 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11389 !cast<Instruction>(instr # "LW")>; 11390 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11391 !cast<Instruction>(instr # "LX")>; 11392 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11393 !cast<Instruction>(instr # "B")>; 11394 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11395 !cast<Instruction>(instr # "H")>; 11396 def : BaseSTOPregister<asm, GPR32, WZR, 11397 !cast<Instruction>(instr # "W")>; 11398 def : BaseSTOPregister<asm, GPR64, XZR, 11399 !cast<Instruction>(instr # "X")>; 11400} 11401 11402class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11403 dag iops, dag oops, list<dag> pat> 11404 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11405 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11406 bits<5> Rt; 11407 bits<5> Rn; 11408 let Inst{31-21} = 0b11111000001; 11409 let Inst{15} = 1; 11410 let Inst{14-12} = opc; 11411 let Inst{11-10} = 0b00; 11412 let Inst{9-5} = Rn; 11413 let Inst{4-0} = Rt; 11414 11415 let Predicates = [HasV8_7a]; 11416} 11417 11418class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11419 list<dag> pat = []> 11420 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11421 let Inst{20-16} = 0b11111; 11422} 11423 11424class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11425 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11426 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11427 bits<5> Rs; 11428 let Inst{20-16} = Rs; 11429} 11430 11431class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 11432 bits<2> op2, string asm> 11433 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 11434 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 11435 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 11436 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 11437 Sched<[]> { 11438 bits<5> Rd; 11439 bits<5> Rs; 11440 bits<5> Rn; 11441 let Inst{31-27} = 0b00011; 11442 let Inst{26} = isMove; 11443 let Inst{25-24} = 0b01; 11444 let Inst{23-22} = opcode; 11445 let Inst{21} = 0b0; 11446 let Inst{20-16} = Rs; 11447 let Inst{15-14} = op2; 11448 let Inst{13-12} = op1; 11449 let Inst{11-10} = 0b01; 11450 let Inst{9-5} = Rn; 11451 let Inst{4-0} = Rd; 11452 11453 let DecoderMethod = "DecodeCPYMemOpInstruction"; 11454 let mayLoad = 1; 11455 let mayStore = 1; 11456} 11457 11458class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11459 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 11460 11461class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11462 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 11463 11464class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 11465 string asm> 11466 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 11467 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 11468 asm, "\t[$Rd]!, $Rn!, $Rm", 11469 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 11470 Sched<[]> { 11471 bits<5> Rd; 11472 bits<5> Rn; 11473 bits<5> Rm; 11474 let Inst{31-27} = 0b00011; 11475 let Inst{26} = isTagging; 11476 let Inst{25-21} = 0b01110; 11477 let Inst{20-16} = Rm; 11478 let Inst{15-14} = opcode; 11479 let Inst{13} = op2; 11480 let Inst{12} = op1; 11481 let Inst{11-10} = 0b01; 11482 let Inst{9-5} = Rn; 11483 let Inst{4-0} = Rd; 11484 11485 let DecoderMethod = "DecodeSETMemOpInstruction"; 11486 let mayLoad = 0; 11487 let mayStore = 1; 11488} 11489 11490class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 11491 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 11492 11493class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 11494 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 11495 11496multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 11497 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 11498 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 11499 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 11500 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 11501 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 11502 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 11503 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 11504 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 11505 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 11506 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 11507 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 11508 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 11509 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 11510 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 11511 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 11512 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 11513} 11514 11515multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 11516 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 11517 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 11518 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 11519 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 11520 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 11521 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 11522 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 11523 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 11524 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 11525 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 11526 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 11527 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 11528 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 11529 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 11530 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 11531 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 11532} 11533 11534multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 11535 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 11536 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 11537 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 11538 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 11539} 11540 11541multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 11542 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 11543 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 11544 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 11545 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 11546} 11547 11548//---------------------------------------------------------------------------- 11549// Allow the size specifier tokens to be upper case, not just lower. 11550def : TokenAlias<".4B", ".4b">; // Add dot product 11551def : TokenAlias<".8B", ".8b">; 11552def : TokenAlias<".4H", ".4h">; 11553def : TokenAlias<".2S", ".2s">; 11554def : TokenAlias<".1D", ".1d">; 11555def : TokenAlias<".16B", ".16b">; 11556def : TokenAlias<".8H", ".8h">; 11557def : TokenAlias<".4S", ".4s">; 11558def : TokenAlias<".2D", ".2d">; 11559def : TokenAlias<".1Q", ".1q">; 11560def : TokenAlias<".2H", ".2h">; 11561def : TokenAlias<".B", ".b">; 11562def : TokenAlias<".H", ".h">; 11563def : TokenAlias<".S", ".s">; 11564def : TokenAlias<".D", ".d">; 11565def : TokenAlias<".Q", ".q">; 11566