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_minus0 : FPImmLeaf<fAny, [{ 1238 return Imm.isExactlyValue(-0.0); 1239}]>; 1240 1241def fpimm_half : FPImmLeaf<fAny, [{ 1242 return Imm.isExactlyValue(+0.5); 1243}]>; 1244 1245def fpimm_one : FPImmLeaf<fAny, [{ 1246 return Imm.isExactlyValue(+1.0); 1247}]>; 1248 1249def fpimm_two : FPImmLeaf<fAny, [{ 1250 return Imm.isExactlyValue(+2.0); 1251}]>; 1252 1253def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1254 GISDNodeXFormEquiv<fpimm16XForm>; 1255def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1256 GISDNodeXFormEquiv<fpimm32XForm>; 1257def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1258 GISDNodeXFormEquiv<fpimm64XForm>; 1259def gi_fpimm32SIMDModImmType4 : 1260 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, 1261 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>; 1262 1263// Vector lane operands 1264class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1265 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1266 let DiagnosticType = "Invalid" # Name; 1267 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1268 let RenderMethod = "addVectorIndexOperands"; 1269} 1270 1271class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1272 : Operand<ty> { 1273 let ParserMatchClass = mc; 1274 let PrintMethod = "printVectorIndex"; 1275} 1276 1277multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1278 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1279 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1280} 1281 1282def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1283def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1284def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1285def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1286def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1287def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1288 1289let OperandNamespace = "AArch64" in { 1290 let OperandType = "OPERAND_IMPLICIT_IMM_0" in { 1291 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1292 [{ return ((uint64_t)Imm) == 0; }]>; 1293 } 1294} 1295defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1296 [{ return ((uint64_t)Imm) == 1; }]>; 1297defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1298 [{ return ((uint64_t)Imm) < 16; }]>; 1299defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1300 [{ return ((uint64_t)Imm) < 8; }]>; 1301defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1302 [{ return ((uint64_t)Imm) < 4; }]>; 1303defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1304 [{ return ((uint64_t)Imm) < 2; }]>; 1305 1306defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1307 [{ return ((uint64_t)Imm) == 1; }]>; 1308defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1309 [{ return ((uint64_t)Imm) < 16; }]>; 1310defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1311 [{ return ((uint64_t)Imm) < 8; }]>; 1312defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1313 [{ return ((uint64_t)Imm) < 4; }]>; 1314defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1315 [{ return ((uint64_t)Imm) < 2; }]>; 1316 1317def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1318def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1319def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1320def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1321def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1322 1323defm sve_elm_idx_extdup_b 1324 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1325 [{ return ((uint64_t)Imm) < 64; }]>; 1326defm sve_elm_idx_extdup_h 1327 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1328 [{ return ((uint64_t)Imm) < 32; }]>; 1329defm sve_elm_idx_extdup_s 1330 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1331 [{ return ((uint64_t)Imm) < 16; }]>; 1332defm sve_elm_idx_extdup_d 1333 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1334 [{ return ((uint64_t)Imm) < 8; }]>; 1335defm sve_elm_idx_extdup_q 1336 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1337 [{ return ((uint64_t)Imm) < 4; }]>; 1338 1339def sme_elm_idx0_0 : Operand<i64>, ImmLeaf<i64, [{ 1340 return ((uint64_t)Imm) == 0; 1341}]> { 1342 let ParserMatchClass = Imm0_0Operand; 1343 let PrintMethod = "printMatrixIndex"; 1344 let OperandNamespace = "AArch64"; 1345 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1346} 1347def sme_elm_idx0_1 : Operand<i64>, ImmLeaf<i64, [{ 1348 return ((uint64_t)Imm) <= 1; 1349}]> { 1350 let ParserMatchClass = Imm0_1Operand; 1351 let PrintMethod = "printMatrixIndex"; 1352} 1353def sme_elm_idx0_3 : Operand<i64>, ImmLeaf<i64, [{ 1354 return ((uint64_t)Imm) <= 3; 1355}]> { 1356 let ParserMatchClass = Imm0_3Operand; 1357 let PrintMethod = "printMatrixIndex"; 1358} 1359def sme_elm_idx0_7 : Operand<i64>, ImmLeaf<i64, [{ 1360 return ((uint64_t)Imm) <= 7; 1361}]> { 1362 let ParserMatchClass = Imm0_7Operand; 1363 let PrintMethod = "printMatrixIndex"; 1364} 1365def sme_elm_idx0_15 : Operand<i64>, ImmLeaf<i64, [{ 1366 return ((uint64_t)Imm) <= 15; 1367}]> { 1368 let ParserMatchClass = Imm0_15Operand; 1369 let PrintMethod = "printMatrixIndex"; 1370} 1371 1372// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1373// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1374// are encoded as the eight bit value 'abcdefgh'. 1375def simdimmtype10 : Operand<i32>, 1376 FPImmLeaf<f64, [{ 1377 return AArch64_AM::isAdvSIMDModImmType10( 1378 Imm.bitcastToAPInt().getZExtValue()); 1379 }], SDNodeXForm<fpimm, [{ 1380 APFloat InVal = N->getValueAPF(); 1381 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1382 .bitcastToAPInt() 1383 .getZExtValue()); 1384 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1385 }]>> { 1386 let ParserMatchClass = SIMDImmType10Operand; 1387 let PrintMethod = "printSIMDType10Operand"; 1388} 1389 1390 1391//--- 1392// System management 1393//--- 1394 1395// Base encoding for system instruction operands. 1396let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1397class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1398 list<dag> pattern = []> 1399 : I<oops, iops, asm, operands, "", pattern> { 1400 let Inst{31-22} = 0b1101010100; 1401 let Inst{21} = L; 1402} 1403 1404// System instructions which do not have an Rt register. 1405class SimpleSystemI<bit L, dag iops, string asm, string operands, 1406 list<dag> pattern = []> 1407 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1408 let Inst{4-0} = 0b11111; 1409} 1410 1411// System instructions which have an Rt register. 1412class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1413 list<dag> pattern = []> 1414 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1415 Sched<[WriteSys]> { 1416 bits<5> Rt; 1417 let Inst{4-0} = Rt; 1418} 1419 1420// System instructions for transactional memory extension 1421class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1422 string asm, string operands, list<dag> pattern> 1423 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1424 Sched<[WriteSys]> { 1425 let Inst{20-12} = 0b000110011; 1426 let Inst{11-8} = CRm; 1427 let Inst{7-5} = op2; 1428 let DecoderMethod = ""; 1429 1430 let mayLoad = 1; 1431 let mayStore = 1; 1432} 1433 1434// System instructions for transactional memory - single input operand 1435class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1436 : TMBaseSystemI<0b1, CRm, 0b011, 1437 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1438 bits<5> Rt; 1439 let Inst{4-0} = Rt; 1440} 1441 1442// System instructions that pass a register argument 1443// This class assumes the register is for input rather than output. 1444class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1445 list<dag> pattern = []> 1446 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1447 let Inst{20-12} = 0b000110001; 1448 let Inst{11-8} = CRm; 1449 let Inst{7-5} = Op2; 1450} 1451 1452// System instructions for transactional memory - no operand 1453class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1454 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1455 let Inst{4-0} = 0b11111; 1456} 1457 1458// System instructions for exit from transactions 1459class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1460 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1461 Sched<[WriteSys]> { 1462 bits<16> imm; 1463 let Inst{31-24} = 0b11010100; 1464 let Inst{23-21} = op1; 1465 let Inst{20-5} = imm; 1466 let Inst{4-0} = 0b00000; 1467} 1468 1469// Hint instructions that take both a CRm and a 3-bit immediate. 1470// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1471// model patterns with sufficiently fine granularity 1472let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1473 class HintI<string mnemonic> 1474 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1475 [(int_aarch64_hint imm0_127:$imm)]>, 1476 Sched<[WriteHint]> { 1477 bits <7> imm; 1478 let Inst{20-12} = 0b000110010; 1479 let Inst{11-5} = imm; 1480 } 1481 1482// System instructions taking a single literal operand which encodes into 1483// CRm. op2 differentiates the opcodes. 1484def BarrierAsmOperand : AsmOperandClass { 1485 let Name = "Barrier"; 1486 let ParserMethod = "tryParseBarrierOperand"; 1487} 1488def barrier_op : Operand<i32> { 1489 let PrintMethod = "printBarrierOption"; 1490 let ParserMatchClass = BarrierAsmOperand; 1491} 1492def BarriernXSAsmOperand : AsmOperandClass { 1493 let Name = "BarriernXS"; 1494 let ParserMethod = "tryParseBarriernXSOperand"; 1495} 1496def barrier_nxs_op : Operand<i32> { 1497 let PrintMethod = "printBarriernXSOption"; 1498 let ParserMatchClass = BarriernXSAsmOperand; 1499} 1500class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1501 list<dag> pattern = []> 1502 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1503 Sched<[WriteBarrier]> { 1504 bits<4> CRm; 1505 let Inst{20-12} = 0b000110011; 1506 let Inst{11-8} = CRm; 1507 let Inst{7-5} = opc; 1508} 1509 1510class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1511 : SimpleSystemI<0, (ins), asm, "", pattern>, 1512 Sched<[WriteHint]> { 1513 bits<4> CRm; 1514 let CRm = 0b0011; 1515 let Inst{31-12} = 0b11010101000000110010; 1516 let Inst{11-8} = CRm; 1517 let Inst{7-5} = op2; 1518 let Inst{4-0} = 0b11111; 1519} 1520 1521// MRS/MSR system instructions. These have different operand classes because 1522// a different subset of registers can be accessed through each instruction. 1523def MRSSystemRegisterOperand : AsmOperandClass { 1524 let Name = "MRSSystemRegister"; 1525 let ParserMethod = "tryParseSysReg"; 1526 let DiagnosticType = "MRS"; 1527} 1528// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1529def mrs_sysreg_op : Operand<i32> { 1530 let ParserMatchClass = MRSSystemRegisterOperand; 1531 let DecoderMethod = "DecodeMRSSystemRegister"; 1532 let PrintMethod = "printMRSSystemRegister"; 1533} 1534 1535def MSRSystemRegisterOperand : AsmOperandClass { 1536 let Name = "MSRSystemRegister"; 1537 let ParserMethod = "tryParseSysReg"; 1538 let DiagnosticType = "MSR"; 1539} 1540def msr_sysreg_op : Operand<i32> { 1541 let ParserMatchClass = MSRSystemRegisterOperand; 1542 let DecoderMethod = "DecodeMSRSystemRegister"; 1543 let PrintMethod = "printMSRSystemRegister"; 1544} 1545 1546def PSBHintOperand : AsmOperandClass { 1547 let Name = "PSBHint"; 1548 let ParserMethod = "tryParsePSBHint"; 1549} 1550def psbhint_op : Operand<i32> { 1551 let ParserMatchClass = PSBHintOperand; 1552 let PrintMethod = "printPSBHintOp"; 1553 let MCOperandPredicate = [{ 1554 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1555 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1556 if (!MCOp.isImm()) 1557 return false; 1558 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1559 }]; 1560} 1561 1562def BTIHintOperand : AsmOperandClass { 1563 let Name = "BTIHint"; 1564 let ParserMethod = "tryParseBTIHint"; 1565} 1566def btihint_op : Operand<i32> { 1567 let ParserMatchClass = BTIHintOperand; 1568 let PrintMethod = "printBTIHintOp"; 1569 let MCOperandPredicate = [{ 1570 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1571 if (!MCOp.isImm()) 1572 return false; 1573 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1574 }]; 1575} 1576 1577class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1578 "mrs", "\t$Rt, $systemreg"> { 1579 bits<16> systemreg; 1580 let Inst{20-5} = systemreg; 1581 let DecoderNamespace = "Fallback"; 1582 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1583 // require doing this. The alternative was to explicitly model each one, but 1584 // it feels like it is unnecessary because it seems there are no negative 1585 // consequences setting these flags for all. 1586 let Defs = [NZCV]; 1587} 1588 1589// FIXME: Some of these def NZCV, others don't. Best way to model that? 1590// Explicitly modeling each of the system register as a register class 1591// would do it, but feels like overkill at this point. 1592class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1593 "msr", "\t$systemreg, $Rt"> { 1594 bits<16> systemreg; 1595 let Inst{20-5} = systemreg; 1596 let DecoderNamespace = "Fallback"; 1597} 1598 1599def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1600 let Name = "SystemPStateFieldWithImm0_15"; 1601 let ParserMethod = "tryParseSysReg"; 1602} 1603def pstatefield4_op : Operand<i32> { 1604 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1605 let PrintMethod = "printSystemPStateField"; 1606} 1607 1608// Instructions to modify PSTATE, no input reg 1609let Defs = [NZCV] in 1610class PstateWriteSimple<dag iops, string asm, string operands> 1611 : SimpleSystemI<0, iops, asm, operands> { 1612 1613 let Inst{20-19} = 0b00; 1614 let Inst{15-12} = 0b0100; 1615} 1616 1617class MSRpstateImm0_15 1618 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1619 "\t$pstatefield, $imm">, 1620 Sched<[WriteSys]> { 1621 1622 bits<6> pstatefield; 1623 bits<4> imm; 1624 let Inst{18-16} = pstatefield{5-3}; 1625 let Inst{11-8} = imm; 1626 let Inst{7-5} = pstatefield{2-0}; 1627 1628 let DecoderMethod = "DecodeSystemPStateInstruction"; 1629 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1630 // Fail the decoder should attempt to decode the instruction as MSRI. 1631 let hasCompleteDecoder = 0; 1632} 1633 1634def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1635 let Name = "SystemPStateFieldWithImm0_1"; 1636 let ParserMethod = "tryParseSysReg"; 1637} 1638def pstatefield1_op : Operand<i32> { 1639 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1640 let PrintMethod = "printSystemPStateField"; 1641} 1642 1643class MSRpstateImm0_1 1644 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1645 "\t$pstatefield, $imm">, 1646 Sched<[WriteSys]> { 1647 1648 bits<6> pstatefield; 1649 bit imm; 1650 let Inst{18-16} = pstatefield{5-3}; 1651 let Inst{11-9} = 0b000; 1652 let Inst{8} = imm; 1653 let Inst{7-5} = pstatefield{2-0}; 1654 1655 let DecoderMethod = "DecodeSystemPStateInstruction"; 1656 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1657 // Fail the decoder should attempt to decode the instruction as MSRI. 1658 let hasCompleteDecoder = 0; 1659} 1660 1661// SYS and SYSL generic system instructions. 1662def SysCRAsmOperand : AsmOperandClass { 1663 let Name = "SysCR"; 1664 let ParserMethod = "tryParseSysCROperand"; 1665} 1666 1667def sys_cr_op : Operand<i32> { 1668 let PrintMethod = "printSysCROperand"; 1669 let ParserMatchClass = SysCRAsmOperand; 1670} 1671 1672class SystemXtI<bit L, string asm> 1673 : RtSystemI<L, (outs), 1674 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1675 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1676 bits<3> op1; 1677 bits<4> Cn; 1678 bits<4> Cm; 1679 bits<3> op2; 1680 let Inst{20-19} = 0b01; 1681 let Inst{18-16} = op1; 1682 let Inst{15-12} = Cn; 1683 let Inst{11-8} = Cm; 1684 let Inst{7-5} = op2; 1685} 1686 1687class SystemLXtI<bit L, string asm> 1688 : RtSystemI<L, (outs), 1689 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1690 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1691 bits<3> op1; 1692 bits<4> Cn; 1693 bits<4> Cm; 1694 bits<3> op2; 1695 let Inst{20-19} = 0b01; 1696 let Inst{18-16} = op1; 1697 let Inst{15-12} = Cn; 1698 let Inst{11-8} = Cm; 1699 let Inst{7-5} = op2; 1700} 1701 1702 1703// Branch (register) instructions: 1704// 1705// case opc of 1706// 0001 blr 1707// 0000 br 1708// 0101 dret 1709// 0100 eret 1710// 0010 ret 1711// otherwise UNDEFINED 1712class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1713 string operands, list<dag> pattern> 1714 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1715 let Inst{31-25} = 0b1101011; 1716 let Inst{24-21} = opc; 1717 let Inst{20-16} = 0b11111; 1718 let Inst{15-10} = 0b000000; 1719 let Inst{4-0} = 0b00000; 1720} 1721 1722class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1723 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1724 bits<5> Rn; 1725 let Inst{9-5} = Rn; 1726} 1727 1728let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1729class SpecialReturn<bits<4> opc, string asm> 1730 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1731 let Inst{9-5} = 0b11111; 1732} 1733 1734let mayLoad = 1 in 1735class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1736 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1737 Sched<[]> { 1738 bits<5> Rn; 1739 bits<5> Rt; 1740 let Inst{31-30} = sz; 1741 let Inst{29-10} = 0b11100010111111110000; 1742 let Inst{9-5} = Rn; 1743 let Inst{4-0} = Rt; 1744} 1745 1746class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1747 list<dag> pattern> 1748 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1749 let isAuthenticated = 1; 1750 let Inst{31-25} = 0b1101011; 1751 let Inst{20-11} = 0b1111100001; 1752 let Inst{10} = M; 1753 let Inst{4-0} = 0b11111; 1754} 1755 1756class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1757 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1758 bits<5> Rn; 1759 bits<5> Rm; 1760 let Inst{24-22} = 0b100; 1761 let Inst{21} = op; 1762 let Inst{9-5} = Rn; 1763 let Inst{4-0} = Rm; 1764} 1765 1766class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1767 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1768 bits<5> Rn; 1769 let Inst{24} = 0; 1770 let Inst{23-21} = opc; 1771 let Inst{9-5} = Rn; 1772} 1773 1774let Uses = [LR,SP] in 1775class AuthReturn<bits<3> op, bits<1> M, string asm> 1776 : AuthBase<M, (outs), (ins), asm, "", []> { 1777 let Inst{24} = 0; 1778 let Inst{23-21} = op; 1779 let Inst{9-0} = 0b1111111111; 1780} 1781 1782let mayLoad = 1 in 1783class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1784 string operands, string cstr> 1785 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1786 bits<10> offset; 1787 bits<5> Rn; 1788 bits<5> Rt; 1789 let isAuthenticated = 1; 1790 let Inst{31-24} = 0b11111000; 1791 let Inst{23} = M; 1792 let Inst{22} = offset{9}; 1793 let Inst{21} = 1; 1794 let Inst{20-12} = offset{8-0}; 1795 let Inst{11} = W; 1796 let Inst{10} = 1; 1797 let Inst{9-5} = Rn; 1798 let Inst{4-0} = Rt; 1799 1800 let DecoderMethod = "DecodeAuthLoadInstruction"; 1801} 1802 1803multiclass AuthLoad<bit M, string asm, Operand opr> { 1804 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1805 (ins GPR64sp:$Rn, opr:$offset), 1806 asm, "\t$Rt, [$Rn, $offset]", "">; 1807 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1808 (ins GPR64sp:$Rn, opr:$offset), 1809 asm, "\t$Rt, [$Rn, $offset]!", 1810 "$Rn = $wback,@earlyclobber $wback">; 1811 1812 def : InstAlias<asm # "\t$Rt, [$Rn]", 1813 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1814 1815 def : InstAlias<asm # "\t$Rt, [$wback]!", 1816 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1817} 1818 1819//--- 1820// Conditional branch instruction. 1821//--- 1822 1823// Condition code. 1824// 4-bit immediate. Pretty-printed as <cc> 1825def ccode : Operand<i32> { 1826 let PrintMethod = "printCondCode"; 1827 let ParserMatchClass = CondCode; 1828} 1829def inv_ccode : Operand<i32> { 1830 // AL and NV are invalid in the aliases which use inv_ccode 1831 let PrintMethod = "printInverseCondCode"; 1832 let ParserMatchClass = CondCode; 1833 let MCOperandPredicate = [{ 1834 return MCOp.isImm() && 1835 MCOp.getImm() != AArch64CC::AL && 1836 MCOp.getImm() != AArch64CC::NV; 1837 }]; 1838} 1839 1840// Conditional branch target. 19-bit immediate. The low two bits of the target 1841// offset are implied zero and so are not part of the immediate. 1842def am_brcond : Operand<OtherVT> { 1843 let EncoderMethod = "getCondBranchTargetOpValue"; 1844 let DecoderMethod = "DecodePCRelLabel19"; 1845 let PrintMethod = "printAlignedLabel"; 1846 let ParserMatchClass = PCRelLabel19Operand; 1847 let OperandType = "OPERAND_PCREL"; 1848} 1849 1850class BranchCond<bit bit4, string mnemonic> 1851 : I<(outs), (ins ccode:$cond, am_brcond:$target), 1852 mnemonic, ".$cond\t$target", "", 1853 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 1854 let isBranch = 1; 1855 let isTerminator = 1; 1856 let Uses = [NZCV]; 1857 1858 bits<4> cond; 1859 bits<19> target; 1860 let Inst{31-24} = 0b01010100; 1861 let Inst{23-5} = target; 1862 let Inst{4} = bit4; 1863 let Inst{3-0} = cond; 1864} 1865 1866//--- 1867// Compare-and-branch instructions. 1868//--- 1869class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1870 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1871 asm, "\t$Rt, $target", "", 1872 [(node regtype:$Rt, bb:$target)]>, 1873 Sched<[WriteBr]> { 1874 let isBranch = 1; 1875 let isTerminator = 1; 1876 1877 bits<5> Rt; 1878 bits<19> target; 1879 let Inst{30-25} = 0b011010; 1880 let Inst{24} = op; 1881 let Inst{23-5} = target; 1882 let Inst{4-0} = Rt; 1883} 1884 1885multiclass CmpBranch<bit op, string asm, SDNode node> { 1886 def W : BaseCmpBranch<GPR32, op, asm, node> { 1887 let Inst{31} = 0; 1888 } 1889 def X : BaseCmpBranch<GPR64, op, asm, node> { 1890 let Inst{31} = 1; 1891 } 1892} 1893 1894//--- 1895// Test-bit-and-branch instructions. 1896//--- 1897// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1898// the target offset are implied zero and so are not part of the immediate. 1899def am_tbrcond : Operand<OtherVT> { 1900 let EncoderMethod = "getTestBranchTargetOpValue"; 1901 let PrintMethod = "printAlignedLabel"; 1902 let ParserMatchClass = BranchTarget14Operand; 1903 let OperandType = "OPERAND_PCREL"; 1904} 1905 1906// AsmOperand classes to emit (or not) special diagnostics 1907def TBZImm0_31Operand : AsmOperandClass { 1908 let Name = "TBZImm0_31"; 1909 let PredicateMethod = "isImmInRange<0,31>"; 1910 let RenderMethod = "addImmOperands"; 1911} 1912def TBZImm32_63Operand : AsmOperandClass { 1913 let Name = "Imm32_63"; 1914 let PredicateMethod = "isImmInRange<32,63>"; 1915 let DiagnosticType = "InvalidImm0_63"; 1916 let RenderMethod = "addImmOperands"; 1917} 1918 1919class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1920 return (((uint32_t)Imm) < 32); 1921}]> { 1922 let ParserMatchClass = matcher; 1923} 1924 1925def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1926def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1927 1928def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1929 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1930}]> { 1931 let ParserMatchClass = TBZImm32_63Operand; 1932} 1933 1934class BaseTestBranch<RegisterClass regtype, Operand immtype, 1935 bit op, string asm, SDNode node> 1936 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1937 asm, "\t$Rt, $bit_off, $target", "", 1938 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1939 Sched<[WriteBr]> { 1940 let isBranch = 1; 1941 let isTerminator = 1; 1942 1943 bits<5> Rt; 1944 bits<6> bit_off; 1945 bits<14> target; 1946 1947 let Inst{30-25} = 0b011011; 1948 let Inst{24} = op; 1949 let Inst{23-19} = bit_off{4-0}; 1950 let Inst{18-5} = target; 1951 let Inst{4-0} = Rt; 1952 1953 let DecoderMethod = "DecodeTestAndBranch"; 1954} 1955 1956multiclass TestBranch<bit op, string asm, SDNode node> { 1957 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1958 let Inst{31} = 0; 1959 } 1960 1961 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1962 let Inst{31} = 1; 1963 } 1964 1965 // Alias X-reg with 0-31 imm to W-Reg. 1966 def : InstAlias<asm # "\t$Rd, $imm, $target", 1967 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1968 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1969 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1970 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1971 tbz_imm0_31_diag:$imm, bb:$target)>; 1972} 1973 1974//--- 1975// Unconditional branch (immediate) instructions. 1976//--- 1977def am_b_target : Operand<OtherVT> { 1978 let EncoderMethod = "getBranchTargetOpValue"; 1979 let PrintMethod = "printAlignedLabel"; 1980 let ParserMatchClass = BranchTarget26Operand; 1981 let OperandType = "OPERAND_PCREL"; 1982} 1983def am_bl_target : Operand<i64> { 1984 let EncoderMethod = "getBranchTargetOpValue"; 1985 let PrintMethod = "printAlignedLabel"; 1986 let ParserMatchClass = BranchTarget26Operand; 1987 let OperandType = "OPERAND_PCREL"; 1988} 1989 1990class BImm<bit op, dag iops, string asm, list<dag> pattern> 1991 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1992 bits<26> addr; 1993 let Inst{31} = op; 1994 let Inst{30-26} = 0b00101; 1995 let Inst{25-0} = addr; 1996 1997 let DecoderMethod = "DecodeUnconditionalBranch"; 1998} 1999 2000class BranchImm<bit op, string asm, list<dag> pattern> 2001 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 2002class CallImm<bit op, string asm, list<dag> pattern> 2003 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 2004 2005//--- 2006// Basic one-operand data processing instructions. 2007//--- 2008 2009let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2010class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 2011 SDPatternOperator node> 2012 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 2013 [(set regtype:$Rd, (node regtype:$Rn))]>, 2014 Sched<[WriteI, ReadI]> { 2015 bits<5> Rd; 2016 bits<5> Rn; 2017 2018 let Inst{30-13} = 0b101101011000000000; 2019 let Inst{12-10} = opc; 2020 let Inst{9-5} = Rn; 2021 let Inst{4-0} = Rd; 2022} 2023 2024let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2025multiclass OneOperandData<bits<3> opc, string asm, 2026 SDPatternOperator node = null_frag> { 2027 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 2028 let Inst{31} = 0; 2029 } 2030 2031 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 2032 let Inst{31} = 1; 2033 } 2034} 2035 2036class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 2037 : BaseOneOperandData<opc, GPR32, asm, node> { 2038 let Inst{31} = 0; 2039} 2040 2041class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 2042 : BaseOneOperandData<opc, GPR64, asm, node> { 2043 let Inst{31} = 1; 2044} 2045 2046class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2047 SDPatternOperator op> 2048 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2049 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2050 Sched<[WriteI, ReadI]> { 2051 bits<5> Rd; 2052 bits<5> Rn; 2053 let Inst{31-15} = 0b11011010110000010; 2054 let Inst{14-12} = opcode_prefix; 2055 let Inst{11-10} = opcode; 2056 let Inst{9-5} = Rn; 2057 let Inst{4-0} = Rd; 2058} 2059 2060class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2061 SDPatternOperator op> 2062 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2063 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2064 Sched<[]> { 2065 bits<5> Rd; 2066 let Inst{31-15} = 0b11011010110000010; 2067 let Inst{14-12} = opcode_prefix; 2068 let Inst{11-10} = opcode; 2069 let Inst{9-5} = 0b11111; 2070 let Inst{4-0} = Rd; 2071} 2072 2073class SignAuthTwoOperand<bits<4> opc, string asm, 2074 SDPatternOperator OpNode> 2075 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2076 asm, "\t$Rd, $Rn, $Rm", "", 2077 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2078 Sched<[WriteI, ReadI, ReadI]> { 2079 bits<5> Rd; 2080 bits<5> Rn; 2081 bits<5> Rm; 2082 let Inst{31-21} = 0b10011010110; 2083 let Inst{20-16} = Rm; 2084 let Inst{15-14} = 0b00; 2085 let Inst{13-10} = opc; 2086 let Inst{9-5} = Rn; 2087 let Inst{4-0} = Rd; 2088} 2089 2090class ClearAuth<bits<1> data, string asm> 2091 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2092 bits<5> Rd; 2093 let Inst{31-11} = 0b110110101100000101000; 2094 let Inst{10} = data; 2095 let Inst{9-5} = 0b11111; 2096 let Inst{4-0} = Rd; 2097} 2098 2099// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2100class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2101 : I<(outs), iops, asm, ops, "", []>, 2102 Sched<[WriteI, ReadI, ReadI]> { 2103 let Uses = [NZCV]; 2104 let Defs = [NZCV]; 2105 bits<5> Rn; 2106 let Inst{31} = sf; 2107 let Inst{30-15} = 0b0111010000000000; 2108 let Inst{14} = sz; 2109 let Inst{13-10} = 0b0010; 2110 let Inst{9-5} = Rn; 2111 let Inst{4-0} = 0b01101; 2112} 2113 2114class FlagRotate<dag iops, string asm, string ops> 2115 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2116 bits<6> imm; 2117 bits<4> mask; 2118 let Inst{20-15} = imm; 2119 let Inst{13-10} = 0b0001; 2120 let Inst{4} = 0b0; 2121 let Inst{3-0} = mask; 2122} 2123 2124//--- 2125// Basic two-operand data processing instructions. 2126//--- 2127class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2128 list<dag> pattern> 2129 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2130 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2131 Sched<[WriteI, ReadI, ReadI]> { 2132 let Uses = [NZCV]; 2133 bits<5> Rd; 2134 bits<5> Rn; 2135 bits<5> Rm; 2136 let Inst{30} = isSub; 2137 let Inst{28-21} = 0b11010000; 2138 let Inst{20-16} = Rm; 2139 let Inst{15-10} = 0; 2140 let Inst{9-5} = Rn; 2141 let Inst{4-0} = Rd; 2142} 2143 2144class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2145 SDNode OpNode> 2146 : BaseBaseAddSubCarry<isSub, regtype, asm, 2147 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2148 2149class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2150 SDNode OpNode> 2151 : BaseBaseAddSubCarry<isSub, regtype, asm, 2152 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2153 (implicit NZCV)]> { 2154 let Defs = [NZCV]; 2155} 2156 2157multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2158 SDNode OpNode, SDNode OpNode_setflags> { 2159 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2160 let Inst{31} = 0; 2161 let Inst{29} = 0; 2162 } 2163 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2164 let Inst{31} = 1; 2165 let Inst{29} = 0; 2166 } 2167 2168 // Sets flags. 2169 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2170 OpNode_setflags> { 2171 let Inst{31} = 0; 2172 let Inst{29} = 1; 2173 } 2174 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2175 OpNode_setflags> { 2176 let Inst{31} = 1; 2177 let Inst{29} = 1; 2178 } 2179} 2180 2181class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2182 SDPatternOperator OpNode, 2183 RegisterClass in1regtype = regtype, 2184 RegisterClass in2regtype = regtype> 2185 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2186 asm, "\t$Rd, $Rn, $Rm", "", 2187 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2188 bits<5> Rd; 2189 bits<5> Rn; 2190 bits<5> Rm; 2191 let Inst{30-21} = 0b0011010110; 2192 let Inst{20-16} = Rm; 2193 let Inst{15-14} = 0b00; 2194 let Inst{13-10} = opc; 2195 let Inst{9-5} = Rn; 2196 let Inst{4-0} = Rd; 2197} 2198 2199class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2200 SDPatternOperator OpNode> 2201 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2202 let Inst{10} = isSigned; 2203} 2204 2205multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2206 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2207 Sched<[WriteID32, ReadID, ReadID]> { 2208 let Inst{31} = 0; 2209 } 2210 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2211 Sched<[WriteID64, ReadID, ReadID]> { 2212 let Inst{31} = 1; 2213 } 2214} 2215 2216class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2217 SDPatternOperator OpNode = null_frag> 2218 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2219 Sched<[WriteIS, ReadI]> { 2220 let Inst{11-10} = shift_type; 2221} 2222 2223multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2224 def Wr : BaseShift<shift_type, GPR32, asm> { 2225 let Inst{31} = 0; 2226 } 2227 2228 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2229 let Inst{31} = 1; 2230 } 2231 2232 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2233 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2234 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2235 2236 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2237 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2238 2239 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2240 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2241 2242 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2243 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2244 2245 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2246 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2247 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2248 2249 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2250 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2251 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2252} 2253 2254class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2255 : InstAlias<asm#"\t$dst, $src1, $src2", 2256 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2257 2258class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2259 RegisterClass addtype, string asm, 2260 list<dag> pattern> 2261 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2262 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2263 bits<5> Rd; 2264 bits<5> Rn; 2265 bits<5> Rm; 2266 bits<5> Ra; 2267 let Inst{30-24} = 0b0011011; 2268 let Inst{23-21} = opc; 2269 let Inst{20-16} = Rm; 2270 let Inst{15} = isSub; 2271 let Inst{14-10} = Ra; 2272 let Inst{9-5} = Rn; 2273 let Inst{4-0} = Rd; 2274} 2275 2276multiclass MulAccum<bit isSub, string asm> { 2277 // MADD/MSUB generation is decided by MachineCombiner.cpp 2278 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2279 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2280 let Inst{31} = 0; 2281 } 2282 2283 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2284 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2285 let Inst{31} = 1; 2286 } 2287} 2288 2289class WideMulAccum<bit isSub, bits<3> opc, string asm, 2290 SDNode AccNode, SDNode ExtNode> 2291 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2292 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2293 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2294 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2295 let Inst{31} = 1; 2296} 2297 2298class MulHi<bits<3> opc, string asm, SDNode OpNode> 2299 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2300 asm, "\t$Rd, $Rn, $Rm", "", 2301 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2302 Sched<[WriteIM64, ReadIM, ReadIM]> { 2303 bits<5> Rd; 2304 bits<5> Rn; 2305 bits<5> Rm; 2306 let Inst{31-24} = 0b10011011; 2307 let Inst{23-21} = opc; 2308 let Inst{20-16} = Rm; 2309 let Inst{15} = 0; 2310 let Inst{9-5} = Rn; 2311 let Inst{4-0} = Rd; 2312 2313 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2314 // (i.e. all bits 1) but is ignored by the processor. 2315 let PostEncoderMethod = "fixMulHigh"; 2316} 2317 2318class MulAccumWAlias<string asm, Instruction inst> 2319 : InstAlias<asm#"\t$dst, $src1, $src2", 2320 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2321class MulAccumXAlias<string asm, Instruction inst> 2322 : InstAlias<asm#"\t$dst, $src1, $src2", 2323 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2324class WideMulAccumAlias<string asm, Instruction inst> 2325 : InstAlias<asm#"\t$dst, $src1, $src2", 2326 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2327 2328class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2329 SDPatternOperator OpNode, string asm> 2330 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2331 asm, "\t$Rd, $Rn, $Rm", "", 2332 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2333 Sched<[WriteISReg, ReadI, ReadISReg]> { 2334 bits<5> Rd; 2335 bits<5> Rn; 2336 bits<5> Rm; 2337 2338 let Inst{31} = sf; 2339 let Inst{30-21} = 0b0011010110; 2340 let Inst{20-16} = Rm; 2341 let Inst{15-13} = 0b010; 2342 let Inst{12} = C; 2343 let Inst{11-10} = sz; 2344 let Inst{9-5} = Rn; 2345 let Inst{4-0} = Rd; 2346 let Predicates = [HasCRC]; 2347} 2348 2349//--- 2350// Address generation. 2351//--- 2352 2353class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2354 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2355 pattern>, 2356 Sched<[WriteI]> { 2357 bits<5> Xd; 2358 bits<21> label; 2359 let Inst{31} = page; 2360 let Inst{30-29} = label{1-0}; 2361 let Inst{28-24} = 0b10000; 2362 let Inst{23-5} = label{20-2}; 2363 let Inst{4-0} = Xd; 2364 2365 let DecoderMethod = "DecodeAdrInstruction"; 2366} 2367 2368//--- 2369// Move immediate. 2370//--- 2371 2372def movimm32_imm : Operand<i32> { 2373 let ParserMatchClass = AsmImmRange<0, 65535>; 2374 let EncoderMethod = "getMoveWideImmOpValue"; 2375 let PrintMethod = "printImm"; 2376} 2377def movimm32_shift : Operand<i32> { 2378 let PrintMethod = "printShifter"; 2379 let ParserMatchClass = MovImm32ShifterOperand; 2380} 2381def movimm64_shift : Operand<i32> { 2382 let PrintMethod = "printShifter"; 2383 let ParserMatchClass = MovImm64ShifterOperand; 2384} 2385 2386let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2387class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2388 string asm> 2389 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2390 asm, "\t$Rd, $imm$shift", "", []>, 2391 Sched<[WriteImm]> { 2392 bits<5> Rd; 2393 bits<16> imm; 2394 bits<6> shift; 2395 let Inst{30-29} = opc; 2396 let Inst{28-23} = 0b100101; 2397 let Inst{22-21} = shift{5-4}; 2398 let Inst{20-5} = imm; 2399 let Inst{4-0} = Rd; 2400 2401 let DecoderMethod = "DecodeMoveImmInstruction"; 2402} 2403 2404multiclass MoveImmediate<bits<2> opc, string asm> { 2405 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2406 let Inst{31} = 0; 2407 } 2408 2409 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2410 let Inst{31} = 1; 2411 } 2412} 2413 2414let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2415class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2416 string asm> 2417 : I<(outs regtype:$Rd), 2418 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2419 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2420 Sched<[WriteI, ReadI]> { 2421 bits<5> Rd; 2422 bits<16> imm; 2423 bits<6> shift; 2424 let Inst{30-29} = opc; 2425 let Inst{28-23} = 0b100101; 2426 let Inst{22-21} = shift{5-4}; 2427 let Inst{20-5} = imm; 2428 let Inst{4-0} = Rd; 2429 2430 let DecoderMethod = "DecodeMoveImmInstruction"; 2431} 2432 2433multiclass InsertImmediate<bits<2> opc, string asm> { 2434 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2435 let Inst{31} = 0; 2436 } 2437 2438 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2439 let Inst{31} = 1; 2440 } 2441} 2442 2443//--- 2444// Add/Subtract 2445//--- 2446 2447class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2448 string asm_inst, string asm_ops, 2449 dag inputs, dag pattern> 2450 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2451 Sched<[WriteI, ReadI]> { 2452 bits<5> Rd; 2453 bits<5> Rn; 2454 let Inst{30} = isSub; 2455 let Inst{29} = setFlags; 2456 let Inst{28-24} = 0b10001; 2457 let Inst{9-5} = Rn; 2458 let Inst{4-0} = Rd; 2459} 2460 2461class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2462 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2463 string asm_inst, SDPatternOperator OpNode> 2464 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2465 (ins srcRegtype:$Rn, immtype:$imm), 2466 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2467 bits<14> imm; 2468 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2469 let Inst{21-10} = imm{11-0}; 2470 let DecoderMethod = "DecodeAddSubImmShift"; 2471} 2472 2473class BaseAddSubRegPseudo<RegisterClass regtype, 2474 SDPatternOperator OpNode> 2475 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2476 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2477 Sched<[WriteI, ReadI, ReadI]>; 2478 2479class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2480 arith_shifted_reg shifted_regtype, string asm, 2481 SDPatternOperator OpNode> 2482 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2483 asm, "\t$Rd, $Rn, $Rm", "", 2484 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2485 Sched<[WriteISReg, ReadI, ReadISReg]> { 2486 // The operands are in order to match the 'addr' MI operands, so we 2487 // don't need an encoder method and by-name matching. Just use the default 2488 // in-order handling. Since we're using by-order, make sure the names 2489 // do not match. 2490 bits<5> dst; 2491 bits<5> src1; 2492 bits<5> src2; 2493 bits<8> shift; 2494 let Inst{30} = isSub; 2495 let Inst{29} = setFlags; 2496 let Inst{28-24} = 0b01011; 2497 let Inst{23-22} = shift{7-6}; 2498 let Inst{21} = 0; 2499 let Inst{20-16} = src2; 2500 let Inst{15-10} = shift{5-0}; 2501 let Inst{9-5} = src1; 2502 let Inst{4-0} = dst; 2503 2504 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2505} 2506 2507class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2508 RegisterClass src1Regtype, Operand src2Regtype, 2509 string asm, SDPatternOperator OpNode> 2510 : I<(outs dstRegtype:$R1), 2511 (ins src1Regtype:$R2, src2Regtype:$R3), 2512 asm, "\t$R1, $R2, $R3", "", 2513 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2514 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2515 bits<5> Rd; 2516 bits<5> Rn; 2517 bits<5> Rm; 2518 bits<6> ext; 2519 let Inst{30} = isSub; 2520 let Inst{29} = setFlags; 2521 let Inst{28-24} = 0b01011; 2522 let Inst{23-21} = 0b001; 2523 let Inst{20-16} = Rm; 2524 let Inst{15-13} = ext{5-3}; 2525 let Inst{12-10} = ext{2-0}; 2526 let Inst{9-5} = Rn; 2527 let Inst{4-0} = Rd; 2528 2529 let DecoderMethod = "DecodeAddSubERegInstruction"; 2530} 2531 2532let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2533class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2534 RegisterClass src1Regtype, RegisterClass src2Regtype, 2535 Operand ext_op, string asm> 2536 : I<(outs dstRegtype:$Rd), 2537 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2538 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2539 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2540 bits<5> Rd; 2541 bits<5> Rn; 2542 bits<5> Rm; 2543 bits<6> ext; 2544 let Inst{30} = isSub; 2545 let Inst{29} = setFlags; 2546 let Inst{28-24} = 0b01011; 2547 let Inst{23-21} = 0b001; 2548 let Inst{20-16} = Rm; 2549 let Inst{15} = ext{5}; 2550 let Inst{12-10} = ext{2-0}; 2551 let Inst{9-5} = Rn; 2552 let Inst{4-0} = Rd; 2553 2554 let DecoderMethod = "DecodeAddSubERegInstruction"; 2555} 2556 2557// Aliases for register+register add/subtract. 2558class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2559 RegisterClass src1Regtype, RegisterClass src2Regtype, 2560 int shiftExt> 2561 : InstAlias<asm#"\t$dst, $src1, $src2", 2562 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2563 shiftExt)>; 2564 2565multiclass AddSub<bit isSub, string mnemonic, string alias, 2566 SDPatternOperator OpNode = null_frag> { 2567 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2568 // Add/Subtract immediate 2569 // Increase the weight of the immediate variant to try to match it before 2570 // the extended register variant. 2571 // We used to match the register variant before the immediate when the 2572 // register argument could be implicitly zero-extended. 2573 let AddedComplexity = 6 in 2574 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2575 mnemonic, OpNode> { 2576 let Inst{31} = 0; 2577 } 2578 let AddedComplexity = 6 in 2579 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2580 mnemonic, OpNode> { 2581 let Inst{31} = 1; 2582 } 2583 2584 // Add/Subtract register - Only used for CodeGen 2585 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2586 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2587 2588 // Add/Subtract shifted register 2589 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2590 OpNode> { 2591 let Inst{31} = 0; 2592 } 2593 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2594 OpNode> { 2595 let Inst{31} = 1; 2596 } 2597 } 2598 2599 // Add/Subtract extended register 2600 let AddedComplexity = 1, hasSideEffects = 0 in { 2601 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2602 arith_extended_reg32_i32, mnemonic, OpNode> { 2603 let Inst{31} = 0; 2604 } 2605 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2606 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2607 let Inst{31} = 1; 2608 } 2609 } 2610 2611 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2612 arith_extendlsl64, mnemonic> { 2613 // UXTX and SXTX only. 2614 let Inst{14-13} = 0b11; 2615 let Inst{31} = 1; 2616 } 2617 2618 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2619 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2620 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2621 addsub_shifted_imm32_neg:$imm), 0>; 2622 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2623 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2624 addsub_shifted_imm64_neg:$imm), 0>; 2625 2626 // Register/register aliases with no shift when SP is not used. 2627 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2628 GPR32, GPR32, GPR32, 0>; 2629 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2630 GPR64, GPR64, GPR64, 0>; 2631 2632 // Register/register aliases with no shift when either the destination or 2633 // first source register is SP. 2634 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2635 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2636 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2637 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2638 def : AddSubRegAlias<mnemonic, 2639 !cast<Instruction>(NAME#"Xrx64"), 2640 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2641 def : AddSubRegAlias<mnemonic, 2642 !cast<Instruction>(NAME#"Xrx64"), 2643 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2644} 2645 2646multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2647 string alias, string cmpAlias> { 2648 let isCompare = 1, Defs = [NZCV] in { 2649 // Add/Subtract immediate 2650 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2651 mnemonic, OpNode> { 2652 let Inst{31} = 0; 2653 } 2654 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2655 mnemonic, OpNode> { 2656 let Inst{31} = 1; 2657 } 2658 2659 // Add/Subtract register 2660 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2661 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2662 2663 // Add/Subtract shifted register 2664 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2665 OpNode> { 2666 let Inst{31} = 0; 2667 } 2668 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2669 OpNode> { 2670 let Inst{31} = 1; 2671 } 2672 2673 // Add/Subtract extended register 2674 let AddedComplexity = 1 in { 2675 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2676 arith_extended_reg32_i32, mnemonic, OpNode> { 2677 let Inst{31} = 0; 2678 } 2679 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2680 arith_extended_reg32_i64, mnemonic, OpNode> { 2681 let Inst{31} = 1; 2682 } 2683 } 2684 2685 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2686 arith_extendlsl64, mnemonic> { 2687 // UXTX and SXTX only. 2688 let Inst{14-13} = 0b11; 2689 let Inst{31} = 1; 2690 } 2691 } // Defs = [NZCV] 2692 2693 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2694 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2695 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2696 addsub_shifted_imm32_neg:$imm), 0>; 2697 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2698 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2699 addsub_shifted_imm64_neg:$imm), 0>; 2700 2701 // Compare aliases 2702 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2703 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2704 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2705 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2706 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2707 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2708 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2709 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2710 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2711 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2712 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2713 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2714 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2715 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2716 2717 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2718 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2719 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2720 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2721 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2722 2723 // Compare shorthands 2724 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2725 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2726 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2727 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2728 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2729 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2730 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2731 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2732 2733 // Register/register aliases with no shift when SP is not used. 2734 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2735 GPR32, GPR32, GPR32, 0>; 2736 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2737 GPR64, GPR64, GPR64, 0>; 2738 2739 // Register/register aliases with no shift when the first source register 2740 // is SP. 2741 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2742 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2743 def : AddSubRegAlias<mnemonic, 2744 !cast<Instruction>(NAME#"Xrx64"), 2745 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2746} 2747 2748class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2749 : BaseAddSubImm< 2750 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2751 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2752 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2753 bits<6> imm6; 2754 bits<4> imm4; 2755 let Inst{31} = 1; 2756 let Inst{23-22} = 0b10; 2757 let Inst{21-16} = imm6; 2758 let Inst{15-14} = 0b00; 2759 let Inst{13-10} = imm4; 2760 let Unpredictable{15-14} = 0b11; 2761} 2762 2763class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2764 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2765 let Inst{31} = 1; 2766 let Inst{29} = setsFlags; 2767} 2768 2769//--- 2770// Extract 2771//--- 2772def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2773 SDTCisPtrTy<3>]>; 2774def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2775 2776class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2777 list<dag> patterns> 2778 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2779 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2780 Sched<[WriteExtr, ReadExtrHi]> { 2781 bits<5> Rd; 2782 bits<5> Rn; 2783 bits<5> Rm; 2784 bits<6> imm; 2785 2786 let Inst{30-23} = 0b00100111; 2787 let Inst{21} = 0; 2788 let Inst{20-16} = Rm; 2789 let Inst{15-10} = imm; 2790 let Inst{9-5} = Rn; 2791 let Inst{4-0} = Rd; 2792} 2793 2794multiclass ExtractImm<string asm> { 2795 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2796 [(set GPR32:$Rd, 2797 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2798 let Inst{31} = 0; 2799 let Inst{22} = 0; 2800 // imm<5> must be zero. 2801 let imm{5} = 0; 2802 } 2803 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2804 [(set GPR64:$Rd, 2805 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2806 2807 let Inst{31} = 1; 2808 let Inst{22} = 1; 2809 } 2810} 2811 2812//--- 2813// Bitfield 2814//--- 2815 2816let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2817class BaseBitfieldImm<bits<2> opc, 2818 RegisterClass regtype, Operand imm_type, string asm> 2819 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2820 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2821 Sched<[WriteIS, ReadI]> { 2822 bits<5> Rd; 2823 bits<5> Rn; 2824 bits<6> immr; 2825 bits<6> imms; 2826 2827 let Inst{30-29} = opc; 2828 let Inst{28-23} = 0b100110; 2829 let Inst{21-16} = immr; 2830 let Inst{15-10} = imms; 2831 let Inst{9-5} = Rn; 2832 let Inst{4-0} = Rd; 2833} 2834 2835multiclass BitfieldImm<bits<2> opc, string asm> { 2836 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2837 let Inst{31} = 0; 2838 let Inst{22} = 0; 2839 // imms<5> and immr<5> must be zero, else ReservedValue(). 2840 let Inst{21} = 0; 2841 let Inst{15} = 0; 2842 } 2843 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2844 let Inst{31} = 1; 2845 let Inst{22} = 1; 2846 } 2847} 2848 2849let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2850class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2851 RegisterClass regtype, Operand imm_type, string asm> 2852 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2853 imm_type:$imms), 2854 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2855 Sched<[WriteIS, ReadI]> { 2856 bits<5> Rd; 2857 bits<5> Rn; 2858 bits<6> immr; 2859 bits<6> imms; 2860 2861 let Inst{30-29} = opc; 2862 let Inst{28-23} = 0b100110; 2863 let Inst{21-16} = immr; 2864 let Inst{15-10} = imms; 2865 let Inst{9-5} = Rn; 2866 let Inst{4-0} = Rd; 2867} 2868 2869multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2870 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2871 let Inst{31} = 0; 2872 let Inst{22} = 0; 2873 // imms<5> and immr<5> must be zero, else ReservedValue(). 2874 let Inst{21} = 0; 2875 let Inst{15} = 0; 2876 } 2877 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2878 let Inst{31} = 1; 2879 let Inst{22} = 1; 2880 } 2881} 2882 2883//--- 2884// Logical 2885//--- 2886 2887// Logical (immediate) 2888class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2889 RegisterClass sregtype, Operand imm_type, string asm, 2890 list<dag> pattern> 2891 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2892 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2893 Sched<[WriteI, ReadI]> { 2894 bits<5> Rd; 2895 bits<5> Rn; 2896 bits<13> imm; 2897 let Inst{30-29} = opc; 2898 let Inst{28-23} = 0b100100; 2899 let Inst{22} = imm{12}; 2900 let Inst{21-16} = imm{11-6}; 2901 let Inst{15-10} = imm{5-0}; 2902 let Inst{9-5} = Rn; 2903 let Inst{4-0} = Rd; 2904 2905 let DecoderMethod = "DecodeLogicalImmInstruction"; 2906} 2907 2908// Logical (shifted register) 2909class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2910 logical_shifted_reg shifted_regtype, string asm, 2911 list<dag> pattern> 2912 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2913 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2914 Sched<[WriteISReg, ReadI, ReadISReg]> { 2915 // The operands are in order to match the 'addr' MI operands, so we 2916 // don't need an encoder method and by-name matching. Just use the default 2917 // in-order handling. Since we're using by-order, make sure the names 2918 // do not match. 2919 bits<5> dst; 2920 bits<5> src1; 2921 bits<5> src2; 2922 bits<8> shift; 2923 let Inst{30-29} = opc; 2924 let Inst{28-24} = 0b01010; 2925 let Inst{23-22} = shift{7-6}; 2926 let Inst{21} = N; 2927 let Inst{20-16} = src2; 2928 let Inst{15-10} = shift{5-0}; 2929 let Inst{9-5} = src1; 2930 let Inst{4-0} = dst; 2931 2932 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2933} 2934 2935// Aliases for register+register logical instructions. 2936class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2937 : InstAlias<asm#"\t$dst, $src1, $src2", 2938 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2939 2940multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2941 string Alias> { 2942 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2943 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2944 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2945 logical_imm32:$imm))]> { 2946 let Inst{31} = 0; 2947 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2948 } 2949 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2950 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2951 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2952 logical_imm64:$imm))]> { 2953 let Inst{31} = 1; 2954 } 2955 2956 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2957 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2958 logical_imm32_not:$imm), 0>; 2959 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2960 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2961 logical_imm64_not:$imm), 0>; 2962} 2963 2964multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2965 string Alias> { 2966 let isCompare = 1, Defs = [NZCV] in { 2967 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2968 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2969 let Inst{31} = 0; 2970 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2971 } 2972 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2973 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2974 let Inst{31} = 1; 2975 } 2976 } // end Defs = [NZCV] 2977 2978 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2979 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2980 logical_imm32_not:$imm), 0>; 2981 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2982 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2983 logical_imm64_not:$imm), 0>; 2984} 2985 2986class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2987 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2988 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2989 Sched<[WriteI, ReadI, ReadI]>; 2990 2991// Split from LogicalImm as not all instructions have both. 2992multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2993 SDPatternOperator OpNode> { 2994 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2995 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2996 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2997 } 2998 2999 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3000 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3001 logical_shifted_reg32:$Rm))]> { 3002 let Inst{31} = 0; 3003 } 3004 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3005 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3006 logical_shifted_reg64:$Rm))]> { 3007 let Inst{31} = 1; 3008 } 3009 3010 def : LogicalRegAlias<mnemonic, 3011 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3012 def : LogicalRegAlias<mnemonic, 3013 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3014} 3015 3016// Split from LogicalReg to allow setting NZCV Defs 3017multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3018 SDPatternOperator OpNode = null_frag> { 3019 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3020 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3021 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3022 3023 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3024 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 3025 let Inst{31} = 0; 3026 } 3027 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3028 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 3029 let Inst{31} = 1; 3030 } 3031 } // Defs = [NZCV] 3032 3033 def : LogicalRegAlias<mnemonic, 3034 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3035 def : LogicalRegAlias<mnemonic, 3036 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3037} 3038 3039//--- 3040// Conditionally set flags 3041//--- 3042 3043let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3044class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3045 string mnemonic, SDNode OpNode> 3046 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3047 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3048 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3049 (i32 imm:$cond), NZCV))]>, 3050 Sched<[WriteI, ReadI]> { 3051 let Uses = [NZCV]; 3052 let Defs = [NZCV]; 3053 3054 bits<5> Rn; 3055 bits<5> imm; 3056 bits<4> nzcv; 3057 bits<4> cond; 3058 3059 let Inst{30} = op; 3060 let Inst{29-21} = 0b111010010; 3061 let Inst{20-16} = imm; 3062 let Inst{15-12} = cond; 3063 let Inst{11-10} = 0b10; 3064 let Inst{9-5} = Rn; 3065 let Inst{4} = 0b0; 3066 let Inst{3-0} = nzcv; 3067} 3068 3069let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3070class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3071 SDNode OpNode> 3072 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3073 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3074 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3075 (i32 imm:$cond), NZCV))]>, 3076 Sched<[WriteI, ReadI, ReadI]> { 3077 let Uses = [NZCV]; 3078 let Defs = [NZCV]; 3079 3080 bits<5> Rn; 3081 bits<5> Rm; 3082 bits<4> nzcv; 3083 bits<4> cond; 3084 3085 let Inst{30} = op; 3086 let Inst{29-21} = 0b111010010; 3087 let Inst{20-16} = Rm; 3088 let Inst{15-12} = cond; 3089 let Inst{11-10} = 0b00; 3090 let Inst{9-5} = Rn; 3091 let Inst{4} = 0b0; 3092 let Inst{3-0} = nzcv; 3093} 3094 3095multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3096 // immediate operand variants 3097 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3098 let Inst{31} = 0; 3099 } 3100 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3101 let Inst{31} = 1; 3102 } 3103 // register operand variants 3104 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3105 let Inst{31} = 0; 3106 } 3107 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3108 let Inst{31} = 1; 3109 } 3110} 3111 3112//--- 3113// Conditional select 3114//--- 3115 3116class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3117 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3118 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3119 [(set regtype:$Rd, 3120 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3121 Sched<[WriteI, ReadI, ReadI]> { 3122 let Uses = [NZCV]; 3123 3124 bits<5> Rd; 3125 bits<5> Rn; 3126 bits<5> Rm; 3127 bits<4> cond; 3128 3129 let Inst{30} = op; 3130 let Inst{29-21} = 0b011010100; 3131 let Inst{20-16} = Rm; 3132 let Inst{15-12} = cond; 3133 let Inst{11-10} = op2; 3134 let Inst{9-5} = Rn; 3135 let Inst{4-0} = Rd; 3136} 3137 3138multiclass CondSelect<bit op, bits<2> op2, string asm> { 3139 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3140 let Inst{31} = 0; 3141 } 3142 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3143 let Inst{31} = 1; 3144 } 3145} 3146 3147class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3148 PatFrag frag> 3149 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3150 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3151 [(set regtype:$Rd, 3152 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3153 (i32 imm:$cond), NZCV))]>, 3154 Sched<[WriteI, ReadI, ReadI]> { 3155 let Uses = [NZCV]; 3156 3157 bits<5> Rd; 3158 bits<5> Rn; 3159 bits<5> Rm; 3160 bits<4> cond; 3161 3162 let Inst{30} = op; 3163 let Inst{29-21} = 0b011010100; 3164 let Inst{20-16} = Rm; 3165 let Inst{15-12} = cond; 3166 let Inst{11-10} = op2; 3167 let Inst{9-5} = Rn; 3168 let Inst{4-0} = Rd; 3169} 3170 3171def inv_cond_XFORM : SDNodeXForm<imm, [{ 3172 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3173 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3174 MVT::i32); 3175}]>; 3176 3177multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3178 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3179 let Inst{31} = 0; 3180 } 3181 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3182 let Inst{31} = 1; 3183 } 3184 3185 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3186 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3187 (inv_cond_XFORM imm:$cond))>; 3188 3189 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3190 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3191 (inv_cond_XFORM imm:$cond))>; 3192} 3193 3194//--- 3195// Special Mask Value 3196//--- 3197def maski8_or_more : Operand<i32>, 3198 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3199} 3200def maski16_or_more : Operand<i32>, 3201 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3202} 3203 3204 3205//--- 3206// Load/store 3207//--- 3208 3209// (unsigned immediate) 3210// Indexed for 8-bit registers. offset is in range [0,4095]. 3211def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3212def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3213def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3214def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3215def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3216 3217// (unsigned immediate) 3218// Indexed for 8-bit registers. offset is in range [0,63]. 3219def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3220def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3221def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3222def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3223 3224def gi_am_indexed8 : 3225 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3226 GIComplexPatternEquiv<am_indexed8>; 3227def gi_am_indexed16 : 3228 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3229 GIComplexPatternEquiv<am_indexed16>; 3230def gi_am_indexed32 : 3231 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3232 GIComplexPatternEquiv<am_indexed32>; 3233def gi_am_indexed64 : 3234 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3235 GIComplexPatternEquiv<am_indexed64>; 3236def gi_am_indexed128 : 3237 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3238 GIComplexPatternEquiv<am_indexed128>; 3239 3240class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3241 let Name = "UImm12Offset" # Scale; 3242 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3243 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3244 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3245} 3246 3247def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3248def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3249def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3250def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3251def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3252 3253class uimm12_scaled<int Scale> : Operand<i64> { 3254 let ParserMatchClass 3255 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3256 let EncoderMethod 3257 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3258 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3259} 3260 3261def uimm12s1 : uimm12_scaled<1>; 3262def uimm12s2 : uimm12_scaled<2>; 3263def uimm12s4 : uimm12_scaled<4>; 3264def uimm12s8 : uimm12_scaled<8>; 3265def uimm12s16 : uimm12_scaled<16>; 3266 3267class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3268 string asm, list<dag> pattern> 3269 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3270 bits<5> Rt; 3271 3272 bits<5> Rn; 3273 bits<12> offset; 3274 3275 let Inst{31-30} = sz; 3276 let Inst{29-27} = 0b111; 3277 let Inst{26} = V; 3278 let Inst{25-24} = 0b01; 3279 let Inst{23-22} = opc; 3280 let Inst{21-10} = offset; 3281 let Inst{9-5} = Rn; 3282 let Inst{4-0} = Rt; 3283 3284 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3285} 3286 3287multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3288 Operand indextype, string asm, list<dag> pattern> { 3289 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3290 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3291 (ins GPR64sp:$Rn, indextype:$offset), 3292 asm, pattern>, 3293 Sched<[WriteLD]>; 3294 3295 def : InstAlias<asm # "\t$Rt, [$Rn]", 3296 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3297} 3298 3299multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3300 Operand indextype, string asm, list<dag> pattern> { 3301 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3302 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3303 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3304 asm, pattern>, 3305 Sched<[WriteST]>; 3306 3307 def : InstAlias<asm # "\t$Rt, [$Rn]", 3308 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3309} 3310 3311// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3312// substitute zero-registers automatically. 3313// 3314// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3315// into StoreUI. 3316multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3317 Operand indextype, string asm, list<dag> pattern> { 3318 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3319 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3320 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3321 asm, pattern>, 3322 Sched<[WriteST]>; 3323 3324 def : InstAlias<asm # "\t$Rt, [$Rn]", 3325 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3326} 3327 3328def PrefetchOperand : AsmOperandClass { 3329 let Name = "Prefetch"; 3330 let ParserMethod = "tryParsePrefetch"; 3331} 3332def prfop : Operand<i32> { 3333 let PrintMethod = "printPrefetchOp"; 3334 let ParserMatchClass = PrefetchOperand; 3335} 3336 3337let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3338class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3339 : BaseLoadStoreUI<sz, V, opc, 3340 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3341 asm, pat>, 3342 Sched<[WriteLD]>; 3343 3344//--- 3345// Load literal 3346//--- 3347 3348// Load literal address: 19-bit immediate. The low two bits of the target 3349// offset are implied zero and so are not part of the immediate. 3350def am_ldrlit : Operand<iPTR> { 3351 let EncoderMethod = "getLoadLiteralOpValue"; 3352 let DecoderMethod = "DecodePCRelLabel19"; 3353 let PrintMethod = "printAlignedLabel"; 3354 let ParserMatchClass = PCRelLabel19Operand; 3355 let OperandType = "OPERAND_PCREL"; 3356} 3357 3358let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3359class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3360 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3361 asm, "\t$Rt, $label", "", pat>, 3362 Sched<[WriteLD]> { 3363 bits<5> Rt; 3364 bits<19> label; 3365 let Inst{31-30} = opc; 3366 let Inst{29-27} = 0b011; 3367 let Inst{26} = V; 3368 let Inst{25-24} = 0b00; 3369 let Inst{23-5} = label; 3370 let Inst{4-0} = Rt; 3371} 3372 3373let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3374class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3375 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3376 asm, "\t$Rt, $label", "", pat>, 3377 Sched<[WriteLD]> { 3378 bits<5> Rt; 3379 bits<19> label; 3380 let Inst{31-30} = opc; 3381 let Inst{29-27} = 0b011; 3382 let Inst{26} = V; 3383 let Inst{25-24} = 0b00; 3384 let Inst{23-5} = label; 3385 let Inst{4-0} = Rt; 3386} 3387 3388//--- 3389// Load/store register offset 3390//--- 3391 3392def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3393def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3394def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3395def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3396def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3397 3398def gi_ro_Xindexed8 : 3399 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3400 GIComplexPatternEquiv<ro_Xindexed8>; 3401def gi_ro_Xindexed16 : 3402 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3403 GIComplexPatternEquiv<ro_Xindexed16>; 3404def gi_ro_Xindexed32 : 3405 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3406 GIComplexPatternEquiv<ro_Xindexed32>; 3407def gi_ro_Xindexed64 : 3408 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3409 GIComplexPatternEquiv<ro_Xindexed64>; 3410def gi_ro_Xindexed128 : 3411 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3412 GIComplexPatternEquiv<ro_Xindexed128>; 3413 3414def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3415def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3416def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3417def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3418def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3419 3420def gi_ro_Windexed8 : 3421 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3422 GIComplexPatternEquiv<ro_Windexed8>; 3423def gi_ro_Windexed16 : 3424 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3425 GIComplexPatternEquiv<ro_Windexed16>; 3426def gi_ro_Windexed32 : 3427 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3428 GIComplexPatternEquiv<ro_Windexed32>; 3429def gi_ro_Windexed64 : 3430 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3431 GIComplexPatternEquiv<ro_Windexed64>; 3432def gi_ro_Windexed128 : 3433 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3434 GIComplexPatternEquiv<ro_Windexed128>; 3435 3436class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3437 let Name = "Mem" # Reg # "Extend" # Width; 3438 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3439 let RenderMethod = "addMemExtendOperands"; 3440 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3441} 3442 3443def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3444 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3445 // the trivial shift. 3446 let RenderMethod = "addMemExtend8Operands"; 3447} 3448def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3449def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3450def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3451def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3452 3453def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3454 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3455 // the trivial shift. 3456 let RenderMethod = "addMemExtend8Operands"; 3457} 3458def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3459def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3460def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3461def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3462 3463class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3464 : Operand<i32> { 3465 let ParserMatchClass = ParserClass; 3466 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3467 let DecoderMethod = "DecodeMemExtend"; 3468 let EncoderMethod = "getMemExtendOpValue"; 3469 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3470} 3471 3472def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3473def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3474def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3475def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3476def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3477 3478def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3479def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3480def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3481def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3482def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3483 3484class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3485 Operand wextend, Operand xextend> { 3486 // CodeGen-level pattern covering the entire addressing mode. 3487 ComplexPattern Wpat = windex; 3488 ComplexPattern Xpat = xindex; 3489 3490 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3491 Operand Wext = wextend; 3492 Operand Xext = xextend; 3493} 3494 3495def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3496def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3497def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3498def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3499def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3500 ro_Xextend128>; 3501 3502class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3503 dag outs, list<dag> pat> 3504 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3505 bits<5> Rt; 3506 bits<5> Rn; 3507 bits<5> Rm; 3508 bits<2> extend; 3509 let Inst{31-30} = sz; 3510 let Inst{29-27} = 0b111; 3511 let Inst{26} = V; 3512 let Inst{25-24} = 0b00; 3513 let Inst{23-22} = opc; 3514 let Inst{21} = 1; 3515 let Inst{20-16} = Rm; 3516 let Inst{15} = extend{1}; // sign extend Rm? 3517 let Inst{14} = 1; 3518 let Inst{12} = extend{0}; // do shift? 3519 let Inst{11-10} = 0b10; 3520 let Inst{9-5} = Rn; 3521 let Inst{4-0} = Rt; 3522} 3523 3524class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3525 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3526 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3527 3528multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3529 string asm, ValueType Ty, SDPatternOperator loadop> { 3530 let AddedComplexity = 10 in 3531 def roW : LoadStore8RO<sz, V, opc, asm, 3532 (outs regtype:$Rt), 3533 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3534 [(set (Ty regtype:$Rt), 3535 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3536 ro_Wextend8:$extend)))]>, 3537 Sched<[WriteLDIdx, ReadAdrBase]> { 3538 let Inst{13} = 0b0; 3539 } 3540 3541 let AddedComplexity = 10 in 3542 def roX : LoadStore8RO<sz, V, opc, asm, 3543 (outs regtype:$Rt), 3544 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3545 [(set (Ty regtype:$Rt), 3546 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3547 ro_Xextend8:$extend)))]>, 3548 Sched<[WriteLDIdx, ReadAdrBase]> { 3549 let Inst{13} = 0b1; 3550 } 3551 3552 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3553} 3554 3555multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3556 string asm, ValueType Ty, SDPatternOperator storeop> { 3557 let AddedComplexity = 10 in 3558 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3559 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3560 [(storeop (Ty regtype:$Rt), 3561 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3562 ro_Wextend8:$extend))]>, 3563 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3564 let Inst{13} = 0b0; 3565 } 3566 3567 let AddedComplexity = 10 in 3568 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3569 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3570 [(storeop (Ty regtype:$Rt), 3571 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3572 ro_Xextend8:$extend))]>, 3573 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3574 let Inst{13} = 0b1; 3575 } 3576 3577 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3578} 3579 3580class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3581 dag outs, list<dag> pat> 3582 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3583 bits<5> Rt; 3584 bits<5> Rn; 3585 bits<5> Rm; 3586 bits<2> extend; 3587 let Inst{31-30} = sz; 3588 let Inst{29-27} = 0b111; 3589 let Inst{26} = V; 3590 let Inst{25-24} = 0b00; 3591 let Inst{23-22} = opc; 3592 let Inst{21} = 1; 3593 let Inst{20-16} = Rm; 3594 let Inst{15} = extend{1}; // sign extend Rm? 3595 let Inst{14} = 1; 3596 let Inst{12} = extend{0}; // do shift? 3597 let Inst{11-10} = 0b10; 3598 let Inst{9-5} = Rn; 3599 let Inst{4-0} = Rt; 3600} 3601 3602multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3603 string asm, ValueType Ty, SDPatternOperator loadop> { 3604 let AddedComplexity = 10 in 3605 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3606 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3607 [(set (Ty regtype:$Rt), 3608 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3609 ro_Wextend16:$extend)))]>, 3610 Sched<[WriteLDIdx, ReadAdrBase]> { 3611 let Inst{13} = 0b0; 3612 } 3613 3614 let AddedComplexity = 10 in 3615 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3616 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3617 [(set (Ty regtype:$Rt), 3618 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3619 ro_Xextend16:$extend)))]>, 3620 Sched<[WriteLDIdx, ReadAdrBase]> { 3621 let Inst{13} = 0b1; 3622 } 3623 3624 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3625} 3626 3627multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3628 string asm, ValueType Ty, SDPatternOperator storeop> { 3629 let AddedComplexity = 10 in 3630 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3631 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3632 [(storeop (Ty regtype:$Rt), 3633 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3634 ro_Wextend16:$extend))]>, 3635 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3636 let Inst{13} = 0b0; 3637 } 3638 3639 let AddedComplexity = 10 in 3640 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3641 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3642 [(storeop (Ty regtype:$Rt), 3643 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3644 ro_Xextend16:$extend))]>, 3645 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3646 let Inst{13} = 0b1; 3647 } 3648 3649 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3650} 3651 3652class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3653 dag outs, list<dag> pat> 3654 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3655 bits<5> Rt; 3656 bits<5> Rn; 3657 bits<5> Rm; 3658 bits<2> extend; 3659 let Inst{31-30} = sz; 3660 let Inst{29-27} = 0b111; 3661 let Inst{26} = V; 3662 let Inst{25-24} = 0b00; 3663 let Inst{23-22} = opc; 3664 let Inst{21} = 1; 3665 let Inst{20-16} = Rm; 3666 let Inst{15} = extend{1}; // sign extend Rm? 3667 let Inst{14} = 1; 3668 let Inst{12} = extend{0}; // do shift? 3669 let Inst{11-10} = 0b10; 3670 let Inst{9-5} = Rn; 3671 let Inst{4-0} = Rt; 3672} 3673 3674multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3675 string asm, ValueType Ty, SDPatternOperator loadop> { 3676 let AddedComplexity = 10 in 3677 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3678 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3679 [(set (Ty regtype:$Rt), 3680 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3681 ro_Wextend32:$extend)))]>, 3682 Sched<[WriteLDIdx, ReadAdrBase]> { 3683 let Inst{13} = 0b0; 3684 } 3685 3686 let AddedComplexity = 10 in 3687 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3688 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3689 [(set (Ty regtype:$Rt), 3690 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3691 ro_Xextend32:$extend)))]>, 3692 Sched<[WriteLDIdx, ReadAdrBase]> { 3693 let Inst{13} = 0b1; 3694 } 3695 3696 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3697} 3698 3699multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3700 string asm, ValueType Ty, SDPatternOperator storeop> { 3701 let AddedComplexity = 10 in 3702 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 3703 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3704 [(storeop (Ty regtype:$Rt), 3705 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3706 ro_Wextend32:$extend))]>, 3707 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3708 let Inst{13} = 0b0; 3709 } 3710 3711 let AddedComplexity = 10 in 3712 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 3713 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3714 [(storeop (Ty regtype:$Rt), 3715 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3716 ro_Xextend32:$extend))]>, 3717 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3718 let Inst{13} = 0b1; 3719 } 3720 3721 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3722} 3723 3724class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3725 dag outs, list<dag> pat> 3726 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3727 bits<5> Rt; 3728 bits<5> Rn; 3729 bits<5> Rm; 3730 bits<2> extend; 3731 let Inst{31-30} = sz; 3732 let Inst{29-27} = 0b111; 3733 let Inst{26} = V; 3734 let Inst{25-24} = 0b00; 3735 let Inst{23-22} = opc; 3736 let Inst{21} = 1; 3737 let Inst{20-16} = Rm; 3738 let Inst{15} = extend{1}; // sign extend Rm? 3739 let Inst{14} = 1; 3740 let Inst{12} = extend{0}; // do shift? 3741 let Inst{11-10} = 0b10; 3742 let Inst{9-5} = Rn; 3743 let Inst{4-0} = Rt; 3744} 3745 3746multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3747 string asm, ValueType Ty, SDPatternOperator loadop> { 3748 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3749 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3750 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3751 [(set (Ty regtype:$Rt), 3752 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3753 ro_Wextend64:$extend)))]>, 3754 Sched<[WriteLDIdx, ReadAdrBase]> { 3755 let Inst{13} = 0b0; 3756 } 3757 3758 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3759 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3760 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3761 [(set (Ty regtype:$Rt), 3762 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3763 ro_Xextend64:$extend)))]>, 3764 Sched<[WriteLDIdx, ReadAdrBase]> { 3765 let Inst{13} = 0b1; 3766 } 3767 3768 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3769} 3770 3771multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3772 string asm, ValueType Ty, SDPatternOperator storeop> { 3773 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3774 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 3775 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3776 [(storeop (Ty regtype:$Rt), 3777 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3778 ro_Wextend64:$extend))]>, 3779 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3780 let Inst{13} = 0b0; 3781 } 3782 3783 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3784 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 3785 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3786 [(storeop (Ty regtype:$Rt), 3787 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3788 ro_Xextend64:$extend))]>, 3789 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3790 let Inst{13} = 0b1; 3791 } 3792 3793 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3794} 3795 3796class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3797 dag outs, list<dag> pat> 3798 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3799 bits<5> Rt; 3800 bits<5> Rn; 3801 bits<5> Rm; 3802 bits<2> extend; 3803 let Inst{31-30} = sz; 3804 let Inst{29-27} = 0b111; 3805 let Inst{26} = V; 3806 let Inst{25-24} = 0b00; 3807 let Inst{23-22} = opc; 3808 let Inst{21} = 1; 3809 let Inst{20-16} = Rm; 3810 let Inst{15} = extend{1}; // sign extend Rm? 3811 let Inst{14} = 1; 3812 let Inst{12} = extend{0}; // do shift? 3813 let Inst{11-10} = 0b10; 3814 let Inst{9-5} = Rn; 3815 let Inst{4-0} = Rt; 3816} 3817 3818multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3819 string asm, ValueType Ty, SDPatternOperator loadop> { 3820 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3821 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3822 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3823 [(set (Ty regtype:$Rt), 3824 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3825 ro_Wextend128:$extend)))]>, 3826 Sched<[WriteLDIdx, ReadAdrBase]> { 3827 let Inst{13} = 0b0; 3828 } 3829 3830 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3831 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3832 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3833 [(set (Ty regtype:$Rt), 3834 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3835 ro_Xextend128:$extend)))]>, 3836 Sched<[WriteLDIdx, ReadAdrBase]> { 3837 let Inst{13} = 0b1; 3838 } 3839 3840 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3841} 3842 3843multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3844 string asm> { 3845 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3846 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 3847 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3848 []>, 3849 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3850 let Inst{13} = 0b0; 3851 } 3852 3853 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3854 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 3855 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3856 []>, 3857 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3858 let Inst{13} = 0b1; 3859 } 3860 3861 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3862} 3863 3864let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3865class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3866 string asm, list<dag> pat> 3867 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3868 Sched<[WriteLD]> { 3869 bits<5> Rt; 3870 bits<5> Rn; 3871 bits<5> Rm; 3872 bits<2> extend; 3873 let Inst{31-30} = sz; 3874 let Inst{29-27} = 0b111; 3875 let Inst{26} = V; 3876 let Inst{25-24} = 0b00; 3877 let Inst{23-22} = opc; 3878 let Inst{21} = 1; 3879 let Inst{20-16} = Rm; 3880 let Inst{15} = extend{1}; // sign extend Rm? 3881 let Inst{14} = 1; 3882 let Inst{12} = extend{0}; // do shift? 3883 let Inst{11-10} = 0b10; 3884 let Inst{9-5} = Rn; 3885 let Inst{4-0} = Rt; 3886} 3887 3888multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3889 def roW : BasePrefetchRO<sz, V, opc, (outs), 3890 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3891 asm, [(AArch64Prefetch imm:$Rt, 3892 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3893 ro_Wextend64:$extend))]> { 3894 let Inst{13} = 0b0; 3895 } 3896 3897 def roX : BasePrefetchRO<sz, V, opc, (outs), 3898 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3899 asm, [(AArch64Prefetch imm:$Rt, 3900 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3901 ro_Xextend64:$extend))]> { 3902 let Inst{13} = 0b1; 3903 } 3904 3905 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3906 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3907 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3908} 3909 3910//--- 3911// Load/store unscaled immediate 3912//--- 3913 3914def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 3915def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 3916def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 3917def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 3918def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 3919 3920def gi_am_unscaled8 : 3921 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3922 GIComplexPatternEquiv<am_unscaled8>; 3923def gi_am_unscaled16 : 3924 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3925 GIComplexPatternEquiv<am_unscaled16>; 3926def gi_am_unscaled32 : 3927 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3928 GIComplexPatternEquiv<am_unscaled32>; 3929def gi_am_unscaled64 : 3930 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3931 GIComplexPatternEquiv<am_unscaled64>; 3932def gi_am_unscaled128 : 3933 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3934 GIComplexPatternEquiv<am_unscaled128>; 3935 3936 3937class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3938 string asm, list<dag> pattern> 3939 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3940 bits<5> Rt; 3941 bits<5> Rn; 3942 bits<9> offset; 3943 let Inst{31-30} = sz; 3944 let Inst{29-27} = 0b111; 3945 let Inst{26} = V; 3946 let Inst{25-24} = 0b00; 3947 let Inst{23-22} = opc; 3948 let Inst{21} = 0; 3949 let Inst{20-12} = offset; 3950 let Inst{11-10} = 0b00; 3951 let Inst{9-5} = Rn; 3952 let Inst{4-0} = Rt; 3953 3954 let DecoderMethod = "DecodeSignedLdStInstruction"; 3955} 3956 3957// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3958multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3959 DAGOperand regtype > { 3960 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3961 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3962 Sched<[WriteST]> { 3963 let Inst{29} = 0; 3964 let Inst{24} = 1; 3965 } 3966 def : InstAlias<asm # "\t$Rt, [$Rn]", 3967 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3968} 3969 3970multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3971 DAGOperand regtype > { 3972 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3973 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3974 asm, []>, 3975 Sched<[WriteST]> { 3976 let Inst{29} = 0; 3977 let Inst{24} = 1; 3978 } 3979 def : InstAlias<asm # "\t$Rt, [$Rn]", 3980 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3981} 3982 3983multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3984 string asm, list<dag> pattern> { 3985 let AddedComplexity = 1 in // try this before LoadUI 3986 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3987 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3988 Sched<[WriteLD]>; 3989 3990 def : InstAlias<asm # "\t$Rt, [$Rn]", 3991 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3992} 3993 3994multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3995 string asm, list<dag> pattern> { 3996 let AddedComplexity = 1 in // try this before StoreUI 3997 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3998 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3999 asm, pattern>, 4000 Sched<[WriteST]>; 4001 4002 def : InstAlias<asm # "\t$Rt, [$Rn]", 4003 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4004} 4005 4006multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4007 list<dag> pat> { 4008 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4009 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4010 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4011 asm, pat>, 4012 Sched<[WriteLD]>; 4013 4014 def : InstAlias<asm # "\t$Rt, [$Rn]", 4015 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4016} 4017 4018//--- 4019// Load/store unscaled immediate, unprivileged 4020//--- 4021 4022class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4023 dag oops, dag iops, string asm> 4024 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4025 bits<5> Rt; 4026 bits<5> Rn; 4027 bits<9> offset; 4028 let Inst{31-30} = sz; 4029 let Inst{29-27} = 0b111; 4030 let Inst{26} = V; 4031 let Inst{25-24} = 0b00; 4032 let Inst{23-22} = opc; 4033 let Inst{21} = 0; 4034 let Inst{20-12} = offset; 4035 let Inst{11-10} = 0b10; 4036 let Inst{9-5} = Rn; 4037 let Inst{4-0} = Rt; 4038 4039 let DecoderMethod = "DecodeSignedLdStInstruction"; 4040} 4041 4042multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4043 RegisterClass regtype, string asm> { 4044 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4045 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4046 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4047 Sched<[WriteLD]>; 4048 4049 def : InstAlias<asm # "\t$Rt, [$Rn]", 4050 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4051} 4052 4053multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4054 RegisterClass regtype, string asm> { 4055 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4056 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4057 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4058 asm>, 4059 Sched<[WriteST]>; 4060 4061 def : InstAlias<asm # "\t$Rt, [$Rn]", 4062 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4063} 4064 4065//--- 4066// Load/store pre-indexed 4067//--- 4068 4069class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4070 string asm, string cstr, list<dag> pat> 4071 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4072 bits<5> Rt; 4073 bits<5> Rn; 4074 bits<9> offset; 4075 let Inst{31-30} = sz; 4076 let Inst{29-27} = 0b111; 4077 let Inst{26} = V; 4078 let Inst{25-24} = 0; 4079 let Inst{23-22} = opc; 4080 let Inst{21} = 0; 4081 let Inst{20-12} = offset; 4082 let Inst{11-10} = 0b11; 4083 let Inst{9-5} = Rn; 4084 let Inst{4-0} = Rt; 4085 4086 let DecoderMethod = "DecodeSignedLdStInstruction"; 4087} 4088 4089let hasSideEffects = 0 in { 4090let mayStore = 0, mayLoad = 1 in 4091class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4092 string asm> 4093 : BaseLoadStorePreIdx<sz, V, opc, 4094 (outs GPR64sp:$wback, regtype:$Rt), 4095 (ins GPR64sp:$Rn, simm9:$offset), asm, 4096 "$Rn = $wback,@earlyclobber $wback", []>, 4097 Sched<[WriteAdr, WriteLD]>; 4098 4099let mayStore = 1, mayLoad = 0 in 4100class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4101 string asm, SDPatternOperator storeop, ValueType Ty> 4102 : BaseLoadStorePreIdx<sz, V, opc, 4103 (outs GPR64sp:$wback), 4104 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4105 asm, "$Rn = $wback,@earlyclobber $wback", 4106 [(set GPR64sp:$wback, 4107 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4108 Sched<[WriteAdr, WriteST]>; 4109} // hasSideEffects = 0 4110 4111//--- 4112// Load/store post-indexed 4113//--- 4114 4115class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4116 string asm, string cstr, list<dag> pat> 4117 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4118 bits<5> Rt; 4119 bits<5> Rn; 4120 bits<9> offset; 4121 let Inst{31-30} = sz; 4122 let Inst{29-27} = 0b111; 4123 let Inst{26} = V; 4124 let Inst{25-24} = 0b00; 4125 let Inst{23-22} = opc; 4126 let Inst{21} = 0b0; 4127 let Inst{20-12} = offset; 4128 let Inst{11-10} = 0b01; 4129 let Inst{9-5} = Rn; 4130 let Inst{4-0} = Rt; 4131 4132 let DecoderMethod = "DecodeSignedLdStInstruction"; 4133} 4134 4135let hasSideEffects = 0 in { 4136let mayStore = 0, mayLoad = 1 in 4137class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4138 string asm> 4139 : BaseLoadStorePostIdx<sz, V, opc, 4140 (outs GPR64sp:$wback, regtype:$Rt), 4141 (ins GPR64sp:$Rn, simm9:$offset), 4142 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4143 Sched<[WriteAdr, WriteLD]>; 4144 4145let mayStore = 1, mayLoad = 0 in 4146class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4147 string asm, SDPatternOperator storeop, ValueType Ty> 4148 : BaseLoadStorePostIdx<sz, V, opc, 4149 (outs GPR64sp:$wback), 4150 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4151 asm, "$Rn = $wback,@earlyclobber $wback", 4152 [(set GPR64sp:$wback, 4153 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4154 Sched<[WriteAdr, WriteST]>; 4155} // hasSideEffects = 0 4156 4157 4158//--- 4159// Load/store pair 4160//--- 4161 4162// (indexed, offset) 4163 4164class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4165 string asm> 4166 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4167 bits<5> Rt; 4168 bits<5> Rt2; 4169 bits<5> Rn; 4170 bits<7> offset; 4171 let Inst{31-30} = opc; 4172 let Inst{29-27} = 0b101; 4173 let Inst{26} = V; 4174 let Inst{25-23} = 0b010; 4175 let Inst{22} = L; 4176 let Inst{21-15} = offset; 4177 let Inst{14-10} = Rt2; 4178 let Inst{9-5} = Rn; 4179 let Inst{4-0} = Rt; 4180 4181 let DecoderMethod = "DecodePairLdStInstruction"; 4182} 4183 4184multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4185 Operand indextype, string asm> { 4186 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4187 def i : BaseLoadStorePairOffset<opc, V, 1, 4188 (outs regtype:$Rt, regtype:$Rt2), 4189 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4190 Sched<[WriteLD, WriteLDHi]>; 4191 4192 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4193 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4194 GPR64sp:$Rn, 0)>; 4195} 4196 4197 4198multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4199 Operand indextype, string asm> { 4200 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4201 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4202 (ins regtype:$Rt, regtype:$Rt2, 4203 GPR64sp:$Rn, indextype:$offset), 4204 asm>, 4205 Sched<[WriteSTP]>; 4206 4207 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4208 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4209 GPR64sp:$Rn, 0)>; 4210} 4211 4212// (pre-indexed) 4213class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4214 string asm> 4215 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4216 bits<5> Rt; 4217 bits<5> Rt2; 4218 bits<5> Rn; 4219 bits<7> offset; 4220 let Inst{31-30} = opc; 4221 let Inst{29-27} = 0b101; 4222 let Inst{26} = V; 4223 let Inst{25-23} = 0b011; 4224 let Inst{22} = L; 4225 let Inst{21-15} = offset; 4226 let Inst{14-10} = Rt2; 4227 let Inst{9-5} = Rn; 4228 let Inst{4-0} = Rt; 4229 4230 let DecoderMethod = "DecodePairLdStInstruction"; 4231} 4232 4233let hasSideEffects = 0 in { 4234let mayStore = 0, mayLoad = 1 in 4235class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4236 Operand indextype, string asm> 4237 : BaseLoadStorePairPreIdx<opc, V, 1, 4238 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4239 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4240 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4241 4242let mayStore = 1, mayLoad = 0 in 4243class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4244 Operand indextype, string asm> 4245 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4246 (ins regtype:$Rt, regtype:$Rt2, 4247 GPR64sp:$Rn, indextype:$offset), 4248 asm>, 4249 Sched<[WriteAdr, WriteSTP]>; 4250} // hasSideEffects = 0 4251 4252// (post-indexed) 4253 4254class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4255 string asm> 4256 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4257 bits<5> Rt; 4258 bits<5> Rt2; 4259 bits<5> Rn; 4260 bits<7> offset; 4261 let Inst{31-30} = opc; 4262 let Inst{29-27} = 0b101; 4263 let Inst{26} = V; 4264 let Inst{25-23} = 0b001; 4265 let Inst{22} = L; 4266 let Inst{21-15} = offset; 4267 let Inst{14-10} = Rt2; 4268 let Inst{9-5} = Rn; 4269 let Inst{4-0} = Rt; 4270 4271 let DecoderMethod = "DecodePairLdStInstruction"; 4272} 4273 4274let hasSideEffects = 0 in { 4275let mayStore = 0, mayLoad = 1 in 4276class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4277 Operand idxtype, string asm> 4278 : BaseLoadStorePairPostIdx<opc, V, 1, 4279 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4280 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4281 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4282 4283let mayStore = 1, mayLoad = 0 in 4284class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4285 Operand idxtype, string asm> 4286 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4287 (ins regtype:$Rt, regtype:$Rt2, 4288 GPR64sp:$Rn, idxtype:$offset), 4289 asm>, 4290 Sched<[WriteAdr, WriteSTP]>; 4291} // hasSideEffects = 0 4292 4293// (no-allocate) 4294 4295class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4296 string asm> 4297 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4298 bits<5> Rt; 4299 bits<5> Rt2; 4300 bits<5> Rn; 4301 bits<7> offset; 4302 let Inst{31-30} = opc; 4303 let Inst{29-27} = 0b101; 4304 let Inst{26} = V; 4305 let Inst{25-23} = 0b000; 4306 let Inst{22} = L; 4307 let Inst{21-15} = offset; 4308 let Inst{14-10} = Rt2; 4309 let Inst{9-5} = Rn; 4310 let Inst{4-0} = Rt; 4311 4312 let DecoderMethod = "DecodePairLdStInstruction"; 4313} 4314 4315multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4316 Operand indextype, string asm> { 4317 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4318 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4319 (outs regtype:$Rt, regtype:$Rt2), 4320 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4321 Sched<[WriteLD, WriteLDHi]>; 4322 4323 4324 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4325 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4326 GPR64sp:$Rn, 0)>; 4327} 4328 4329multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4330 Operand indextype, string asm> { 4331 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4332 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4333 (ins regtype:$Rt, regtype:$Rt2, 4334 GPR64sp:$Rn, indextype:$offset), 4335 asm>, 4336 Sched<[WriteSTP]>; 4337 4338 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4339 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4340 GPR64sp:$Rn, 0)>; 4341} 4342 4343//--- 4344// Load/store exclusive 4345//--- 4346 4347// True exclusive operations write to and/or read from the system's exclusive 4348// monitors, which as far as a compiler is concerned can be modelled as a 4349// random shared memory address. Hence LoadExclusive mayStore. 4350// 4351// Since these instructions have the undefined register bits set to 1 in 4352// their canonical form, we need a post encoder method to set those bits 4353// to 1 when encoding these instructions. We do this using the 4354// fixLoadStoreExclusive function. This function has template parameters: 4355// 4356// fixLoadStoreExclusive<int hasRs, int hasRt2> 4357// 4358// hasRs indicates that the instruction uses the Rs field, so we won't set 4359// it to 1 (and the same for Rt2). We don't need template parameters for 4360// the other register fields since Rt and Rn are always used. 4361// 4362let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4363class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4364 dag oops, dag iops, string asm, string operands> 4365 : I<oops, iops, asm, operands, "", []> { 4366 let Inst{31-30} = sz; 4367 let Inst{29-24} = 0b001000; 4368 let Inst{23} = o2; 4369 let Inst{22} = L; 4370 let Inst{21} = o1; 4371 let Inst{15} = o0; 4372 4373 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4374} 4375 4376// Neither Rs nor Rt2 operands. 4377class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4378 dag oops, dag iops, string asm, string operands> 4379 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4380 bits<5> Rt; 4381 bits<5> Rn; 4382 let Inst{20-16} = 0b11111; 4383 let Unpredictable{20-16} = 0b11111; 4384 let Inst{14-10} = 0b11111; 4385 let Unpredictable{14-10} = 0b11111; 4386 let Inst{9-5} = Rn; 4387 let Inst{4-0} = Rt; 4388 4389 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4390} 4391 4392// Simple load acquires don't set the exclusive monitor 4393let mayLoad = 1, mayStore = 0 in 4394class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4395 RegisterClass regtype, string asm> 4396 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4397 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4398 Sched<[WriteLD]>; 4399 4400class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4401 RegisterClass regtype, string asm> 4402 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4403 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4404 Sched<[WriteLD]>; 4405 4406class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4407 RegisterClass regtype, string asm> 4408 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4409 (outs regtype:$Rt, regtype:$Rt2), 4410 (ins GPR64sp0:$Rn), asm, 4411 "\t$Rt, $Rt2, [$Rn]">, 4412 Sched<[WriteLD, WriteLDHi]> { 4413 bits<5> Rt; 4414 bits<5> Rt2; 4415 bits<5> Rn; 4416 let Inst{14-10} = Rt2; 4417 let Inst{9-5} = Rn; 4418 let Inst{4-0} = Rt; 4419 4420 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4421} 4422 4423// Simple store release operations do not check the exclusive monitor. 4424let mayLoad = 0, mayStore = 1 in 4425class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4426 RegisterClass regtype, string asm> 4427 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4428 (ins regtype:$Rt, GPR64sp0:$Rn), 4429 asm, "\t$Rt, [$Rn]">, 4430 Sched<[WriteST]>; 4431 4432let mayLoad = 1, mayStore = 1 in 4433class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4434 RegisterClass regtype, string asm> 4435 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4436 (ins regtype:$Rt, GPR64sp0:$Rn), 4437 asm, "\t$Ws, $Rt, [$Rn]">, 4438 Sched<[WriteSTX]> { 4439 bits<5> Ws; 4440 bits<5> Rt; 4441 bits<5> Rn; 4442 let Inst{20-16} = Ws; 4443 let Inst{9-5} = Rn; 4444 let Inst{4-0} = Rt; 4445 4446 let Constraints = "@earlyclobber $Ws"; 4447 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4448} 4449 4450class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4451 RegisterClass regtype, string asm> 4452 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4453 (outs GPR32:$Ws), 4454 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4455 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4456 Sched<[WriteSTX]> { 4457 bits<5> Ws; 4458 bits<5> Rt; 4459 bits<5> Rt2; 4460 bits<5> Rn; 4461 let Inst{20-16} = Ws; 4462 let Inst{14-10} = Rt2; 4463 let Inst{9-5} = Rn; 4464 let Inst{4-0} = Rt; 4465 4466 let Constraints = "@earlyclobber $Ws"; 4467} 4468 4469// Armv8.5-A Memory Tagging Extension 4470class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4471 string asm_opnds, string cstr, dag oops, dag iops> 4472 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4473 Sched<[]> { 4474 bits<5> Rn; 4475 4476 let Inst{31-24} = 0b11011001; 4477 let Inst{23-22} = opc1; 4478 let Inst{21} = 1; 4479 // Inst{20-12} defined by subclass 4480 let Inst{11-10} = opc2; 4481 let Inst{9-5} = Rn; 4482 // Inst{4-0} defined by subclass 4483} 4484 4485class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4486 dag oops, dag iops> 4487 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4488 "", oops, iops> { 4489 bits<5> Rt; 4490 4491 let Inst{20-12} = 0b000000000; 4492 let Inst{4-0} = Rt; 4493 4494 let mayLoad = Load; 4495} 4496 4497class MemTagLoad<string asm_insn, string asm_opnds> 4498 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4499 (outs GPR64:$wback), 4500 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4501 bits<5> Rt; 4502 bits<9> offset; 4503 4504 let Inst{20-12} = offset; 4505 let Inst{4-0} = Rt; 4506 4507 let mayLoad = 1; 4508} 4509 4510class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4511 string asm_opnds, string cstr, dag oops, dag iops> 4512 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4513 bits<5> Rt; 4514 bits<9> offset; 4515 4516 let Inst{20-12} = offset; 4517 let Inst{4-0} = Rt; 4518 4519 let mayStore = 1; 4520} 4521 4522multiclass MemTagStore<bits<2> opc1, string insn> { 4523 def Offset : 4524 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4525 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4526 def PreIndex : 4527 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4528 "$Rn = $wback", 4529 (outs GPR64sp:$wback), 4530 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4531 def PostIndex : 4532 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4533 "$Rn = $wback", 4534 (outs GPR64sp:$wback), 4535 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4536 4537 def : InstAlias<insn # "\t$Rt, [$Rn]", 4538 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4539} 4540 4541//--- 4542// Exception generation 4543//--- 4544 4545let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4546class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4547 list<dag> pattern = []> 4548 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4549 Sched<[WriteSys]> { 4550 bits<16> imm; 4551 let Inst{31-24} = 0b11010100; 4552 let Inst{23-21} = op1; 4553 let Inst{20-5} = imm; 4554 let Inst{4-2} = 0b000; 4555 let Inst{1-0} = ll; 4556} 4557 4558//--- 4559// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4560//-- 4561let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4562class UDFType<bits<16> opc, string asm> 4563 : I<(outs), (ins uimm16:$imm), 4564 asm, "\t$imm", "", []>, 4565 Sched<[]> { 4566 bits<16> imm; 4567 let Inst{31-16} = opc; 4568 let Inst{15-0} = imm; 4569} 4570} 4571let Predicates = [HasFPARMv8] in { 4572 4573//--- 4574// Floating point to integer conversion 4575//--- 4576 4577let mayRaiseFPException = 1 in 4578class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4579 RegisterClass srcType, RegisterClass dstType, 4580 string asm, list<dag> pattern> 4581 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4582 asm, "\t$Rd, $Rn", "", pattern>, 4583 Sched<[WriteFCvt]> { 4584 bits<5> Rd; 4585 bits<5> Rn; 4586 let Inst{30-29} = 0b00; 4587 let Inst{28-24} = 0b11110; 4588 let Inst{23-22} = type; 4589 let Inst{21} = 1; 4590 let Inst{20-19} = rmode; 4591 let Inst{18-16} = opcode; 4592 let Inst{15-10} = 0; 4593 let Inst{9-5} = Rn; 4594 let Inst{4-0} = Rd; 4595} 4596 4597let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 4598class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4599 RegisterClass srcType, RegisterClass dstType, 4600 Operand immType, string asm, list<dag> pattern> 4601 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4602 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4603 Sched<[WriteFCvt]> { 4604 bits<5> Rd; 4605 bits<5> Rn; 4606 bits<6> scale; 4607 let Inst{30-29} = 0b00; 4608 let Inst{28-24} = 0b11110; 4609 let Inst{23-22} = type; 4610 let Inst{21} = 0; 4611 let Inst{20-19} = rmode; 4612 let Inst{18-16} = opcode; 4613 let Inst{15-10} = scale; 4614 let Inst{9-5} = Rn; 4615 let Inst{4-0} = Rd; 4616} 4617 4618multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4619 SDPatternOperator OpN> { 4620 // Unscaled half-precision to 32-bit 4621 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4622 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4623 let Inst{31} = 0; // 32-bit GPR flag 4624 let Predicates = [HasFullFP16]; 4625 } 4626 4627 // Unscaled half-precision to 64-bit 4628 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4629 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4630 let Inst{31} = 1; // 64-bit GPR flag 4631 let Predicates = [HasFullFP16]; 4632 } 4633 4634 // Unscaled single-precision to 32-bit 4635 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4636 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4637 let Inst{31} = 0; // 32-bit GPR flag 4638 } 4639 4640 // Unscaled single-precision to 64-bit 4641 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4642 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4643 let Inst{31} = 1; // 64-bit GPR flag 4644 } 4645 4646 // Unscaled double-precision to 32-bit 4647 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4648 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4649 let Inst{31} = 0; // 32-bit GPR flag 4650 } 4651 4652 // Unscaled double-precision to 64-bit 4653 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4654 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4655 let Inst{31} = 1; // 64-bit GPR flag 4656 } 4657} 4658 4659multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4660 SDPatternOperator OpN> { 4661 // Scaled half-precision to 32-bit 4662 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4663 fixedpoint_f16_i32, asm, 4664 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4665 fixedpoint_f16_i32:$scale)))]> { 4666 let Inst{31} = 0; // 32-bit GPR flag 4667 let scale{5} = 1; 4668 let Predicates = [HasFullFP16]; 4669 } 4670 4671 // Scaled half-precision to 64-bit 4672 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4673 fixedpoint_f16_i64, asm, 4674 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4675 fixedpoint_f16_i64:$scale)))]> { 4676 let Inst{31} = 1; // 64-bit GPR flag 4677 let Predicates = [HasFullFP16]; 4678 } 4679 4680 // Scaled single-precision to 32-bit 4681 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4682 fixedpoint_f32_i32, asm, 4683 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4684 fixedpoint_f32_i32:$scale)))]> { 4685 let Inst{31} = 0; // 32-bit GPR flag 4686 let scale{5} = 1; 4687 } 4688 4689 // Scaled single-precision to 64-bit 4690 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4691 fixedpoint_f32_i64, asm, 4692 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4693 fixedpoint_f32_i64:$scale)))]> { 4694 let Inst{31} = 1; // 64-bit GPR flag 4695 } 4696 4697 // Scaled double-precision to 32-bit 4698 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4699 fixedpoint_f64_i32, asm, 4700 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4701 fixedpoint_f64_i32:$scale)))]> { 4702 let Inst{31} = 0; // 32-bit GPR flag 4703 let scale{5} = 1; 4704 } 4705 4706 // Scaled double-precision to 64-bit 4707 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4708 fixedpoint_f64_i64, asm, 4709 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4710 fixedpoint_f64_i64:$scale)))]> { 4711 let Inst{31} = 1; // 64-bit GPR flag 4712 } 4713} 4714 4715//--- 4716// Integer to floating point conversion 4717//--- 4718 4719let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 4720class BaseIntegerToFP<bit isUnsigned, 4721 RegisterClass srcType, RegisterClass dstType, 4722 Operand immType, string asm, list<dag> pattern> 4723 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4724 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4725 Sched<[WriteFCvt]> { 4726 bits<5> Rd; 4727 bits<5> Rn; 4728 bits<6> scale; 4729 let Inst{30-24} = 0b0011110; 4730 let Inst{21-17} = 0b00001; 4731 let Inst{16} = isUnsigned; 4732 let Inst{15-10} = scale; 4733 let Inst{9-5} = Rn; 4734 let Inst{4-0} = Rd; 4735} 4736 4737let mayRaiseFPException = 1 in 4738class BaseIntegerToFPUnscaled<bit isUnsigned, 4739 RegisterClass srcType, RegisterClass dstType, 4740 ValueType dvt, string asm, SDPatternOperator node> 4741 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4742 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4743 Sched<[WriteFCvt]> { 4744 bits<5> Rd; 4745 bits<5> Rn; 4746 bits<6> scale; 4747 let Inst{30-24} = 0b0011110; 4748 let Inst{21-17} = 0b10001; 4749 let Inst{16} = isUnsigned; 4750 let Inst{15-10} = 0b000000; 4751 let Inst{9-5} = Rn; 4752 let Inst{4-0} = Rd; 4753} 4754 4755multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4756 // Unscaled 4757 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4758 let Inst{31} = 0; // 32-bit GPR flag 4759 let Inst{23-22} = 0b11; // 16-bit FPR flag 4760 let Predicates = [HasFullFP16]; 4761 } 4762 4763 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4764 let Inst{31} = 0; // 32-bit GPR flag 4765 let Inst{23-22} = 0b00; // 32-bit FPR flag 4766 } 4767 4768 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4769 let Inst{31} = 0; // 32-bit GPR flag 4770 let Inst{23-22} = 0b01; // 64-bit FPR flag 4771 } 4772 4773 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4774 let Inst{31} = 1; // 64-bit GPR flag 4775 let Inst{23-22} = 0b11; // 16-bit FPR flag 4776 let Predicates = [HasFullFP16]; 4777 } 4778 4779 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4780 let Inst{31} = 1; // 64-bit GPR flag 4781 let Inst{23-22} = 0b00; // 32-bit FPR flag 4782 } 4783 4784 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4785 let Inst{31} = 1; // 64-bit GPR flag 4786 let Inst{23-22} = 0b01; // 64-bit FPR flag 4787 } 4788 4789 // Scaled 4790 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4791 [(set (f16 FPR16:$Rd), 4792 (fdiv (node GPR32:$Rn), 4793 fixedpoint_f16_i32:$scale))]> { 4794 let Inst{31} = 0; // 32-bit GPR flag 4795 let Inst{23-22} = 0b11; // 16-bit FPR flag 4796 let scale{5} = 1; 4797 let Predicates = [HasFullFP16]; 4798 } 4799 4800 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4801 [(set FPR32:$Rd, 4802 (fdiv (node GPR32:$Rn), 4803 fixedpoint_f32_i32:$scale))]> { 4804 let Inst{31} = 0; // 32-bit GPR flag 4805 let Inst{23-22} = 0b00; // 32-bit FPR flag 4806 let scale{5} = 1; 4807 } 4808 4809 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4810 [(set FPR64:$Rd, 4811 (fdiv (node GPR32:$Rn), 4812 fixedpoint_f64_i32:$scale))]> { 4813 let Inst{31} = 0; // 32-bit GPR flag 4814 let Inst{23-22} = 0b01; // 64-bit FPR flag 4815 let scale{5} = 1; 4816 } 4817 4818 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4819 [(set (f16 FPR16:$Rd), 4820 (fdiv (node GPR64:$Rn), 4821 fixedpoint_f16_i64:$scale))]> { 4822 let Inst{31} = 1; // 64-bit GPR flag 4823 let Inst{23-22} = 0b11; // 16-bit FPR flag 4824 let Predicates = [HasFullFP16]; 4825 } 4826 4827 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4828 [(set FPR32:$Rd, 4829 (fdiv (node GPR64:$Rn), 4830 fixedpoint_f32_i64:$scale))]> { 4831 let Inst{31} = 1; // 64-bit GPR flag 4832 let Inst{23-22} = 0b00; // 32-bit FPR flag 4833 } 4834 4835 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4836 [(set FPR64:$Rd, 4837 (fdiv (node GPR64:$Rn), 4838 fixedpoint_f64_i64:$scale))]> { 4839 let Inst{31} = 1; // 64-bit GPR flag 4840 let Inst{23-22} = 0b01; // 64-bit FPR flag 4841 } 4842} 4843 4844//--- 4845// Unscaled integer <-> floating point conversion (i.e. FMOV) 4846//--- 4847 4848let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4849class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4850 RegisterClass srcType, RegisterClass dstType, 4851 string asm> 4852 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4853 // We use COPY_TO_REGCLASS for these bitconvert operations. 4854 // copyPhysReg() expands the resultant COPY instructions after 4855 // regalloc is done. This gives greater freedom for the allocator 4856 // and related passes (coalescing, copy propagation, et. al.) to 4857 // be more effective. 4858 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4859 Sched<[WriteFCopy]> { 4860 bits<5> Rd; 4861 bits<5> Rn; 4862 let Inst{30-24} = 0b0011110; 4863 let Inst{21} = 1; 4864 let Inst{20-19} = rmode; 4865 let Inst{18-16} = opcode; 4866 let Inst{15-10} = 0b000000; 4867 let Inst{9-5} = Rn; 4868 let Inst{4-0} = Rd; 4869} 4870 4871let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4872class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4873 RegisterClass srcType, RegisterOperand dstType, string asm, 4874 string kind> 4875 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4876 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4877 Sched<[WriteFCopy]> { 4878 bits<5> Rd; 4879 bits<5> Rn; 4880 let Inst{30-23} = 0b00111101; 4881 let Inst{21} = 1; 4882 let Inst{20-19} = rmode; 4883 let Inst{18-16} = opcode; 4884 let Inst{15-10} = 0b000000; 4885 let Inst{9-5} = Rn; 4886 let Inst{4-0} = Rd; 4887 4888 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4889} 4890 4891let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4892class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4893 RegisterOperand srcType, RegisterClass dstType, string asm, 4894 string kind> 4895 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4896 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4897 Sched<[WriteFCopy]> { 4898 bits<5> Rd; 4899 bits<5> Rn; 4900 let Inst{30-23} = 0b00111101; 4901 let Inst{21} = 1; 4902 let Inst{20-19} = rmode; 4903 let Inst{18-16} = opcode; 4904 let Inst{15-10} = 0b000000; 4905 let Inst{9-5} = Rn; 4906 let Inst{4-0} = Rd; 4907 4908 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4909} 4910 4911 4912multiclass UnscaledConversion<string asm> { 4913 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4914 let Inst{31} = 0; // 32-bit GPR flag 4915 let Inst{23-22} = 0b11; // 16-bit FPR flag 4916 let Predicates = [HasFullFP16]; 4917 } 4918 4919 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4920 let Inst{31} = 1; // 64-bit GPR flag 4921 let Inst{23-22} = 0b11; // 16-bit FPR flag 4922 let Predicates = [HasFullFP16]; 4923 } 4924 4925 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4926 let Inst{31} = 0; // 32-bit GPR flag 4927 let Inst{23-22} = 0b00; // 32-bit FPR flag 4928 } 4929 4930 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4931 let Inst{31} = 1; // 64-bit GPR flag 4932 let Inst{23-22} = 0b01; // 64-bit FPR flag 4933 } 4934 4935 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4936 let Inst{31} = 0; // 32-bit GPR flag 4937 let Inst{23-22} = 0b11; // 16-bit FPR flag 4938 let Predicates = [HasFullFP16]; 4939 } 4940 4941 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4942 let Inst{31} = 1; // 64-bit GPR flag 4943 let Inst{23-22} = 0b11; // 16-bit FPR flag 4944 let Predicates = [HasFullFP16]; 4945 } 4946 4947 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4948 let Inst{31} = 0; // 32-bit GPR flag 4949 let Inst{23-22} = 0b00; // 32-bit FPR flag 4950 } 4951 4952 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4953 let Inst{31} = 1; // 64-bit GPR flag 4954 let Inst{23-22} = 0b01; // 64-bit FPR flag 4955 } 4956 4957 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4958 asm, ".d"> { 4959 let Inst{31} = 1; 4960 let Inst{22} = 0; 4961 } 4962 4963 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4964 asm, ".d"> { 4965 let Inst{31} = 1; 4966 let Inst{22} = 0; 4967 } 4968} 4969 4970//--- 4971// Floating point conversion 4972//--- 4973 4974let mayRaiseFPException = 1 in 4975class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4976 RegisterClass srcType, string asm, list<dag> pattern> 4977 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4978 Sched<[WriteFCvt]> { 4979 bits<5> Rd; 4980 bits<5> Rn; 4981 let Inst{31-24} = 0b00011110; 4982 let Inst{23-22} = type; 4983 let Inst{21-17} = 0b10001; 4984 let Inst{16-15} = opcode; 4985 let Inst{14-10} = 0b10000; 4986 let Inst{9-5} = Rn; 4987 let Inst{4-0} = Rd; 4988} 4989 4990multiclass FPConversion<string asm> { 4991 // Double-precision to Half-precision 4992 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4993 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4994 4995 // Double-precision to Single-precision 4996 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4997 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4998 4999 // Half-precision to Double-precision 5000 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5001 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5002 5003 // Half-precision to Single-precision 5004 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5005 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5006 5007 // Single-precision to Double-precision 5008 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5009 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5010 5011 // Single-precision to Half-precision 5012 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5013 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5014} 5015 5016//--- 5017// Single operand floating point data processing 5018//--- 5019 5020let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5021class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5022 ValueType vt, string asm, SDPatternOperator node> 5023 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5024 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5025 Sched<[WriteF]> { 5026 bits<5> Rd; 5027 bits<5> Rn; 5028 let Inst{31-24} = 0b00011110; 5029 let Inst{21} = 0b1; 5030 let Inst{20-15} = opcode; 5031 let Inst{14-10} = 0b10000; 5032 let Inst{9-5} = Rn; 5033 let Inst{4-0} = Rd; 5034} 5035 5036multiclass SingleOperandFPData<bits<4> opcode, string asm, 5037 SDPatternOperator node = null_frag, 5038 int fpexceptions = 1> { 5039 let mayRaiseFPException = fpexceptions in { 5040 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5041 let Inst{23-22} = 0b11; // 16-bit size flag 5042 let Predicates = [HasFullFP16]; 5043 } 5044 5045 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5046 let Inst{23-22} = 0b00; // 32-bit size flag 5047 } 5048 5049 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5050 let Inst{23-22} = 0b01; // 64-bit size flag 5051 } 5052 } 5053} 5054 5055multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5056 SDPatternOperator node = null_frag> 5057 : SingleOperandFPData<opcode, asm, node, 0>; 5058 5059let mayRaiseFPException = 1 in 5060multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5061 SDPatternOperator node = null_frag>{ 5062 5063 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5064 let Inst{23-22} = 0b00; // 32-bit registers 5065 } 5066 5067 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5068 let Inst{23-22} = 0b01; // 64-bit registers 5069 } 5070} 5071 5072// FRInt[32|64][Z|N] instructions 5073multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5074 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5075 5076//--- 5077// Two operand floating point data processing 5078//--- 5079 5080let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5081class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5082 string asm, list<dag> pat> 5083 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5084 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5085 Sched<[WriteF]> { 5086 bits<5> Rd; 5087 bits<5> Rn; 5088 bits<5> Rm; 5089 let Inst{31-24} = 0b00011110; 5090 let Inst{21} = 1; 5091 let Inst{20-16} = Rm; 5092 let Inst{15-12} = opcode; 5093 let Inst{11-10} = 0b10; 5094 let Inst{9-5} = Rn; 5095 let Inst{4-0} = Rd; 5096} 5097 5098multiclass TwoOperandFPData<bits<4> opcode, string asm, 5099 SDPatternOperator node = null_frag> { 5100 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5101 [(set (f16 FPR16:$Rd), 5102 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5103 let Inst{23-22} = 0b11; // 16-bit size flag 5104 let Predicates = [HasFullFP16]; 5105 } 5106 5107 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5108 [(set (f32 FPR32:$Rd), 5109 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5110 let Inst{23-22} = 0b00; // 32-bit size flag 5111 } 5112 5113 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5114 [(set (f64 FPR64:$Rd), 5115 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5116 let Inst{23-22} = 0b01; // 64-bit size flag 5117 } 5118} 5119 5120multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5121 SDPatternOperator node> { 5122 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5123 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5124 let Inst{23-22} = 0b11; // 16-bit size flag 5125 let Predicates = [HasFullFP16]; 5126 } 5127 5128 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5129 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5130 let Inst{23-22} = 0b00; // 32-bit size flag 5131 } 5132 5133 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5134 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5135 let Inst{23-22} = 0b01; // 64-bit size flag 5136 } 5137} 5138 5139 5140//--- 5141// Three operand floating point data processing 5142//--- 5143 5144let mayRaiseFPException = 1 in 5145class BaseThreeOperandFPData<bit isNegated, bit isSub, 5146 RegisterClass regtype, string asm, list<dag> pat> 5147 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5148 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5149 Sched<[WriteFMul]> { 5150 bits<5> Rd; 5151 bits<5> Rn; 5152 bits<5> Rm; 5153 bits<5> Ra; 5154 let Inst{31-24} = 0b00011111; 5155 let Inst{21} = isNegated; 5156 let Inst{20-16} = Rm; 5157 let Inst{15} = isSub; 5158 let Inst{14-10} = Ra; 5159 let Inst{9-5} = Rn; 5160 let Inst{4-0} = Rd; 5161} 5162 5163multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5164 SDPatternOperator node> { 5165 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5166 [(set (f16 FPR16:$Rd), 5167 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5168 let Inst{23-22} = 0b11; // 16-bit size flag 5169 let Predicates = [HasFullFP16]; 5170 } 5171 5172 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5173 [(set FPR32:$Rd, 5174 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5175 let Inst{23-22} = 0b00; // 32-bit size flag 5176 } 5177 5178 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5179 [(set FPR64:$Rd, 5180 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5181 let Inst{23-22} = 0b01; // 64-bit size flag 5182 } 5183} 5184 5185//--- 5186// Floating point data comparisons 5187//--- 5188 5189let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5190class BaseOneOperandFPComparison<bit signalAllNans, 5191 RegisterClass regtype, string asm, 5192 list<dag> pat> 5193 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5194 Sched<[WriteFCmp]> { 5195 bits<5> Rn; 5196 let Inst{31-24} = 0b00011110; 5197 let Inst{21} = 1; 5198 5199 let Inst{15-10} = 0b001000; 5200 let Inst{9-5} = Rn; 5201 let Inst{4} = signalAllNans; 5202 let Inst{3-0} = 0b1000; 5203 5204 // Rm should be 0b00000 canonically, but we need to accept any value. 5205 let PostEncoderMethod = "fixOneOperandFPComparison"; 5206} 5207 5208let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5209class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5210 string asm, list<dag> pat> 5211 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5212 Sched<[WriteFCmp]> { 5213 bits<5> Rm; 5214 bits<5> Rn; 5215 let Inst{31-24} = 0b00011110; 5216 let Inst{21} = 1; 5217 let Inst{20-16} = Rm; 5218 let Inst{15-10} = 0b001000; 5219 let Inst{9-5} = Rn; 5220 let Inst{4} = signalAllNans; 5221 let Inst{3-0} = 0b0000; 5222} 5223 5224multiclass FPComparison<bit signalAllNans, string asm, 5225 SDPatternOperator OpNode = null_frag> { 5226 let Defs = [NZCV] in { 5227 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5228 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5229 let Inst{23-22} = 0b11; 5230 let Predicates = [HasFullFP16]; 5231 } 5232 5233 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5234 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5235 let Inst{23-22} = 0b11; 5236 let Predicates = [HasFullFP16]; 5237 } 5238 5239 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5240 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5241 let Inst{23-22} = 0b00; 5242 } 5243 5244 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5245 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5246 let Inst{23-22} = 0b00; 5247 } 5248 5249 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5250 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5251 let Inst{23-22} = 0b01; 5252 } 5253 5254 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5255 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5256 let Inst{23-22} = 0b01; 5257 } 5258 } // Defs = [NZCV] 5259} 5260 5261//--- 5262// Floating point conditional comparisons 5263//--- 5264 5265let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5266class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5267 string mnemonic, list<dag> pat> 5268 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5269 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5270 Sched<[WriteFCmp]> { 5271 let Uses = [NZCV]; 5272 let Defs = [NZCV]; 5273 5274 bits<5> Rn; 5275 bits<5> Rm; 5276 bits<4> nzcv; 5277 bits<4> cond; 5278 5279 let Inst{31-24} = 0b00011110; 5280 let Inst{21} = 1; 5281 let Inst{20-16} = Rm; 5282 let Inst{15-12} = cond; 5283 let Inst{11-10} = 0b01; 5284 let Inst{9-5} = Rn; 5285 let Inst{4} = signalAllNans; 5286 let Inst{3-0} = nzcv; 5287} 5288 5289multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5290 SDPatternOperator OpNode = null_frag> { 5291 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5292 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5293 (i32 imm:$cond), NZCV))]> { 5294 let Inst{23-22} = 0b11; 5295 let Predicates = [HasFullFP16]; 5296 } 5297 5298 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5299 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5300 (i32 imm:$cond), NZCV))]> { 5301 let Inst{23-22} = 0b00; 5302 } 5303 5304 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5305 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5306 (i32 imm:$cond), NZCV))]> { 5307 let Inst{23-22} = 0b01; 5308 } 5309} 5310 5311//--- 5312// Floating point conditional select 5313//--- 5314 5315class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5316 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5317 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5318 [(set regtype:$Rd, 5319 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5320 (i32 imm:$cond), NZCV))]>, 5321 Sched<[WriteF]> { 5322 bits<5> Rd; 5323 bits<5> Rn; 5324 bits<5> Rm; 5325 bits<4> cond; 5326 5327 let Inst{31-24} = 0b00011110; 5328 let Inst{21} = 1; 5329 let Inst{20-16} = Rm; 5330 let Inst{15-12} = cond; 5331 let Inst{11-10} = 0b11; 5332 let Inst{9-5} = Rn; 5333 let Inst{4-0} = Rd; 5334} 5335 5336multiclass FPCondSelect<string asm> { 5337 let Uses = [NZCV] in { 5338 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5339 let Inst{23-22} = 0b11; 5340 let Predicates = [HasFullFP16]; 5341 } 5342 5343 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5344 let Inst{23-22} = 0b00; 5345 } 5346 5347 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5348 let Inst{23-22} = 0b01; 5349 } 5350 } // Uses = [NZCV] 5351} 5352 5353//--- 5354// Floating move immediate 5355//--- 5356 5357class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5358 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5359 [(set regtype:$Rd, fpimmtype:$imm)]>, 5360 Sched<[WriteFImm]> { 5361 bits<5> Rd; 5362 bits<8> imm; 5363 let Inst{31-24} = 0b00011110; 5364 let Inst{21} = 1; 5365 let Inst{20-13} = imm; 5366 let Inst{12-5} = 0b10000000; 5367 let Inst{4-0} = Rd; 5368} 5369 5370multiclass FPMoveImmediate<string asm> { 5371 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5372 let Inst{23-22} = 0b11; 5373 let Predicates = [HasFullFP16]; 5374 } 5375 5376 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5377 let Inst{23-22} = 0b00; 5378 } 5379 5380 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5381 let Inst{23-22} = 0b01; 5382 } 5383} 5384} // end of 'let Predicates = [HasFPARMv8]' 5385 5386//---------------------------------------------------------------------------- 5387// AdvSIMD 5388//---------------------------------------------------------------------------- 5389 5390let Predicates = [HasNEON] in { 5391 5392//---------------------------------------------------------------------------- 5393// AdvSIMD three register vector instructions 5394//---------------------------------------------------------------------------- 5395 5396let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5397class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5398 RegisterOperand regtype, string asm, string kind, 5399 list<dag> pattern> 5400 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5401 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5402 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5403 Sched<[!if(Q, WriteVq, WriteVd)]> { 5404 bits<5> Rd; 5405 bits<5> Rn; 5406 bits<5> Rm; 5407 let Inst{31} = 0; 5408 let Inst{30} = Q; 5409 let Inst{29} = U; 5410 let Inst{28-24} = 0b01110; 5411 let Inst{23-21} = size; 5412 let Inst{20-16} = Rm; 5413 let Inst{15-11} = opcode; 5414 let Inst{10} = 1; 5415 let Inst{9-5} = Rn; 5416 let Inst{4-0} = Rd; 5417} 5418 5419let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5420class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5421 RegisterOperand regtype, string asm, string kind, 5422 list<dag> pattern> 5423 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5424 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5425 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5426 Sched<[!if(Q, WriteVq, WriteVd)]> { 5427 bits<5> Rd; 5428 bits<5> Rn; 5429 bits<5> Rm; 5430 let Inst{31} = 0; 5431 let Inst{30} = Q; 5432 let Inst{29} = U; 5433 let Inst{28-24} = 0b01110; 5434 let Inst{23-21} = size; 5435 let Inst{20-16} = Rm; 5436 let Inst{15-11} = opcode; 5437 let Inst{10} = 1; 5438 let Inst{9-5} = Rn; 5439 let Inst{4-0} = Rd; 5440} 5441 5442let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5443class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5444 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5445 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5446 5447multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5448 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5449 [(set (v8i8 V64:$dst), 5450 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5451 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5452 [(set (v16i8 V128:$dst), 5453 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5454 (v16i8 V128:$Rm)))]>; 5455 5456 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5457 (v4i16 V64:$RHS))), 5458 (!cast<Instruction>(NAME#"v8i8") 5459 V64:$LHS, V64:$MHS, V64:$RHS)>; 5460 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5461 (v2i32 V64:$RHS))), 5462 (!cast<Instruction>(NAME#"v8i8") 5463 V64:$LHS, V64:$MHS, V64:$RHS)>; 5464 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5465 (v1i64 V64:$RHS))), 5466 (!cast<Instruction>(NAME#"v8i8") 5467 V64:$LHS, V64:$MHS, V64:$RHS)>; 5468 5469 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5470 (v8i16 V128:$RHS))), 5471 (!cast<Instruction>(NAME#"v16i8") 5472 V128:$LHS, V128:$MHS, V128:$RHS)>; 5473 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5474 (v4i32 V128:$RHS))), 5475 (!cast<Instruction>(NAME#"v16i8") 5476 V128:$LHS, V128:$MHS, V128:$RHS)>; 5477 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5478 (v2i64 V128:$RHS))), 5479 (!cast<Instruction>(NAME#"v16i8") 5480 V128:$LHS, V128:$MHS, V128:$RHS)>; 5481} 5482 5483// All operand sizes distinguished in the encoding. 5484multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5485 SDPatternOperator OpNode> { 5486 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5487 asm, ".8b", 5488 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5489 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5490 asm, ".16b", 5491 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5492 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5493 asm, ".4h", 5494 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5495 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5496 asm, ".8h", 5497 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5498 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5499 asm, ".2s", 5500 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5501 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5502 asm, ".4s", 5503 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5504 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5505 asm, ".2d", 5506 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5507} 5508 5509multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5510 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5511 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5512 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5513 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5514 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5515 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5516 5517 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5518 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5519 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5520 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5521 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5522 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5523 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5524 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5525} 5526 5527// As above, but D sized elements unsupported. 5528multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5529 SDPatternOperator OpNode> { 5530 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5531 asm, ".8b", 5532 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5533 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5534 asm, ".16b", 5535 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5536 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5537 asm, ".4h", 5538 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5539 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5540 asm, ".8h", 5541 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5542 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5543 asm, ".2s", 5544 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5545 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5546 asm, ".4s", 5547 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5548} 5549 5550multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5551 SDPatternOperator OpNode> { 5552 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5553 asm, ".8b", 5554 [(set (v8i8 V64:$dst), 5555 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5556 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5557 asm, ".16b", 5558 [(set (v16i8 V128:$dst), 5559 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5560 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5561 asm, ".4h", 5562 [(set (v4i16 V64:$dst), 5563 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5564 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5565 asm, ".8h", 5566 [(set (v8i16 V128:$dst), 5567 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5568 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5569 asm, ".2s", 5570 [(set (v2i32 V64:$dst), 5571 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5572 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5573 asm, ".4s", 5574 [(set (v4i32 V128:$dst), 5575 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5576} 5577 5578// As above, but only B sized elements supported. 5579multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5580 SDPatternOperator OpNode> { 5581 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5582 asm, ".8b", 5583 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5584 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5585 asm, ".16b", 5586 [(set (v16i8 V128:$Rd), 5587 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5588} 5589 5590// As above, but only floating point elements supported. 5591let mayRaiseFPException = 1 in 5592multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5593 string asm, SDPatternOperator OpNode> { 5594 let Predicates = [HasNEON, HasFullFP16] in { 5595 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5596 asm, ".4h", 5597 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5598 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5599 asm, ".8h", 5600 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5601 } // Predicates = [HasNEON, HasFullFP16] 5602 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5603 asm, ".2s", 5604 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5605 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5606 asm, ".4s", 5607 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5608 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5609 asm, ".2d", 5610 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5611} 5612 5613let mayRaiseFPException = 1 in 5614multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5615 string asm, 5616 SDPatternOperator OpNode> { 5617 let Predicates = [HasNEON, HasFullFP16] in { 5618 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5619 asm, ".4h", 5620 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5621 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5622 asm, ".8h", 5623 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5624 } // Predicates = [HasNEON, HasFullFP16] 5625 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5626 asm, ".2s", 5627 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5628 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5629 asm, ".4s", 5630 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5631 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5632 asm, ".2d", 5633 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5634} 5635 5636let mayRaiseFPException = 1 in 5637multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5638 string asm, SDPatternOperator OpNode> { 5639 let Predicates = [HasNEON, HasFullFP16] in { 5640 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5641 asm, ".4h", 5642 [(set (v4f16 V64:$dst), 5643 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5644 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5645 asm, ".8h", 5646 [(set (v8f16 V128:$dst), 5647 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5648 } // Predicates = [HasNEON, HasFullFP16] 5649 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5650 asm, ".2s", 5651 [(set (v2f32 V64:$dst), 5652 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5653 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5654 asm, ".4s", 5655 [(set (v4f32 V128:$dst), 5656 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5657 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5658 asm, ".2d", 5659 [(set (v2f64 V128:$dst), 5660 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5661} 5662 5663// As above, but D and B sized elements unsupported. 5664let mayRaiseFPException = 1 in 5665multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5666 SDPatternOperator OpNode> { 5667 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5668 asm, ".4h", 5669 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5670 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5671 asm, ".8h", 5672 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5673 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5674 asm, ".2s", 5675 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5676 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5677 asm, ".4s", 5678 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5679} 5680 5681// Logical three vector ops share opcode bits, and only use B sized elements. 5682multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5683 SDPatternOperator OpNode = null_frag> { 5684 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5685 asm, ".8b", 5686 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5687 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5688 asm, ".16b", 5689 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5690 5691 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5692 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5693 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5694 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5695 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5696 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5697 5698 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5699 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5700 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5701 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5702 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5703 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5704} 5705 5706multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5707 string asm, SDPatternOperator OpNode = null_frag> { 5708 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5709 asm, ".8b", 5710 [(set (v8i8 V64:$dst), 5711 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5712 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5713 asm, ".16b", 5714 [(set (v16i8 V128:$dst), 5715 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5716 (v16i8 V128:$Rm)))]>; 5717 5718 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5719 (v4i16 V64:$RHS))), 5720 (!cast<Instruction>(NAME#"v8i8") 5721 V64:$LHS, V64:$MHS, V64:$RHS)>; 5722 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5723 (v2i32 V64:$RHS))), 5724 (!cast<Instruction>(NAME#"v8i8") 5725 V64:$LHS, V64:$MHS, V64:$RHS)>; 5726 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5727 (v1i64 V64:$RHS))), 5728 (!cast<Instruction>(NAME#"v8i8") 5729 V64:$LHS, V64:$MHS, V64:$RHS)>; 5730 5731 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5732 (v8i16 V128:$RHS))), 5733 (!cast<Instruction>(NAME#"v16i8") 5734 V128:$LHS, V128:$MHS, V128:$RHS)>; 5735 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5736 (v4i32 V128:$RHS))), 5737 (!cast<Instruction>(NAME#"v16i8") 5738 V128:$LHS, V128:$MHS, V128:$RHS)>; 5739 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5740 (v2i64 V128:$RHS))), 5741 (!cast<Instruction>(NAME#"v16i8") 5742 V128:$LHS, V128:$MHS, V128:$RHS)>; 5743} 5744 5745// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5746// bytes from S-sized elements. 5747class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5748 string kind2, RegisterOperand RegType, 5749 ValueType AccumType, ValueType InputType, 5750 SDPatternOperator OpNode> : 5751 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5752 [(set (AccumType RegType:$dst), 5753 (OpNode (AccumType RegType:$Rd), 5754 (InputType RegType:$Rn), 5755 (InputType RegType:$Rm)))]> { 5756 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5757} 5758 5759multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5760 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5761 v2i32, v8i8, OpNode>; 5762 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5763 v4i32, v16i8, OpNode>; 5764} 5765 5766// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5767// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5768// 8H to 4S, when Q=1). 5769let mayRaiseFPException = 1 in 5770class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5771 string kind2, RegisterOperand RegType, 5772 ValueType AccumType, ValueType InputType, 5773 SDPatternOperator OpNode> : 5774 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5775 [(set (AccumType RegType:$dst), 5776 (OpNode (AccumType RegType:$Rd), 5777 (InputType RegType:$Rn), 5778 (InputType RegType:$Rm)))]> { 5779 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5780 let Inst{13} = b13; 5781} 5782 5783multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5784 SDPatternOperator OpNode> { 5785 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5786 v2f32, v4f16, OpNode>; 5787 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5788 v4f32, v8f16, OpNode>; 5789} 5790 5791 5792//---------------------------------------------------------------------------- 5793// AdvSIMD two register vector instructions. 5794//---------------------------------------------------------------------------- 5795 5796let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5797class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5798 bits<2> size2, RegisterOperand regtype, string asm, 5799 string dstkind, string srckind, list<dag> pattern> 5800 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5801 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5802 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5803 Sched<[!if(Q, WriteVq, WriteVd)]> { 5804 bits<5> Rd; 5805 bits<5> Rn; 5806 let Inst{31} = 0; 5807 let Inst{30} = Q; 5808 let Inst{29} = U; 5809 let Inst{28-24} = 0b01110; 5810 let Inst{23-22} = size; 5811 let Inst{21} = 0b1; 5812 let Inst{20-19} = size2; 5813 let Inst{18-17} = 0b00; 5814 let Inst{16-12} = opcode; 5815 let Inst{11-10} = 0b10; 5816 let Inst{9-5} = Rn; 5817 let Inst{4-0} = Rd; 5818} 5819 5820let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5821class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5822 bits<2> size2, RegisterOperand regtype, 5823 string asm, string dstkind, string srckind, 5824 list<dag> pattern> 5825 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5826 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5827 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5828 Sched<[!if(Q, WriteVq, WriteVd)]> { 5829 bits<5> Rd; 5830 bits<5> Rn; 5831 let Inst{31} = 0; 5832 let Inst{30} = Q; 5833 let Inst{29} = U; 5834 let Inst{28-24} = 0b01110; 5835 let Inst{23-22} = size; 5836 let Inst{21} = 0b1; 5837 let Inst{20-19} = size2; 5838 let Inst{18-17} = 0b00; 5839 let Inst{16-12} = opcode; 5840 let Inst{11-10} = 0b10; 5841 let Inst{9-5} = Rn; 5842 let Inst{4-0} = Rd; 5843} 5844 5845// Supports B, H, and S element sizes. 5846multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5847 SDPatternOperator OpNode> { 5848 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5849 asm, ".8b", ".8b", 5850 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5851 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5852 asm, ".16b", ".16b", 5853 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5854 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5855 asm, ".4h", ".4h", 5856 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5857 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5858 asm, ".8h", ".8h", 5859 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5860 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5861 asm, ".2s", ".2s", 5862 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5863 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5864 asm, ".4s", ".4s", 5865 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5866} 5867 5868class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5869 RegisterOperand regtype, string asm, string dstkind, 5870 string srckind, string amount> 5871 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5872 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5873 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5874 Sched<[WriteVq]> { 5875 bits<5> Rd; 5876 bits<5> Rn; 5877 let Inst{31} = 0; 5878 let Inst{30} = Q; 5879 let Inst{29-24} = 0b101110; 5880 let Inst{23-22} = size; 5881 let Inst{21-10} = 0b100001001110; 5882 let Inst{9-5} = Rn; 5883 let Inst{4-0} = Rd; 5884} 5885 5886multiclass SIMDVectorLShiftLongBySizeBHS { 5887 let hasSideEffects = 0 in { 5888 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5889 "shll", ".8h", ".8b", "8">; 5890 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5891 "shll2", ".8h", ".16b", "8">; 5892 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5893 "shll", ".4s", ".4h", "16">; 5894 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5895 "shll2", ".4s", ".8h", "16">; 5896 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5897 "shll", ".2d", ".2s", "32">; 5898 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5899 "shll2", ".2d", ".4s", "32">; 5900 } 5901} 5902 5903// Supports all element sizes. 5904multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5905 SDPatternOperator OpNode> { 5906 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5907 asm, ".4h", ".8b", 5908 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5909 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5910 asm, ".8h", ".16b", 5911 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5912 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5913 asm, ".2s", ".4h", 5914 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5915 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5916 asm, ".4s", ".8h", 5917 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5918 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5919 asm, ".1d", ".2s", 5920 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5921 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5922 asm, ".2d", ".4s", 5923 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5924} 5925 5926multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5927 SDPatternOperator OpNode> { 5928 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5929 asm, ".4h", ".8b", 5930 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5931 (v8i8 V64:$Rn)))]>; 5932 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5933 asm, ".8h", ".16b", 5934 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5935 (v16i8 V128:$Rn)))]>; 5936 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5937 asm, ".2s", ".4h", 5938 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5939 (v4i16 V64:$Rn)))]>; 5940 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5941 asm, ".4s", ".8h", 5942 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5943 (v8i16 V128:$Rn)))]>; 5944 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5945 asm, ".1d", ".2s", 5946 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5947 (v2i32 V64:$Rn)))]>; 5948 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5949 asm, ".2d", ".4s", 5950 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5951 (v4i32 V128:$Rn)))]>; 5952} 5953 5954// Supports all element sizes, except 1xD. 5955multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5956 SDPatternOperator OpNode> { 5957 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5958 asm, ".8b", ".8b", 5959 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5960 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5961 asm, ".16b", ".16b", 5962 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5963 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5964 asm, ".4h", ".4h", 5965 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5966 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5967 asm, ".8h", ".8h", 5968 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5969 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5970 asm, ".2s", ".2s", 5971 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5972 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5973 asm, ".4s", ".4s", 5974 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5975 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5976 asm, ".2d", ".2d", 5977 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5978} 5979 5980multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5981 SDPatternOperator OpNode = null_frag> { 5982 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5983 asm, ".8b", ".8b", 5984 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5985 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5986 asm, ".16b", ".16b", 5987 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5988 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5989 asm, ".4h", ".4h", 5990 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5991 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5992 asm, ".8h", ".8h", 5993 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5994 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5995 asm, ".2s", ".2s", 5996 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5997 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5998 asm, ".4s", ".4s", 5999 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6000 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6001 asm, ".2d", ".2d", 6002 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6003} 6004 6005 6006// Supports only B element sizes. 6007multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6008 SDPatternOperator OpNode> { 6009 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6010 asm, ".8b", ".8b", 6011 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6012 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6013 asm, ".16b", ".16b", 6014 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6015 6016} 6017 6018// Supports only B and H element sizes. 6019multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6020 SDPatternOperator OpNode> { 6021 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6022 asm, ".8b", ".8b", 6023 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6024 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6025 asm, ".16b", ".16b", 6026 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6027 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6028 asm, ".4h", ".4h", 6029 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6030 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6031 asm, ".8h", ".8h", 6032 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6033} 6034 6035// Supports H, S and D element sizes, uses high bit of the size field 6036// as an extra opcode bit. 6037multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6038 SDPatternOperator OpNode, 6039 int fpexceptions = 1> { 6040 let mayRaiseFPException = fpexceptions in { 6041 let Predicates = [HasNEON, HasFullFP16] in { 6042 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6043 asm, ".4h", ".4h", 6044 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6045 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6046 asm, ".8h", ".8h", 6047 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6048 } // Predicates = [HasNEON, HasFullFP16] 6049 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6050 asm, ".2s", ".2s", 6051 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6052 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6053 asm, ".4s", ".4s", 6054 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6055 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6056 asm, ".2d", ".2d", 6057 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6058 } 6059} 6060 6061multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6062 SDPatternOperator OpNode> 6063 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6064 6065// Supports only S and D element sizes 6066let mayRaiseFPException = 1 in 6067multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6068 SDPatternOperator OpNode = null_frag> { 6069 6070 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6071 asm, ".2s", ".2s", 6072 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6073 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6074 asm, ".4s", ".4s", 6075 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6076 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6077 asm, ".2d", ".2d", 6078 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6079} 6080 6081multiclass FRIntNNTVector<bit U, bit op, string asm, 6082 SDPatternOperator OpNode = null_frag> : 6083 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6084 6085// Supports only S element size. 6086multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6087 SDPatternOperator OpNode> { 6088 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6089 asm, ".2s", ".2s", 6090 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6091 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6092 asm, ".4s", ".4s", 6093 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6094} 6095 6096let mayRaiseFPException = 1 in 6097multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6098 SDPatternOperator OpNode> { 6099 let Predicates = [HasNEON, HasFullFP16] in { 6100 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6101 asm, ".4h", ".4h", 6102 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6103 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6104 asm, ".8h", ".8h", 6105 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6106 } // Predicates = [HasNEON, HasFullFP16] 6107 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6108 asm, ".2s", ".2s", 6109 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6110 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6111 asm, ".4s", ".4s", 6112 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6113 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6114 asm, ".2d", ".2d", 6115 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6116} 6117 6118let mayRaiseFPException = 1 in 6119multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6120 SDPatternOperator OpNode> { 6121 let Predicates = [HasNEON, HasFullFP16] in { 6122 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6123 asm, ".4h", ".4h", 6124 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6125 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6126 asm, ".8h", ".8h", 6127 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6128 } // Predicates = [HasNEON, HasFullFP16] 6129 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6130 asm, ".2s", ".2s", 6131 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6132 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6133 asm, ".4s", ".4s", 6134 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6135 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6136 asm, ".2d", ".2d", 6137 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6138} 6139 6140let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6141class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6142 RegisterOperand inreg, RegisterOperand outreg, 6143 string asm, string outkind, string inkind, 6144 list<dag> pattern> 6145 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6146 "{\t$Rd" # outkind # ", $Rn" # inkind # 6147 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6148 Sched<[WriteVq]> { 6149 bits<5> Rd; 6150 bits<5> Rn; 6151 let Inst{31} = 0; 6152 let Inst{30} = Q; 6153 let Inst{29} = U; 6154 let Inst{28-24} = 0b01110; 6155 let Inst{23-22} = size; 6156 let Inst{21-17} = 0b10000; 6157 let Inst{16-12} = opcode; 6158 let Inst{11-10} = 0b10; 6159 let Inst{9-5} = Rn; 6160 let Inst{4-0} = Rd; 6161} 6162 6163let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6164class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6165 RegisterOperand inreg, RegisterOperand outreg, 6166 string asm, string outkind, string inkind, 6167 list<dag> pattern> 6168 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6169 "{\t$Rd" # outkind # ", $Rn" # inkind # 6170 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6171 Sched<[WriteVq]> { 6172 bits<5> Rd; 6173 bits<5> Rn; 6174 let Inst{31} = 0; 6175 let Inst{30} = Q; 6176 let Inst{29} = U; 6177 let Inst{28-24} = 0b01110; 6178 let Inst{23-22} = size; 6179 let Inst{21-17} = 0b10000; 6180 let Inst{16-12} = opcode; 6181 let Inst{11-10} = 0b10; 6182 let Inst{9-5} = Rn; 6183 let Inst{4-0} = Rd; 6184} 6185 6186multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6187 SDPatternOperator OpNode> { 6188 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6189 asm, ".8b", ".8h", 6190 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6191 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6192 asm#"2", ".16b", ".8h", []>; 6193 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6194 asm, ".4h", ".4s", 6195 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6196 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6197 asm#"2", ".8h", ".4s", []>; 6198 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6199 asm, ".2s", ".2d", 6200 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6201 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6202 asm#"2", ".4s", ".2d", []>; 6203 6204 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6205 (!cast<Instruction>(NAME # "v16i8") 6206 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6207 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6208 (!cast<Instruction>(NAME # "v8i16") 6209 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6210 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6211 (!cast<Instruction>(NAME # "v4i32") 6212 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6213} 6214 6215class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6216 bits<5> opcode, RegisterOperand regtype, string asm, 6217 string kind, string zero, ValueType dty, 6218 ValueType sty, SDNode OpNode> 6219 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6220 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6221 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6222 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6223 Sched<[!if(Q, WriteVq, WriteVd)]> { 6224 bits<5> Rd; 6225 bits<5> Rn; 6226 let Inst{31} = 0; 6227 let Inst{30} = Q; 6228 let Inst{29} = U; 6229 let Inst{28-24} = 0b01110; 6230 let Inst{23-22} = size; 6231 let Inst{21} = 0b1; 6232 let Inst{20-19} = size2; 6233 let Inst{18-17} = 0b00; 6234 let Inst{16-12} = opcode; 6235 let Inst{11-10} = 0b10; 6236 let Inst{9-5} = Rn; 6237 let Inst{4-0} = Rd; 6238} 6239 6240// Comparisons support all element sizes, except 1xD. 6241multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6242 SDNode OpNode> { 6243 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6244 asm, ".8b", "0", 6245 v8i8, v8i8, OpNode>; 6246 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6247 asm, ".16b", "0", 6248 v16i8, v16i8, OpNode>; 6249 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6250 asm, ".4h", "0", 6251 v4i16, v4i16, OpNode>; 6252 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6253 asm, ".8h", "0", 6254 v8i16, v8i16, OpNode>; 6255 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6256 asm, ".2s", "0", 6257 v2i32, v2i32, OpNode>; 6258 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6259 asm, ".4s", "0", 6260 v4i32, v4i32, OpNode>; 6261 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6262 asm, ".2d", "0", 6263 v2i64, v2i64, OpNode>; 6264} 6265 6266// FP Comparisons support only S and D element sizes (and H for v8.2a). 6267multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6268 string asm, SDNode OpNode> { 6269 6270 let mayRaiseFPException = 1 in { 6271 let Predicates = [HasNEON, HasFullFP16] in { 6272 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6273 asm, ".4h", "0.0", 6274 v4i16, v4f16, OpNode>; 6275 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6276 asm, ".8h", "0.0", 6277 v8i16, v8f16, OpNode>; 6278 } // Predicates = [HasNEON, HasFullFP16] 6279 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6280 asm, ".2s", "0.0", 6281 v2i32, v2f32, OpNode>; 6282 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6283 asm, ".4s", "0.0", 6284 v4i32, v4f32, OpNode>; 6285 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6286 asm, ".2d", "0.0", 6287 v2i64, v2f64, OpNode>; 6288 } 6289 6290 let Predicates = [HasNEON, HasFullFP16] in { 6291 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6292 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6293 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6294 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6295 } 6296 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6297 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6298 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6299 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6300 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6301 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6302 let Predicates = [HasNEON, HasFullFP16] in { 6303 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6304 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6305 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6306 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6307 } 6308 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6309 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6310 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6311 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6312 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6313 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6314} 6315 6316let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 6317class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6318 RegisterOperand outtype, RegisterOperand intype, 6319 string asm, string VdTy, string VnTy, 6320 list<dag> pattern> 6321 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6322 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6323 Sched<[WriteVq]> { 6324 bits<5> Rd; 6325 bits<5> Rn; 6326 let Inst{31} = 0; 6327 let Inst{30} = Q; 6328 let Inst{29} = U; 6329 let Inst{28-24} = 0b01110; 6330 let Inst{23-22} = size; 6331 let Inst{21-17} = 0b10000; 6332 let Inst{16-12} = opcode; 6333 let Inst{11-10} = 0b10; 6334 let Inst{9-5} = Rn; 6335 let Inst{4-0} = Rd; 6336} 6337 6338let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 6339class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6340 RegisterOperand outtype, RegisterOperand intype, 6341 string asm, string VdTy, string VnTy, 6342 list<dag> pattern> 6343 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6344 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6345 Sched<[WriteVq]> { 6346 bits<5> Rd; 6347 bits<5> Rn; 6348 let Inst{31} = 0; 6349 let Inst{30} = Q; 6350 let Inst{29} = U; 6351 let Inst{28-24} = 0b01110; 6352 let Inst{23-22} = size; 6353 let Inst{21-17} = 0b10000; 6354 let Inst{16-12} = opcode; 6355 let Inst{11-10} = 0b10; 6356 let Inst{9-5} = Rn; 6357 let Inst{4-0} = Rd; 6358} 6359 6360multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6361 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6362 asm, ".4s", ".4h", []>; 6363 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6364 asm#"2", ".4s", ".8h", []>; 6365 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6366 asm, ".2d", ".2s", []>; 6367 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6368 asm#"2", ".2d", ".4s", []>; 6369} 6370 6371multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6372 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6373 asm, ".4h", ".4s", []>; 6374 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6375 asm#"2", ".8h", ".4s", []>; 6376 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6377 asm, ".2s", ".2d", []>; 6378 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6379 asm#"2", ".4s", ".2d", []>; 6380} 6381 6382multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6383 Intrinsic OpNode> { 6384 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6385 asm, ".2s", ".2d", 6386 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6387 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6388 asm#"2", ".4s", ".2d", []>; 6389 6390 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6391 (!cast<Instruction>(NAME # "v4f32") 6392 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6393} 6394 6395//---------------------------------------------------------------------------- 6396// AdvSIMD three register different-size vector instructions. 6397//---------------------------------------------------------------------------- 6398 6399let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6400class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6401 RegisterOperand outtype, RegisterOperand intype1, 6402 RegisterOperand intype2, string asm, 6403 string outkind, string inkind1, string inkind2, 6404 list<dag> pattern> 6405 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6406 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6407 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6408 Sched<[WriteVq]> { 6409 bits<5> Rd; 6410 bits<5> Rn; 6411 bits<5> Rm; 6412 let Inst{31} = 0; 6413 let Inst{30} = size{0}; 6414 let Inst{29} = U; 6415 let Inst{28-24} = 0b01110; 6416 let Inst{23-22} = size{2-1}; 6417 let Inst{21} = 1; 6418 let Inst{20-16} = Rm; 6419 let Inst{15-12} = opcode; 6420 let Inst{11-10} = 0b00; 6421 let Inst{9-5} = Rn; 6422 let Inst{4-0} = Rd; 6423} 6424 6425let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6426class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6427 RegisterOperand outtype, RegisterOperand intype1, 6428 RegisterOperand intype2, string asm, 6429 string outkind, string inkind1, string inkind2, 6430 list<dag> pattern> 6431 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6432 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6433 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6434 Sched<[WriteVq]> { 6435 bits<5> Rd; 6436 bits<5> Rn; 6437 bits<5> Rm; 6438 let Inst{31} = 0; 6439 let Inst{30} = size{0}; 6440 let Inst{29} = U; 6441 let Inst{28-24} = 0b01110; 6442 let Inst{23-22} = size{2-1}; 6443 let Inst{21} = 1; 6444 let Inst{20-16} = Rm; 6445 let Inst{15-12} = opcode; 6446 let Inst{11-10} = 0b00; 6447 let Inst{9-5} = Rn; 6448 let Inst{4-0} = Rd; 6449} 6450 6451// FIXME: TableGen doesn't know how to deal with expanded types that also 6452// change the element count (in this case, placing the results in 6453// the high elements of the result register rather than the low 6454// elements). Until that's fixed, we can't code-gen those. 6455multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6456 Intrinsic IntOp> { 6457 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6458 V64, V128, V128, 6459 asm, ".8b", ".8h", ".8h", 6460 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6461 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6462 V128, V128, V128, 6463 asm#"2", ".16b", ".8h", ".8h", 6464 []>; 6465 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6466 V64, V128, V128, 6467 asm, ".4h", ".4s", ".4s", 6468 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6469 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6470 V128, V128, V128, 6471 asm#"2", ".8h", ".4s", ".4s", 6472 []>; 6473 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6474 V64, V128, V128, 6475 asm, ".2s", ".2d", ".2d", 6476 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6477 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6478 V128, V128, V128, 6479 asm#"2", ".4s", ".2d", ".2d", 6480 []>; 6481 6482 6483 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6484 // a version attached to an instruction. 6485 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6486 (v8i16 V128:$Rm))), 6487 (!cast<Instruction>(NAME # "v8i16_v16i8") 6488 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6489 V128:$Rn, V128:$Rm)>; 6490 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6491 (v4i32 V128:$Rm))), 6492 (!cast<Instruction>(NAME # "v4i32_v8i16") 6493 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6494 V128:$Rn, V128:$Rm)>; 6495 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6496 (v2i64 V128:$Rm))), 6497 (!cast<Instruction>(NAME # "v2i64_v4i32") 6498 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6499 V128:$Rn, V128:$Rm)>; 6500} 6501 6502multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6503 Intrinsic IntOp> { 6504 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6505 V128, V64, V64, 6506 asm, ".8h", ".8b", ".8b", 6507 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6508 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6509 V128, V128, V128, 6510 asm#"2", ".8h", ".16b", ".16b", []>; 6511 let Predicates = [HasAES] in { 6512 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6513 V128, V64, V64, 6514 asm, ".1q", ".1d", ".1d", []>; 6515 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6516 V128, V128, V128, 6517 asm#"2", ".1q", ".2d", ".2d", []>; 6518 } 6519 6520 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6521 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6522 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6523} 6524 6525multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6526 SDPatternOperator OpNode> { 6527 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6528 V128, V64, V64, 6529 asm, ".4s", ".4h", ".4h", 6530 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6531 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6532 V128, V128, V128, 6533 asm#"2", ".4s", ".8h", ".8h", 6534 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6535 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6536 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6537 V128, V64, V64, 6538 asm, ".2d", ".2s", ".2s", 6539 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6540 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6541 V128, V128, V128, 6542 asm#"2", ".2d", ".4s", ".4s", 6543 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6544 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6545} 6546 6547multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6548 SDPatternOperator OpNode = null_frag> { 6549 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6550 V128, V64, V64, 6551 asm, ".8h", ".8b", ".8b", 6552 [(set (v8i16 V128:$Rd), 6553 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6554 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6555 V128, V128, V128, 6556 asm#"2", ".8h", ".16b", ".16b", 6557 [(set (v8i16 V128:$Rd), 6558 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6559 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 6560 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6561 V128, V64, V64, 6562 asm, ".4s", ".4h", ".4h", 6563 [(set (v4i32 V128:$Rd), 6564 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6565 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6566 V128, V128, V128, 6567 asm#"2", ".4s", ".8h", ".8h", 6568 [(set (v4i32 V128:$Rd), 6569 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6570 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6571 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6572 V128, V64, V64, 6573 asm, ".2d", ".2s", ".2s", 6574 [(set (v2i64 V128:$Rd), 6575 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6576 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6577 V128, V128, V128, 6578 asm#"2", ".2d", ".4s", ".4s", 6579 [(set (v2i64 V128:$Rd), 6580 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6581 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6582} 6583 6584multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6585 string asm, 6586 SDPatternOperator OpNode> { 6587 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6588 V128, V64, V64, 6589 asm, ".8h", ".8b", ".8b", 6590 [(set (v8i16 V128:$dst), 6591 (add (v8i16 V128:$Rd), 6592 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6593 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6594 V128, V128, V128, 6595 asm#"2", ".8h", ".16b", ".16b", 6596 [(set (v8i16 V128:$dst), 6597 (add (v8i16 V128:$Rd), 6598 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6599 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 6600 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6601 V128, V64, V64, 6602 asm, ".4s", ".4h", ".4h", 6603 [(set (v4i32 V128:$dst), 6604 (add (v4i32 V128:$Rd), 6605 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6606 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6607 V128, V128, V128, 6608 asm#"2", ".4s", ".8h", ".8h", 6609 [(set (v4i32 V128:$dst), 6610 (add (v4i32 V128:$Rd), 6611 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6612 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 6613 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6614 V128, V64, V64, 6615 asm, ".2d", ".2s", ".2s", 6616 [(set (v2i64 V128:$dst), 6617 (add (v2i64 V128:$Rd), 6618 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6619 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6620 V128, V128, V128, 6621 asm#"2", ".2d", ".4s", ".4s", 6622 [(set (v2i64 V128:$dst), 6623 (add (v2i64 V128:$Rd), 6624 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6625 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 6626} 6627 6628multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6629 SDPatternOperator OpNode = null_frag> { 6630 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6631 V128, V64, V64, 6632 asm, ".8h", ".8b", ".8b", 6633 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6634 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6635 V128, V128, V128, 6636 asm#"2", ".8h", ".16b", ".16b", 6637 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6638 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6639 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6640 V128, V64, V64, 6641 asm, ".4s", ".4h", ".4h", 6642 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6643 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6644 V128, V128, V128, 6645 asm#"2", ".4s", ".8h", ".8h", 6646 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6647 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6648 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6649 V128, V64, V64, 6650 asm, ".2d", ".2s", ".2s", 6651 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6652 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6653 V128, V128, V128, 6654 asm#"2", ".2d", ".4s", ".4s", 6655 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6656 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6657} 6658 6659multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6660 string asm, 6661 SDPatternOperator OpNode> { 6662 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6663 V128, V64, V64, 6664 asm, ".8h", ".8b", ".8b", 6665 [(set (v8i16 V128:$dst), 6666 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6667 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6668 V128, V128, V128, 6669 asm#"2", ".8h", ".16b", ".16b", 6670 [(set (v8i16 V128:$dst), 6671 (OpNode (v8i16 V128:$Rd), 6672 (extract_high_v16i8 (v16i8 V128:$Rn)), 6673 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6674 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6675 V128, V64, V64, 6676 asm, ".4s", ".4h", ".4h", 6677 [(set (v4i32 V128:$dst), 6678 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6679 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6680 V128, V128, V128, 6681 asm#"2", ".4s", ".8h", ".8h", 6682 [(set (v4i32 V128:$dst), 6683 (OpNode (v4i32 V128:$Rd), 6684 (extract_high_v8i16 (v8i16 V128:$Rn)), 6685 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6686 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6687 V128, V64, V64, 6688 asm, ".2d", ".2s", ".2s", 6689 [(set (v2i64 V128:$dst), 6690 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6691 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6692 V128, V128, V128, 6693 asm#"2", ".2d", ".4s", ".4s", 6694 [(set (v2i64 V128:$dst), 6695 (OpNode (v2i64 V128:$Rd), 6696 (extract_high_v4i32 (v4i32 V128:$Rn)), 6697 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6698} 6699 6700multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6701 SDPatternOperator Accum> { 6702 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6703 V128, V64, V64, 6704 asm, ".4s", ".4h", ".4h", 6705 [(set (v4i32 V128:$dst), 6706 (Accum (v4i32 V128:$Rd), 6707 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6708 (v4i16 V64:$Rm)))))]>; 6709 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6710 V128, V128, V128, 6711 asm#"2", ".4s", ".8h", ".8h", 6712 [(set (v4i32 V128:$dst), 6713 (Accum (v4i32 V128:$Rd), 6714 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 6715 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6716 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6717 V128, V64, V64, 6718 asm, ".2d", ".2s", ".2s", 6719 [(set (v2i64 V128:$dst), 6720 (Accum (v2i64 V128:$Rd), 6721 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6722 (v2i32 V64:$Rm)))))]>; 6723 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6724 V128, V128, V128, 6725 asm#"2", ".2d", ".4s", ".4s", 6726 [(set (v2i64 V128:$dst), 6727 (Accum (v2i64 V128:$Rd), 6728 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 6729 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6730} 6731 6732multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6733 SDPatternOperator OpNode> { 6734 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6735 V128, V128, V64, 6736 asm, ".8h", ".8h", ".8b", 6737 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6738 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6739 V128, V128, V128, 6740 asm#"2", ".8h", ".8h", ".16b", 6741 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6742 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6743 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6744 V128, V128, V64, 6745 asm, ".4s", ".4s", ".4h", 6746 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6747 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6748 V128, V128, V128, 6749 asm#"2", ".4s", ".4s", ".8h", 6750 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6751 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6752 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6753 V128, V128, V64, 6754 asm, ".2d", ".2d", ".2s", 6755 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6756 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6757 V128, V128, V128, 6758 asm#"2", ".2d", ".2d", ".4s", 6759 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6760 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6761} 6762 6763//---------------------------------------------------------------------------- 6764// AdvSIMD bitwise extract from vector 6765//---------------------------------------------------------------------------- 6766 6767class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6768 string asm, string kind> 6769 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6770 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6771 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6772 [(set (vty regtype:$Rd), 6773 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6774 Sched<[!if(size, WriteVq, WriteVd)]> { 6775 bits<5> Rd; 6776 bits<5> Rn; 6777 bits<5> Rm; 6778 bits<4> imm; 6779 let Inst{31} = 0; 6780 let Inst{30} = size; 6781 let Inst{29-21} = 0b101110000; 6782 let Inst{20-16} = Rm; 6783 let Inst{15} = 0; 6784 let Inst{14-11} = imm; 6785 let Inst{10} = 0; 6786 let Inst{9-5} = Rn; 6787 let Inst{4-0} = Rd; 6788} 6789 6790 6791multiclass SIMDBitwiseExtract<string asm> { 6792 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6793 let imm{3} = 0; 6794 } 6795 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6796} 6797 6798//---------------------------------------------------------------------------- 6799// AdvSIMD zip vector 6800//---------------------------------------------------------------------------- 6801 6802class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6803 string asm, string kind, SDNode OpNode, ValueType valty> 6804 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6805 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6806 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6807 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6808 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 6809 bits<5> Rd; 6810 bits<5> Rn; 6811 bits<5> Rm; 6812 let Inst{31} = 0; 6813 let Inst{30} = size{0}; 6814 let Inst{29-24} = 0b001110; 6815 let Inst{23-22} = size{2-1}; 6816 let Inst{21} = 0; 6817 let Inst{20-16} = Rm; 6818 let Inst{15} = 0; 6819 let Inst{14-12} = opc; 6820 let Inst{11-10} = 0b10; 6821 let Inst{9-5} = Rn; 6822 let Inst{4-0} = Rd; 6823} 6824 6825multiclass SIMDZipVector<bits<3>opc, string asm, 6826 SDNode OpNode> { 6827 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6828 asm, ".8b", OpNode, v8i8>; 6829 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6830 asm, ".16b", OpNode, v16i8>; 6831 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6832 asm, ".4h", OpNode, v4i16>; 6833 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6834 asm, ".8h", OpNode, v8i16>; 6835 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6836 asm, ".2s", OpNode, v2i32>; 6837 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6838 asm, ".4s", OpNode, v4i32>; 6839 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6840 asm, ".2d", OpNode, v2i64>; 6841 6842 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6843 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6844 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6845 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6846 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6847 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6848 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6849 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6850 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6851 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6852} 6853 6854//---------------------------------------------------------------------------- 6855// AdvSIMD three register scalar instructions 6856//---------------------------------------------------------------------------- 6857 6858let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6859class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6860 RegisterClass regtype, string asm, 6861 list<dag> pattern> 6862 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6863 "\t$Rd, $Rn, $Rm", "", pattern>, 6864 Sched<[WriteVd]> { 6865 bits<5> Rd; 6866 bits<5> Rn; 6867 bits<5> Rm; 6868 let Inst{31-30} = 0b01; 6869 let Inst{29} = U; 6870 let Inst{28-24} = 0b11110; 6871 let Inst{23-21} = size; 6872 let Inst{20-16} = Rm; 6873 let Inst{15-11} = opcode; 6874 let Inst{10} = 1; 6875 let Inst{9-5} = Rn; 6876 let Inst{4-0} = Rd; 6877} 6878 6879let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6880class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6881 dag oops, dag iops, string asm, 6882 list<dag> pattern> 6883 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6884 Sched<[WriteVd]> { 6885 bits<5> Rd; 6886 bits<5> Rn; 6887 bits<5> Rm; 6888 let Inst{31-30} = 0b01; 6889 let Inst{29} = U; 6890 let Inst{28-24} = 0b11110; 6891 let Inst{23-22} = size; 6892 let Inst{21} = R; 6893 let Inst{20-16} = Rm; 6894 let Inst{15-11} = opcode; 6895 let Inst{10} = 1; 6896 let Inst{9-5} = Rn; 6897 let Inst{4-0} = Rd; 6898} 6899 6900multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6901 SDPatternOperator OpNode> { 6902 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6903 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6904} 6905 6906multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6907 SDPatternOperator OpNode> { 6908 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6909 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6910 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6911 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6912 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6913 6914 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6915 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6916 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6917 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6918} 6919 6920multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6921 SDPatternOperator OpNode> { 6922 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6923 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6924 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6925} 6926 6927multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 6928 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6929 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6930 asm, []>; 6931 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6932 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6933 asm, []>; 6934} 6935 6936multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6937 SDPatternOperator OpNode = null_frag, 6938 Predicate pred = HasNEON> { 6939 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in { 6940 let Predicates = [pred] in { 6941 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6942 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6943 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6944 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6945 } 6946 let Predicates = [pred, HasFullFP16] in { 6947 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6948 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6949 } 6950 } 6951 6952 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6953 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6954} 6955 6956multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6957 SDPatternOperator OpNode = null_frag> { 6958 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in { 6959 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6960 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6961 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6962 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6963 let Predicates = [HasNEON, HasFullFP16] in { 6964 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6965 []>; 6966 } // Predicates = [HasNEON, HasFullFP16] 6967 } 6968 6969 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6970 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6971} 6972 6973class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6974 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6975 : I<oops, iops, asm, 6976 "\t$Rd, $Rn, $Rm", cstr, pat>, 6977 Sched<[WriteVd]> { 6978 bits<5> Rd; 6979 bits<5> Rn; 6980 bits<5> Rm; 6981 let Inst{31-30} = 0b01; 6982 let Inst{29} = U; 6983 let Inst{28-24} = 0b11110; 6984 let Inst{23-22} = size; 6985 let Inst{21} = 1; 6986 let Inst{20-16} = Rm; 6987 let Inst{15-11} = opcode; 6988 let Inst{10} = 0; 6989 let Inst{9-5} = Rn; 6990 let Inst{4-0} = Rd; 6991} 6992 6993let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6994multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6995 SDPatternOperator OpNode = null_frag> { 6996 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6997 (outs FPR32:$Rd), 6998 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6999 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7000 (outs FPR64:$Rd), 7001 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7002 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7003} 7004 7005let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7006multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7007 SDPatternOperator OpNode = null_frag> { 7008 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7009 (outs FPR32:$dst), 7010 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7011 asm, "$Rd = $dst", []>; 7012 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7013 (outs FPR64:$dst), 7014 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7015 asm, "$Rd = $dst", 7016 [(set (i64 FPR64:$dst), 7017 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7018} 7019 7020//---------------------------------------------------------------------------- 7021// AdvSIMD two register scalar instructions 7022//---------------------------------------------------------------------------- 7023 7024let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7025class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7026 RegisterClass regtype, RegisterClass regtype2, 7027 string asm, list<dag> pat> 7028 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7029 "\t$Rd, $Rn", "", pat>, 7030 Sched<[WriteVd]> { 7031 bits<5> Rd; 7032 bits<5> Rn; 7033 let Inst{31-30} = 0b01; 7034 let Inst{29} = U; 7035 let Inst{28-24} = 0b11110; 7036 let Inst{23-22} = size; 7037 let Inst{21} = 0b1; 7038 let Inst{20-19} = size2; 7039 let Inst{18-17} = 0b00; 7040 let Inst{16-12} = opcode; 7041 let Inst{11-10} = 0b10; 7042 let Inst{9-5} = Rn; 7043 let Inst{4-0} = Rd; 7044} 7045 7046let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7047class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7048 RegisterClass regtype, RegisterClass regtype2, 7049 string asm, list<dag> pat> 7050 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7051 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7052 Sched<[WriteVd]> { 7053 bits<5> Rd; 7054 bits<5> Rn; 7055 let Inst{31-30} = 0b01; 7056 let Inst{29} = U; 7057 let Inst{28-24} = 0b11110; 7058 let Inst{23-22} = size; 7059 let Inst{21-17} = 0b10000; 7060 let Inst{16-12} = opcode; 7061 let Inst{11-10} = 0b10; 7062 let Inst{9-5} = Rn; 7063 let Inst{4-0} = Rd; 7064} 7065 7066 7067let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7068class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7069 RegisterClass regtype, string asm, string zero> 7070 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7071 "\t$Rd, $Rn, #" # zero, "", []>, 7072 Sched<[WriteVd]> { 7073 bits<5> Rd; 7074 bits<5> Rn; 7075 let Inst{31-30} = 0b01; 7076 let Inst{29} = U; 7077 let Inst{28-24} = 0b11110; 7078 let Inst{23-22} = size; 7079 let Inst{21} = 0b1; 7080 let Inst{20-19} = size2; 7081 let Inst{18-17} = 0b00; 7082 let Inst{16-12} = opcode; 7083 let Inst{11-10} = 0b10; 7084 let Inst{9-5} = Rn; 7085 let Inst{4-0} = Rd; 7086} 7087 7088let mayRaiseFPException = 1 in 7089class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7090 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7091 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7092 Sched<[WriteVd]> { 7093 bits<5> Rd; 7094 bits<5> Rn; 7095 let Inst{31-17} = 0b011111100110000; 7096 let Inst{16-12} = opcode; 7097 let Inst{11-10} = 0b10; 7098 let Inst{9-5} = Rn; 7099 let Inst{4-0} = Rd; 7100} 7101 7102multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7103 SDPatternOperator OpNode> { 7104 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7105 7106 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7107 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7108} 7109 7110multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7111 SDPatternOperator OpNode> { 7112 let mayRaiseFPException = 1 in { 7113 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7114 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7115 let Predicates = [HasNEON, HasFullFP16] in { 7116 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7117 } 7118 } 7119 7120 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7121 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7122 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7123 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7124 let Predicates = [HasNEON, HasFullFP16] in { 7125 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7126 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7127 } 7128 7129 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7130 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7131} 7132 7133multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7134 SDPatternOperator OpNode = null_frag> { 7135 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7136 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7137 7138 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7139 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7140} 7141 7142let mayRaiseFPException = 1 in 7143multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7144 Predicate pred = HasNEON> { 7145 let Predicates = [pred] in { 7146 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7147 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7148 } 7149 let Predicates = [pred, HasFullFP16] in { 7150 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7151 } 7152} 7153 7154let mayRaiseFPException = 1 in 7155multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7156 SDPatternOperator OpNode> { 7157 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7158 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7159 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7160 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7161 let Predicates = [HasNEON, HasFullFP16] in { 7162 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7163 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7164 } 7165} 7166 7167multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7168 SDPatternOperator OpNode = null_frag> { 7169 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7170 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7171 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7172 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7173 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7174 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7175 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7176 } 7177 7178 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7179 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7180} 7181 7182multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7183 Intrinsic OpNode> { 7184 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7185 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7186 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7187 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7188 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7189 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7190 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7191 } 7192 7193 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7194 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7195} 7196 7197 7198 7199let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7200multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7201 SDPatternOperator OpNode = null_frag> { 7202 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7203 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7204 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7205 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7206} 7207 7208//---------------------------------------------------------------------------- 7209// AdvSIMD scalar pairwise instructions 7210//---------------------------------------------------------------------------- 7211 7212let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7213class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7214 RegisterOperand regtype, RegisterOperand vectype, 7215 string asm, string kind> 7216 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7217 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7218 Sched<[WriteVd]> { 7219 bits<5> Rd; 7220 bits<5> Rn; 7221 let Inst{31-30} = 0b01; 7222 let Inst{29} = U; 7223 let Inst{28-24} = 0b11110; 7224 let Inst{23-22} = size; 7225 let Inst{21-17} = 0b11000; 7226 let Inst{16-12} = opcode; 7227 let Inst{11-10} = 0b10; 7228 let Inst{9-5} = Rn; 7229 let Inst{4-0} = Rd; 7230} 7231 7232multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7233 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7234 asm, ".2d">; 7235} 7236 7237let mayRaiseFPException = 1 in 7238multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7239 let Predicates = [HasNEON, HasFullFP16] in { 7240 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7241 asm, ".2h">; 7242 } 7243 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7244 asm, ".2s">; 7245 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7246 asm, ".2d">; 7247} 7248 7249//---------------------------------------------------------------------------- 7250// AdvSIMD across lanes instructions 7251//---------------------------------------------------------------------------- 7252 7253let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7254class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7255 RegisterClass regtype, RegisterOperand vectype, 7256 string asm, string kind, list<dag> pattern> 7257 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7258 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7259 Sched<[!if(Q, WriteVq, WriteVd)]> { 7260 bits<5> Rd; 7261 bits<5> Rn; 7262 let Inst{31} = 0; 7263 let Inst{30} = Q; 7264 let Inst{29} = U; 7265 let Inst{28-24} = 0b01110; 7266 let Inst{23-22} = size; 7267 let Inst{21-17} = 0b11000; 7268 let Inst{16-12} = opcode; 7269 let Inst{11-10} = 0b10; 7270 let Inst{9-5} = Rn; 7271 let Inst{4-0} = Rd; 7272} 7273 7274multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7275 string asm> { 7276 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7277 asm, ".8b", []>; 7278 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7279 asm, ".16b", []>; 7280 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7281 asm, ".4h", []>; 7282 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7283 asm, ".8h", []>; 7284 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7285 asm, ".4s", []>; 7286} 7287 7288multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7289 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7290 asm, ".8b", []>; 7291 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7292 asm, ".16b", []>; 7293 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7294 asm, ".4h", []>; 7295 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7296 asm, ".8h", []>; 7297 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7298 asm, ".4s", []>; 7299} 7300 7301let mayRaiseFPException = 1 in 7302multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7303 Intrinsic intOp> { 7304 let Predicates = [HasNEON, HasFullFP16] in { 7305 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7306 asm, ".4h", 7307 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7308 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7309 asm, ".8h", 7310 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7311 } // Predicates = [HasNEON, HasFullFP16] 7312 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7313 asm, ".4s", 7314 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7315} 7316 7317//---------------------------------------------------------------------------- 7318// AdvSIMD INS/DUP instructions 7319//---------------------------------------------------------------------------- 7320 7321// FIXME: There has got to be a better way to factor these. ugh. 7322 7323class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7324 string operands, string constraints, list<dag> pattern> 7325 : I<outs, ins, asm, operands, constraints, pattern>, 7326 Sched<[!if(Q, WriteVq, WriteVd)]> { 7327 bits<5> Rd; 7328 bits<5> Rn; 7329 let Inst{31} = 0; 7330 let Inst{30} = Q; 7331 let Inst{29} = op; 7332 let Inst{28-21} = 0b01110000; 7333 let Inst{15} = 0; 7334 let Inst{10} = 1; 7335 let Inst{9-5} = Rn; 7336 let Inst{4-0} = Rd; 7337} 7338 7339class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7340 RegisterOperand vecreg, RegisterClass regtype> 7341 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7342 "{\t$Rd" # size # ", $Rn" # 7343 "|" # size # "\t$Rd, $Rn}", "", 7344 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7345 let Inst{20-16} = imm5; 7346 let Inst{14-11} = 0b0001; 7347} 7348 7349class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7350 ValueType vectype, ValueType insreg, 7351 RegisterOperand vecreg, Operand idxtype, 7352 SDNode OpNode> 7353 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7354 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7355 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7356 [(set (vectype vecreg:$Rd), 7357 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7358 let Inst{14-11} = 0b0000; 7359} 7360 7361class SIMDDup64FromElement 7362 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7363 VectorIndexD, AArch64duplane64> { 7364 bits<1> idx; 7365 let Inst{20} = idx; 7366 let Inst{19-16} = 0b1000; 7367} 7368 7369class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7370 RegisterOperand vecreg> 7371 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7372 VectorIndexS, AArch64duplane32> { 7373 bits<2> idx; 7374 let Inst{20-19} = idx; 7375 let Inst{18-16} = 0b100; 7376} 7377 7378class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7379 RegisterOperand vecreg> 7380 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7381 VectorIndexH, AArch64duplane16> { 7382 bits<3> idx; 7383 let Inst{20-18} = idx; 7384 let Inst{17-16} = 0b10; 7385} 7386 7387class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7388 RegisterOperand vecreg> 7389 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7390 VectorIndexB, AArch64duplane8> { 7391 bits<4> idx; 7392 let Inst{20-17} = idx; 7393 let Inst{16} = 1; 7394} 7395 7396class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7397 Operand idxtype, string asm, list<dag> pattern> 7398 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7399 "{\t$Rd, $Rn" # size # "$idx" # 7400 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7401 let Inst{14-11} = imm4; 7402} 7403 7404class SIMDSMov<bit Q, string size, RegisterClass regtype, 7405 Operand idxtype> 7406 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7407class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7408 Operand idxtype> 7409 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7410 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7411 7412class SIMDMovAlias<string asm, string size, Instruction inst, 7413 RegisterClass regtype, Operand idxtype> 7414 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7415 "|" # size # "\t$dst, $src$idx}", 7416 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7417 7418multiclass SMov { 7419 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7420 // streaming mode. 7421 let Predicates = [HasNEONorSME] in { 7422 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7423 let Inst{20-16} = 0b00001; 7424 } 7425 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7426 let Inst{20-16} = 0b00001; 7427 } 7428 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7429 let Inst{20-16} = 0b00010; 7430 } 7431 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7432 let Inst{20-16} = 0b00010; 7433 } 7434 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7435 let Inst{20-16} = 0b00100; 7436 } 7437 } 7438 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7439 bits<4> idx; 7440 let Inst{20-17} = idx; 7441 let Inst{16} = 1; 7442 } 7443 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7444 bits<4> idx; 7445 let Inst{20-17} = idx; 7446 let Inst{16} = 1; 7447 } 7448 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7449 bits<3> idx; 7450 let Inst{20-18} = idx; 7451 let Inst{17-16} = 0b10; 7452 } 7453 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7454 bits<3> idx; 7455 let Inst{20-18} = idx; 7456 let Inst{17-16} = 0b10; 7457 } 7458 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7459 bits<2> idx; 7460 let Inst{20-19} = idx; 7461 let Inst{18-16} = 0b100; 7462 } 7463} 7464 7465multiclass UMov { 7466 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7467 // streaming mode. 7468 let Predicates = [HasNEONorSME] in { 7469 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7470 let Inst{20-16} = 0b00001; 7471 } 7472 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7473 let Inst{20-16} = 0b00010; 7474 } 7475 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7476 let Inst{20-16} = 0b00100; 7477 } 7478 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7479 let Inst{20-16} = 0b01000; 7480 } 7481 def : SIMDMovAlias<"mov", ".s", 7482 !cast<Instruction>(NAME # vi32_idx0), 7483 GPR32, VectorIndex0>; 7484 def : SIMDMovAlias<"mov", ".d", 7485 !cast<Instruction>(NAME # vi64_idx0), 7486 GPR64, VectorIndex0>; 7487 } 7488 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7489 bits<4> idx; 7490 let Inst{20-17} = idx; 7491 let Inst{16} = 1; 7492 } 7493 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7494 bits<3> idx; 7495 let Inst{20-18} = idx; 7496 let Inst{17-16} = 0b10; 7497 } 7498 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7499 bits<2> idx; 7500 let Inst{20-19} = idx; 7501 let Inst{18-16} = 0b100; 7502 } 7503 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7504 bits<1> idx; 7505 let Inst{20} = idx; 7506 let Inst{19-16} = 0b1000; 7507 } 7508 def : SIMDMovAlias<"mov", ".s", 7509 !cast<Instruction>(NAME#"vi32"), 7510 GPR32, VectorIndexS>; 7511 def : SIMDMovAlias<"mov", ".d", 7512 !cast<Instruction>(NAME#"vi64"), 7513 GPR64, VectorIndexD>; 7514} 7515 7516class SIMDInsFromMain<string size, ValueType vectype, 7517 RegisterClass regtype, Operand idxtype> 7518 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7519 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7520 "{\t$Rd" # size # "$idx, $Rn" # 7521 "|" # size # "\t$Rd$idx, $Rn}", 7522 "$Rd = $dst", 7523 [(set V128:$dst, 7524 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7525 let Inst{14-11} = 0b0011; 7526} 7527 7528class SIMDInsFromElement<string size, ValueType vectype, 7529 ValueType elttype, Operand idxtype> 7530 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7531 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7532 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7533 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7534 "$Rd = $dst", 7535 [(set V128:$dst, 7536 (vector_insert 7537 (vectype V128:$Rd), 7538 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7539 idxtype:$idx))]>; 7540 7541class SIMDInsMainMovAlias<string size, Instruction inst, 7542 RegisterClass regtype, Operand idxtype> 7543 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7544 "|" # size #"\t$dst$idx, $src}", 7545 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7546class SIMDInsElementMovAlias<string size, Instruction inst, 7547 Operand idxtype> 7548 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7549 # "|" # size #"\t$dst$idx, $src$idx2}", 7550 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7551 7552 7553multiclass SIMDIns { 7554 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7555 bits<4> idx; 7556 let Inst{20-17} = idx; 7557 let Inst{16} = 1; 7558 } 7559 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7560 bits<3> idx; 7561 let Inst{20-18} = idx; 7562 let Inst{17-16} = 0b10; 7563 } 7564 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7565 bits<2> idx; 7566 let Inst{20-19} = idx; 7567 let Inst{18-16} = 0b100; 7568 } 7569 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7570 bits<1> idx; 7571 let Inst{20} = idx; 7572 let Inst{19-16} = 0b1000; 7573 } 7574 7575 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7576 bits<4> idx; 7577 bits<4> idx2; 7578 let Inst{20-17} = idx; 7579 let Inst{16} = 1; 7580 let Inst{14-11} = idx2; 7581 } 7582 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7583 bits<3> idx; 7584 bits<3> idx2; 7585 let Inst{20-18} = idx; 7586 let Inst{17-16} = 0b10; 7587 let Inst{14-12} = idx2; 7588 let Inst{11} = {?}; 7589 } 7590 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7591 bits<2> idx; 7592 bits<2> idx2; 7593 let Inst{20-19} = idx; 7594 let Inst{18-16} = 0b100; 7595 let Inst{14-13} = idx2; 7596 let Inst{12-11} = {?,?}; 7597 } 7598 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7599 bits<1> idx; 7600 bits<1> idx2; 7601 let Inst{20} = idx; 7602 let Inst{19-16} = 0b1000; 7603 let Inst{14} = idx2; 7604 let Inst{13-11} = {?,?,?}; 7605 } 7606 7607 // For all forms of the INS instruction, the "mov" mnemonic is the 7608 // preferred alias. Why they didn't just call the instruction "mov" in 7609 // the first place is a very good question indeed... 7610 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7611 GPR32, VectorIndexB>; 7612 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7613 GPR32, VectorIndexH>; 7614 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7615 GPR32, VectorIndexS>; 7616 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7617 GPR64, VectorIndexD>; 7618 7619 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7620 VectorIndexB>; 7621 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7622 VectorIndexH>; 7623 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7624 VectorIndexS>; 7625 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7626 VectorIndexD>; 7627} 7628 7629//---------------------------------------------------------------------------- 7630// AdvSIMD TBL/TBX 7631//---------------------------------------------------------------------------- 7632 7633let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7634class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7635 RegisterOperand listtype, string asm, string kind> 7636 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7637 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7638 Sched<[!if(Q, WriteVq, WriteVd)]> { 7639 bits<5> Vd; 7640 bits<5> Vn; 7641 bits<5> Vm; 7642 let Inst{31} = 0; 7643 let Inst{30} = Q; 7644 let Inst{29-21} = 0b001110000; 7645 let Inst{20-16} = Vm; 7646 let Inst{15} = 0; 7647 let Inst{14-13} = len; 7648 let Inst{12} = op; 7649 let Inst{11-10} = 0b00; 7650 let Inst{9-5} = Vn; 7651 let Inst{4-0} = Vd; 7652} 7653 7654let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7655class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7656 RegisterOperand listtype, string asm, string kind> 7657 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7658 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7659 Sched<[!if(Q, WriteVq, WriteVd)]> { 7660 bits<5> Vd; 7661 bits<5> Vn; 7662 bits<5> Vm; 7663 let Inst{31} = 0; 7664 let Inst{30} = Q; 7665 let Inst{29-21} = 0b001110000; 7666 let Inst{20-16} = Vm; 7667 let Inst{15} = 0; 7668 let Inst{14-13} = len; 7669 let Inst{12} = op; 7670 let Inst{11-10} = 0b00; 7671 let Inst{9-5} = Vn; 7672 let Inst{4-0} = Vd; 7673} 7674 7675class SIMDTableLookupAlias<string asm, Instruction inst, 7676 RegisterOperand vectype, RegisterOperand listtype> 7677 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7678 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7679 7680multiclass SIMDTableLookup<bit op, string asm> { 7681 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7682 asm, ".8b">; 7683 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7684 asm, ".8b">; 7685 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7686 asm, ".8b">; 7687 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7688 asm, ".8b">; 7689 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7690 asm, ".16b">; 7691 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7692 asm, ".16b">; 7693 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7694 asm, ".16b">; 7695 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7696 asm, ".16b">; 7697 7698 def : SIMDTableLookupAlias<asm # ".8b", 7699 !cast<Instruction>(NAME#"v8i8One"), 7700 V64, VecListOne128>; 7701 def : SIMDTableLookupAlias<asm # ".8b", 7702 !cast<Instruction>(NAME#"v8i8Two"), 7703 V64, VecListTwo128>; 7704 def : SIMDTableLookupAlias<asm # ".8b", 7705 !cast<Instruction>(NAME#"v8i8Three"), 7706 V64, VecListThree128>; 7707 def : SIMDTableLookupAlias<asm # ".8b", 7708 !cast<Instruction>(NAME#"v8i8Four"), 7709 V64, VecListFour128>; 7710 def : SIMDTableLookupAlias<asm # ".16b", 7711 !cast<Instruction>(NAME#"v16i8One"), 7712 V128, VecListOne128>; 7713 def : SIMDTableLookupAlias<asm # ".16b", 7714 !cast<Instruction>(NAME#"v16i8Two"), 7715 V128, VecListTwo128>; 7716 def : SIMDTableLookupAlias<asm # ".16b", 7717 !cast<Instruction>(NAME#"v16i8Three"), 7718 V128, VecListThree128>; 7719 def : SIMDTableLookupAlias<asm # ".16b", 7720 !cast<Instruction>(NAME#"v16i8Four"), 7721 V128, VecListFour128>; 7722} 7723 7724multiclass SIMDTableLookupTied<bit op, string asm> { 7725 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7726 asm, ".8b">; 7727 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7728 asm, ".8b">; 7729 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7730 asm, ".8b">; 7731 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7732 asm, ".8b">; 7733 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7734 asm, ".16b">; 7735 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7736 asm, ".16b">; 7737 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7738 asm, ".16b">; 7739 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7740 asm, ".16b">; 7741 7742 def : SIMDTableLookupAlias<asm # ".8b", 7743 !cast<Instruction>(NAME#"v8i8One"), 7744 V64, VecListOne128>; 7745 def : SIMDTableLookupAlias<asm # ".8b", 7746 !cast<Instruction>(NAME#"v8i8Two"), 7747 V64, VecListTwo128>; 7748 def : SIMDTableLookupAlias<asm # ".8b", 7749 !cast<Instruction>(NAME#"v8i8Three"), 7750 V64, VecListThree128>; 7751 def : SIMDTableLookupAlias<asm # ".8b", 7752 !cast<Instruction>(NAME#"v8i8Four"), 7753 V64, VecListFour128>; 7754 def : SIMDTableLookupAlias<asm # ".16b", 7755 !cast<Instruction>(NAME#"v16i8One"), 7756 V128, VecListOne128>; 7757 def : SIMDTableLookupAlias<asm # ".16b", 7758 !cast<Instruction>(NAME#"v16i8Two"), 7759 V128, VecListTwo128>; 7760 def : SIMDTableLookupAlias<asm # ".16b", 7761 !cast<Instruction>(NAME#"v16i8Three"), 7762 V128, VecListThree128>; 7763 def : SIMDTableLookupAlias<asm # ".16b", 7764 !cast<Instruction>(NAME#"v16i8Four"), 7765 V128, VecListFour128>; 7766} 7767 7768 7769//---------------------------------------------------------------------------- 7770// AdvSIMD scalar DUP 7771//---------------------------------------------------------------------------- 7772let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7773class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 7774 string asm, string kind, Operand idxtype> 7775 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 7776 "{\t$dst, $src" # kind # "$idx" # 7777 "|\t$dst, $src$idx}", "", []>, 7778 Sched<[WriteVd]> { 7779 bits<5> dst; 7780 bits<5> src; 7781 let Inst{31-21} = 0b01011110000; 7782 let Inst{15-10} = 0b000001; 7783 let Inst{9-5} = src; 7784 let Inst{4-0} = dst; 7785} 7786 7787class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 7788 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7789 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7790 # "|\t$dst, $src$index}", 7791 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7792 7793 7794multiclass SIMDScalarDUP<string asm> { 7795 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 7796 bits<4> idx; 7797 let Inst{20-17} = idx; 7798 let Inst{16} = 1; 7799 } 7800 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 7801 bits<3> idx; 7802 let Inst{20-18} = idx; 7803 let Inst{17-16} = 0b10; 7804 } 7805 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 7806 bits<2> idx; 7807 let Inst{20-19} = idx; 7808 let Inst{18-16} = 0b100; 7809 } 7810 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 7811 bits<1> idx; 7812 let Inst{20} = idx; 7813 let Inst{19-16} = 0b1000; 7814 } 7815 7816 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7817 VectorIndexD:$idx)))), 7818 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7819 7820 // 'DUP' mnemonic aliases. 7821 def : SIMDScalarDUPAlias<"dup", ".b", 7822 !cast<Instruction>(NAME#"i8"), 7823 FPR8, V128, VectorIndexB>; 7824 def : SIMDScalarDUPAlias<"dup", ".h", 7825 !cast<Instruction>(NAME#"i16"), 7826 FPR16, V128, VectorIndexH>; 7827 def : SIMDScalarDUPAlias<"dup", ".s", 7828 !cast<Instruction>(NAME#"i32"), 7829 FPR32, V128, VectorIndexS>; 7830 def : SIMDScalarDUPAlias<"dup", ".d", 7831 !cast<Instruction>(NAME#"i64"), 7832 FPR64, V128, VectorIndexD>; 7833} 7834 7835//---------------------------------------------------------------------------- 7836// AdvSIMD modified immediate instructions 7837//---------------------------------------------------------------------------- 7838 7839class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7840 string asm, string op_string, 7841 string cstr, list<dag> pattern> 7842 : I<oops, iops, asm, op_string, cstr, pattern>, 7843 Sched<[!if(Q, WriteVq, WriteVd)]> { 7844 bits<5> Rd; 7845 bits<8> imm8; 7846 let Inst{31} = 0; 7847 let Inst{30} = Q; 7848 let Inst{29} = op; 7849 let Inst{28-19} = 0b0111100000; 7850 let Inst{18-16} = imm8{7-5}; 7851 let Inst{11} = op2; 7852 let Inst{10} = 1; 7853 let Inst{9-5} = imm8{4-0}; 7854 let Inst{4-0} = Rd; 7855} 7856 7857class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7858 Operand immtype, dag opt_shift_iop, 7859 string opt_shift, string asm, string kind, 7860 list<dag> pattern> 7861 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7862 !con((ins immtype:$imm8), opt_shift_iop), asm, 7863 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7864 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7865 "", pattern> { 7866 let DecoderMethod = "DecodeModImmInstruction"; 7867} 7868 7869class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7870 Operand immtype, dag opt_shift_iop, 7871 string opt_shift, string asm, string kind, 7872 list<dag> pattern> 7873 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7874 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7875 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7876 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7877 "$Rd = $dst", pattern> { 7878 let DecoderMethod = "DecodeModImmTiedInstruction"; 7879} 7880 7881class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7882 RegisterOperand vectype, string asm, 7883 string kind, list<dag> pattern> 7884 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7885 (ins logical_vec_shift:$shift), 7886 "$shift", asm, kind, pattern> { 7887 bits<2> shift; 7888 let Inst{15} = b15_b12{1}; 7889 let Inst{14-13} = shift; 7890 let Inst{12} = b15_b12{0}; 7891} 7892 7893class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7894 RegisterOperand vectype, string asm, 7895 string kind, list<dag> pattern> 7896 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7897 (ins logical_vec_shift:$shift), 7898 "$shift", asm, kind, pattern> { 7899 bits<2> shift; 7900 let Inst{15} = b15_b12{1}; 7901 let Inst{14-13} = shift; 7902 let Inst{12} = b15_b12{0}; 7903} 7904 7905 7906class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7907 RegisterOperand vectype, string asm, 7908 string kind, list<dag> pattern> 7909 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7910 (ins logical_vec_hw_shift:$shift), 7911 "$shift", asm, kind, pattern> { 7912 bits<2> shift; 7913 let Inst{15} = b15_b12{1}; 7914 let Inst{14} = 0; 7915 let Inst{13} = shift{0}; 7916 let Inst{12} = b15_b12{0}; 7917} 7918 7919class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7920 RegisterOperand vectype, string asm, 7921 string kind, list<dag> pattern> 7922 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7923 (ins logical_vec_hw_shift:$shift), 7924 "$shift", asm, kind, pattern> { 7925 bits<2> shift; 7926 let Inst{15} = b15_b12{1}; 7927 let Inst{14} = 0; 7928 let Inst{13} = shift{0}; 7929 let Inst{12} = b15_b12{0}; 7930} 7931 7932multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7933 string asm> { 7934 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7935 asm, ".4h", []>; 7936 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7937 asm, ".8h", []>; 7938 7939 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7940 asm, ".2s", []>; 7941 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7942 asm, ".4s", []>; 7943} 7944 7945multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7946 bits<2> w_cmode, string asm, 7947 SDNode OpNode> { 7948 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7949 asm, ".4h", 7950 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7951 imm0_255:$imm8, 7952 (i32 imm:$shift)))]>; 7953 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7954 asm, ".8h", 7955 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7956 imm0_255:$imm8, 7957 (i32 imm:$shift)))]>; 7958 7959 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7960 asm, ".2s", 7961 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7962 imm0_255:$imm8, 7963 (i32 imm:$shift)))]>; 7964 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7965 asm, ".4s", 7966 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7967 imm0_255:$imm8, 7968 (i32 imm:$shift)))]>; 7969} 7970 7971class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7972 RegisterOperand vectype, string asm, 7973 string kind, list<dag> pattern> 7974 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7975 (ins move_vec_shift:$shift), 7976 "$shift", asm, kind, pattern> { 7977 bits<1> shift; 7978 let Inst{15-13} = cmode{3-1}; 7979 let Inst{12} = shift; 7980} 7981 7982class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7983 RegisterOperand vectype, 7984 Operand imm_type, string asm, 7985 string kind, list<dag> pattern> 7986 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7987 asm, kind, pattern> { 7988 let Inst{15-12} = cmode; 7989} 7990 7991class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7992 list<dag> pattern> 7993 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7994 "\t$Rd, $imm8", "", pattern> { 7995 let Inst{15-12} = cmode; 7996 let DecoderMethod = "DecodeModImmInstruction"; 7997} 7998 7999//---------------------------------------------------------------------------- 8000// AdvSIMD indexed element 8001//---------------------------------------------------------------------------- 8002 8003let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8004class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8005 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8006 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8007 string apple_kind, string dst_kind, string lhs_kind, 8008 string rhs_kind, list<dag> pattern> 8009 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8010 asm, 8011 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8012 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8013 Sched<[WriteVd]> { 8014 bits<5> Rd; 8015 bits<5> Rn; 8016 bits<5> Rm; 8017 8018 let Inst{31} = 0; 8019 let Inst{30} = Q; 8020 let Inst{29} = U; 8021 let Inst{28} = Scalar; 8022 let Inst{27-24} = 0b1111; 8023 let Inst{23-22} = size; 8024 // Bit 21 must be set by the derived class. 8025 let Inst{20-16} = Rm; 8026 let Inst{15-12} = opc; 8027 // Bit 11 must be set by the derived class. 8028 let Inst{10} = 0; 8029 let Inst{9-5} = Rn; 8030 let Inst{4-0} = Rd; 8031} 8032 8033let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8034class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8035 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8036 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8037 string apple_kind, string dst_kind, string lhs_kind, 8038 string rhs_kind, list<dag> pattern> 8039 : I<(outs dst_reg:$dst), 8040 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8041 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8042 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8043 Sched<[WriteVd]> { 8044 bits<5> Rd; 8045 bits<5> Rn; 8046 bits<5> Rm; 8047 8048 let Inst{31} = 0; 8049 let Inst{30} = Q; 8050 let Inst{29} = U; 8051 let Inst{28} = Scalar; 8052 let Inst{27-24} = 0b1111; 8053 let Inst{23-22} = size; 8054 // Bit 21 must be set by the derived class. 8055 let Inst{20-16} = Rm; 8056 let Inst{15-12} = opc; 8057 // Bit 11 must be set by the derived class. 8058 let Inst{10} = 0; 8059 let Inst{9-5} = Rn; 8060 let Inst{4-0} = Rd; 8061} 8062 8063 8064//---------------------------------------------------------------------------- 8065// Armv8.6 BFloat16 Extension 8066//---------------------------------------------------------------------------- 8067let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8068 8069class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8070 string kind2, RegisterOperand RegType, 8071 ValueType AccumType, ValueType InputType> 8072 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8073 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8074 (InputType RegType:$Rn), 8075 (InputType RegType:$Rm)))]> { 8076 let AsmString = !strconcat(asm, 8077 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8078 ", $Rm" # kind2 # "}"); 8079} 8080 8081multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8082 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8083 v2f32, v4bf16>; 8084 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8085 v4f32, v8bf16>; 8086} 8087 8088class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8089 string dst_kind, string lhs_kind, 8090 string rhs_kind, 8091 RegisterOperand RegType, 8092 ValueType AccumType, 8093 ValueType InputType> 8094 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8095 RegType, RegType, V128, VectorIndexS, 8096 asm, "", dst_kind, lhs_kind, rhs_kind, 8097 [(set (AccumType RegType:$dst), 8098 (AccumType (int_aarch64_neon_bfdot 8099 (AccumType RegType:$Rd), 8100 (InputType RegType:$Rn), 8101 (InputType (bitconvert (AccumType 8102 (AArch64duplane32 (v4f32 V128:$Rm), 8103 VectorIndexS:$idx)))))))]> { 8104 8105 bits<2> idx; 8106 let Inst{21} = idx{0}; // L 8107 let Inst{11} = idx{1}; // H 8108} 8109 8110multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8111 8112 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8113 ".2h", V64, v2f32, v4bf16>; 8114 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8115 ".2h", V128, v4f32, v8bf16>; 8116} 8117 8118let mayRaiseFPException = 1 in 8119class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8120 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8121 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8122 (v8bf16 V128:$Rn), 8123 (v8bf16 V128:$Rm)))]> { 8124 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8125} 8126 8127let mayRaiseFPException = 1 in 8128class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8129 : I<(outs V128:$dst), 8130 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8131 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8132 [(set (v4f32 V128:$dst), 8133 (v4f32 (OpNode (v4f32 V128:$Rd), 8134 (v8bf16 V128:$Rn), 8135 (v8bf16 8136 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8137 VectorIndexH:$idx)))))]>, 8138 Sched<[WriteVq]> { 8139 bits<5> Rd; 8140 bits<5> Rn; 8141 bits<4> Rm; 8142 bits<3> idx; 8143 8144 let Inst{31} = 0; 8145 let Inst{30} = Q; 8146 let Inst{29-22} = 0b00111111; 8147 let Inst{21-20} = idx{1-0}; 8148 let Inst{19-16} = Rm; 8149 let Inst{15-12} = 0b1111; 8150 let Inst{11} = idx{2}; // H 8151 let Inst{10} = 0; 8152 let Inst{9-5} = Rn; 8153 let Inst{4-0} = Rd; 8154} 8155 8156class SIMDThreeSameVectorBF16MatrixMul<string asm> 8157 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8158 V128, asm, ".4s", 8159 [(set (v4f32 V128:$dst), 8160 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8161 (v8bf16 V128:$Rn), 8162 (v8bf16 V128:$Rm)))]> { 8163 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8164 ", $Rm", ".8h", "}"); 8165} 8166 8167let mayRaiseFPException = 1 in 8168class SIMD_BFCVTN 8169 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8170 "bfcvtn", ".4h", ".4s", 8171 [(set (v8bf16 V128:$Rd), 8172 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8173 8174let mayRaiseFPException = 1 in 8175class SIMD_BFCVTN2 8176 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8177 "bfcvtn2", ".8h", ".4s", 8178 [(set (v8bf16 V128:$dst), 8179 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8180 8181let mayRaiseFPException = 1 in 8182class BF16ToSinglePrecision<string asm> 8183 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8184 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8185 Sched<[WriteFCvt]> { 8186 bits<5> Rd; 8187 bits<5> Rn; 8188 let Inst{31-10} = 0b0001111001100011010000; 8189 let Inst{9-5} = Rn; 8190 let Inst{4-0} = Rd; 8191} 8192} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8193 8194//---------------------------------------------------------------------------- 8195// Armv8.6 Matrix Multiply Extension 8196//---------------------------------------------------------------------------- 8197 8198class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8199 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8200 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8201 (v16i8 V128:$Rn), 8202 (v16i8 V128:$Rm)))]> { 8203 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8204} 8205 8206//---------------------------------------------------------------------------- 8207// ARMv8.2-A Dot Product Instructions (Indexed) 8208class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8209 string dst_kind, string lhs_kind, string rhs_kind, 8210 RegisterOperand RegType, 8211 ValueType AccumType, ValueType InputType, 8212 SDPatternOperator OpNode> : 8213 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8214 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8215 [(set (AccumType RegType:$dst), 8216 (AccumType (OpNode (AccumType RegType:$Rd), 8217 (InputType RegType:$Rn), 8218 (InputType (bitconvert (AccumType 8219 (AArch64duplane32 (v4i32 V128:$Rm), 8220 VectorIndexS:$idx)))))))]> { 8221 bits<2> idx; 8222 let Inst{21} = idx{0}; // L 8223 let Inst{11} = idx{1}; // H 8224} 8225 8226multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8227 SDPatternOperator OpNode> { 8228 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8229 V64, v2i32, v8i8, OpNode>; 8230 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8231 V128, v4i32, v16i8, OpNode>; 8232} 8233 8234// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8235let mayRaiseFPException = 1 in 8236class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8237 string dst_kind, string lhs_kind, 8238 string rhs_kind, RegisterOperand RegType, 8239 ValueType AccumType, ValueType InputType, 8240 SDPatternOperator OpNode> : 8241 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8242 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8243 [(set (AccumType RegType:$dst), 8244 (AccumType (OpNode (AccumType RegType:$Rd), 8245 (InputType RegType:$Rn), 8246 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8247 VectorIndexH:$idx)))))]> { 8248 // idx = H:L:M 8249 bits<3> idx; 8250 let Inst{11} = idx{2}; // H 8251 let Inst{21} = idx{1}; // L 8252 let Inst{20} = idx{0}; // M 8253} 8254 8255multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8256 SDPatternOperator OpNode> { 8257 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8258 V64, v2f32, v4f16, OpNode>; 8259 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8260 V128, v4f32, v8f16, OpNode>; 8261} 8262 8263let mayRaiseFPException = 1 in 8264multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8265 SDPatternOperator OpNode> { 8266 let Predicates = [HasNEON, HasFullFP16] in { 8267 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8268 V64, V64, 8269 V128_lo, VectorIndexH, 8270 asm, ".4h", ".4h", ".4h", ".h", 8271 [(set (v4f16 V64:$Rd), 8272 (OpNode (v4f16 V64:$Rn), 8273 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8274 bits<3> idx; 8275 let Inst{11} = idx{2}; 8276 let Inst{21} = idx{1}; 8277 let Inst{20} = idx{0}; 8278 } 8279 8280 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8281 V128, V128, 8282 V128_lo, VectorIndexH, 8283 asm, ".8h", ".8h", ".8h", ".h", 8284 [(set (v8f16 V128:$Rd), 8285 (OpNode (v8f16 V128:$Rn), 8286 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8287 bits<3> idx; 8288 let Inst{11} = idx{2}; 8289 let Inst{21} = idx{1}; 8290 let Inst{20} = idx{0}; 8291 } 8292 } // Predicates = [HasNEON, HasFullFP16] 8293 8294 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8295 V64, V64, 8296 V128, VectorIndexS, 8297 asm, ".2s", ".2s", ".2s", ".s", 8298 [(set (v2f32 V64:$Rd), 8299 (OpNode (v2f32 V64:$Rn), 8300 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8301 bits<2> idx; 8302 let Inst{11} = idx{1}; 8303 let Inst{21} = idx{0}; 8304 } 8305 8306 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8307 V128, V128, 8308 V128, VectorIndexS, 8309 asm, ".4s", ".4s", ".4s", ".s", 8310 [(set (v4f32 V128:$Rd), 8311 (OpNode (v4f32 V128:$Rn), 8312 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8313 bits<2> idx; 8314 let Inst{11} = idx{1}; 8315 let Inst{21} = idx{0}; 8316 } 8317 8318 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8319 V128, V128, 8320 V128, VectorIndexD, 8321 asm, ".2d", ".2d", ".2d", ".d", 8322 [(set (v2f64 V128:$Rd), 8323 (OpNode (v2f64 V128:$Rn), 8324 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8325 bits<1> idx; 8326 let Inst{11} = idx{0}; 8327 let Inst{21} = 0; 8328 } 8329 8330 let Predicates = [HasNEON, HasFullFP16] in { 8331 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8332 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8333 asm, ".h", "", "", ".h", 8334 [(set (f16 FPR16Op:$Rd), 8335 (OpNode (f16 FPR16Op:$Rn), 8336 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8337 VectorIndexH:$idx))))]> { 8338 bits<3> idx; 8339 let Inst{11} = idx{2}; 8340 let Inst{21} = idx{1}; 8341 let Inst{20} = idx{0}; 8342 } 8343 } // Predicates = [HasNEON, HasFullFP16] 8344 8345 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8346 FPR32Op, FPR32Op, V128, VectorIndexS, 8347 asm, ".s", "", "", ".s", 8348 [(set (f32 FPR32Op:$Rd), 8349 (OpNode (f32 FPR32Op:$Rn), 8350 (f32 (vector_extract (v4f32 V128:$Rm), 8351 VectorIndexS:$idx))))]> { 8352 bits<2> idx; 8353 let Inst{11} = idx{1}; 8354 let Inst{21} = idx{0}; 8355 } 8356 8357 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8358 FPR64Op, FPR64Op, V128, VectorIndexD, 8359 asm, ".d", "", "", ".d", 8360 [(set (f64 FPR64Op:$Rd), 8361 (OpNode (f64 FPR64Op:$Rn), 8362 (f64 (vector_extract (v2f64 V128:$Rm), 8363 VectorIndexD:$idx))))]> { 8364 bits<1> idx; 8365 let Inst{11} = idx{0}; 8366 let Inst{21} = 0; 8367 } 8368} 8369 8370multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8371 let Predicates = [HasNEON, HasFullFP16] in { 8372 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8373 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8374 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8375 VectorIndexH:$idx))), 8376 (!cast<Instruction>(INST # "v8i16_indexed") 8377 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8378 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8379 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8380 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8381 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8382 8383 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8384 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8385 VectorIndexH:$idx))), 8386 (!cast<Instruction>(INST # "v4i16_indexed") 8387 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8388 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8389 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8390 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8391 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8392 8393 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8394 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8395 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8396 V128_lo:$Rm, VectorIndexH:$idx)>; 8397 } // Predicates = [HasNEON, HasFullFP16] 8398 8399 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8400 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8401 (AArch64duplane32 (v4f32 V128:$Rm), 8402 VectorIndexS:$idx))), 8403 (!cast<Instruction>(INST # v2i32_indexed) 8404 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8405 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8406 (AArch64dup (f32 FPR32Op:$Rm)))), 8407 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8408 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8409 8410 8411 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8412 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8413 (AArch64duplane32 (v4f32 V128:$Rm), 8414 VectorIndexS:$idx))), 8415 (!cast<Instruction>(INST # "v4i32_indexed") 8416 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8417 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8418 (AArch64dup (f32 FPR32Op:$Rm)))), 8419 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8420 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8421 8422 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8423 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8424 (AArch64duplane64 (v2f64 V128:$Rm), 8425 VectorIndexD:$idx))), 8426 (!cast<Instruction>(INST # "v2i64_indexed") 8427 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8428 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8429 (AArch64dup (f64 FPR64Op:$Rm)))), 8430 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8431 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8432 8433 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8434 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8435 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8436 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8437 V128:$Rm, VectorIndexS:$idx)>; 8438 8439 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8440 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8441 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8442 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8443 V128:$Rm, VectorIndexD:$idx)>; 8444} 8445 8446let mayRaiseFPException = 1 in 8447multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8448 let Predicates = [HasNEON, HasFullFP16] in { 8449 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8450 V128_lo, VectorIndexH, 8451 asm, ".4h", ".4h", ".4h", ".h", []> { 8452 bits<3> idx; 8453 let Inst{11} = idx{2}; 8454 let Inst{21} = idx{1}; 8455 let Inst{20} = idx{0}; 8456 } 8457 8458 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8459 V128, V128, 8460 V128_lo, VectorIndexH, 8461 asm, ".8h", ".8h", ".8h", ".h", []> { 8462 bits<3> idx; 8463 let Inst{11} = idx{2}; 8464 let Inst{21} = idx{1}; 8465 let Inst{20} = idx{0}; 8466 } 8467 } // Predicates = [HasNEON, HasFullFP16] 8468 8469 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8470 V128, VectorIndexS, 8471 asm, ".2s", ".2s", ".2s", ".s", []> { 8472 bits<2> idx; 8473 let Inst{11} = idx{1}; 8474 let Inst{21} = idx{0}; 8475 } 8476 8477 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8478 V128, V128, 8479 V128, VectorIndexS, 8480 asm, ".4s", ".4s", ".4s", ".s", []> { 8481 bits<2> idx; 8482 let Inst{11} = idx{1}; 8483 let Inst{21} = idx{0}; 8484 } 8485 8486 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8487 V128, V128, 8488 V128, VectorIndexD, 8489 asm, ".2d", ".2d", ".2d", ".d", []> { 8490 bits<1> idx; 8491 let Inst{11} = idx{0}; 8492 let Inst{21} = 0; 8493 } 8494 8495 let Predicates = [HasNEON, HasFullFP16] in { 8496 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8497 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8498 asm, ".h", "", "", ".h", []> { 8499 bits<3> idx; 8500 let Inst{11} = idx{2}; 8501 let Inst{21} = idx{1}; 8502 let Inst{20} = idx{0}; 8503 } 8504 } // Predicates = [HasNEON, HasFullFP16] 8505 8506 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8507 FPR32Op, FPR32Op, V128, VectorIndexS, 8508 asm, ".s", "", "", ".s", []> { 8509 bits<2> idx; 8510 let Inst{11} = idx{1}; 8511 let Inst{21} = idx{0}; 8512 } 8513 8514 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8515 FPR64Op, FPR64Op, V128, VectorIndexD, 8516 asm, ".d", "", "", ".d", []> { 8517 bits<1> idx; 8518 let Inst{11} = idx{0}; 8519 let Inst{21} = 0; 8520 } 8521} 8522 8523multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8524 SDPatternOperator OpNodeLaneQ> { 8525 8526 def : Pat<(v4i16 (OpNodeLane 8527 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8528 VectorIndexS32b:$idx)), 8529 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8530 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8531 (UImmS1XForm $idx))>; 8532 8533 def : Pat<(v4i16 (OpNodeLaneQ 8534 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8535 VectorIndexH32b:$idx)), 8536 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8537 (UImmS1XForm $idx))>; 8538 8539 def : Pat<(v8i16 (OpNodeLane 8540 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8541 VectorIndexS32b:$idx)), 8542 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8543 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8544 (UImmS1XForm $idx))>; 8545 8546 def : Pat<(v8i16 (OpNodeLaneQ 8547 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8548 VectorIndexH32b:$idx)), 8549 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8550 (UImmS1XForm $idx))>; 8551 8552 def : Pat<(v2i32 (OpNodeLane 8553 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8554 VectorIndexD32b:$idx)), 8555 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8556 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8557 (UImmS1XForm $idx))>; 8558 8559 def : Pat<(v2i32 (OpNodeLaneQ 8560 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8561 VectorIndexS32b:$idx)), 8562 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8563 (UImmS1XForm $idx))>; 8564 8565 def : Pat<(v4i32 (OpNodeLane 8566 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8567 VectorIndexD32b:$idx)), 8568 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8569 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8570 (UImmS1XForm $idx))>; 8571 8572 def : Pat<(v4i32 (OpNodeLaneQ 8573 (v4i32 V128:$Rn), 8574 (v4i32 V128:$Rm), 8575 VectorIndexS32b:$idx)), 8576 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8577 (UImmS1XForm $idx))>; 8578 8579} 8580 8581multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8582 SDPatternOperator OpNode> { 8583 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8584 V128_lo, VectorIndexH, 8585 asm, ".4h", ".4h", ".4h", ".h", 8586 [(set (v4i16 V64:$Rd), 8587 (OpNode (v4i16 V64:$Rn), 8588 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8589 bits<3> idx; 8590 let Inst{11} = idx{2}; 8591 let Inst{21} = idx{1}; 8592 let Inst{20} = idx{0}; 8593 } 8594 8595 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8596 V128, V128, 8597 V128_lo, VectorIndexH, 8598 asm, ".8h", ".8h", ".8h", ".h", 8599 [(set (v8i16 V128:$Rd), 8600 (OpNode (v8i16 V128:$Rn), 8601 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8602 bits<3> idx; 8603 let Inst{11} = idx{2}; 8604 let Inst{21} = idx{1}; 8605 let Inst{20} = idx{0}; 8606 } 8607 8608 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8609 V64, V64, 8610 V128, VectorIndexS, 8611 asm, ".2s", ".2s", ".2s", ".s", 8612 [(set (v2i32 V64:$Rd), 8613 (OpNode (v2i32 V64:$Rn), 8614 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8615 bits<2> idx; 8616 let Inst{11} = idx{1}; 8617 let Inst{21} = idx{0}; 8618 } 8619 8620 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8621 V128, V128, 8622 V128, VectorIndexS, 8623 asm, ".4s", ".4s", ".4s", ".s", 8624 [(set (v4i32 V128:$Rd), 8625 (OpNode (v4i32 V128:$Rn), 8626 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8627 bits<2> idx; 8628 let Inst{11} = idx{1}; 8629 let Inst{21} = idx{0}; 8630 } 8631 8632 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8633 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8634 asm, ".h", "", "", ".h", []> { 8635 bits<3> idx; 8636 let Inst{11} = idx{2}; 8637 let Inst{21} = idx{1}; 8638 let Inst{20} = idx{0}; 8639 } 8640 8641 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8642 FPR32Op, FPR32Op, V128, VectorIndexS, 8643 asm, ".s", "", "", ".s", 8644 [(set (i32 FPR32Op:$Rd), 8645 (OpNode FPR32Op:$Rn, 8646 (i32 (vector_extract (v4i32 V128:$Rm), 8647 VectorIndexS:$idx))))]> { 8648 bits<2> idx; 8649 let Inst{11} = idx{1}; 8650 let Inst{21} = idx{0}; 8651 } 8652} 8653 8654multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8655 SDPatternOperator OpNode> { 8656 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8657 V64, V64, 8658 V128_lo, VectorIndexH, 8659 asm, ".4h", ".4h", ".4h", ".h", 8660 [(set (v4i16 V64:$Rd), 8661 (OpNode (v4i16 V64:$Rn), 8662 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8663 bits<3> idx; 8664 let Inst{11} = idx{2}; 8665 let Inst{21} = idx{1}; 8666 let Inst{20} = idx{0}; 8667 } 8668 8669 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8670 V128, V128, 8671 V128_lo, VectorIndexH, 8672 asm, ".8h", ".8h", ".8h", ".h", 8673 [(set (v8i16 V128:$Rd), 8674 (OpNode (v8i16 V128:$Rn), 8675 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8676 bits<3> idx; 8677 let Inst{11} = idx{2}; 8678 let Inst{21} = idx{1}; 8679 let Inst{20} = idx{0}; 8680 } 8681 8682 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8683 V64, V64, 8684 V128, VectorIndexS, 8685 asm, ".2s", ".2s", ".2s", ".s", 8686 [(set (v2i32 V64:$Rd), 8687 (OpNode (v2i32 V64:$Rn), 8688 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8689 bits<2> idx; 8690 let Inst{11} = idx{1}; 8691 let Inst{21} = idx{0}; 8692 } 8693 8694 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8695 V128, V128, 8696 V128, VectorIndexS, 8697 asm, ".4s", ".4s", ".4s", ".s", 8698 [(set (v4i32 V128:$Rd), 8699 (OpNode (v4i32 V128:$Rn), 8700 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8701 bits<2> idx; 8702 let Inst{11} = idx{1}; 8703 let Inst{21} = idx{0}; 8704 } 8705} 8706 8707multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8708 SDPatternOperator OpNode> { 8709 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8710 V128_lo, VectorIndexH, 8711 asm, ".4h", ".4h", ".4h", ".h", 8712 [(set (v4i16 V64:$dst), 8713 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8714 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8715 bits<3> idx; 8716 let Inst{11} = idx{2}; 8717 let Inst{21} = idx{1}; 8718 let Inst{20} = idx{0}; 8719 } 8720 8721 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8722 V128, V128, 8723 V128_lo, VectorIndexH, 8724 asm, ".8h", ".8h", ".8h", ".h", 8725 [(set (v8i16 V128:$dst), 8726 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8727 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8728 bits<3> idx; 8729 let Inst{11} = idx{2}; 8730 let Inst{21} = idx{1}; 8731 let Inst{20} = idx{0}; 8732 } 8733 8734 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8735 V64, V64, 8736 V128, VectorIndexS, 8737 asm, ".2s", ".2s", ".2s", ".s", 8738 [(set (v2i32 V64:$dst), 8739 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8740 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8741 bits<2> idx; 8742 let Inst{11} = idx{1}; 8743 let Inst{21} = idx{0}; 8744 } 8745 8746 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8747 V128, V128, 8748 V128, VectorIndexS, 8749 asm, ".4s", ".4s", ".4s", ".s", 8750 [(set (v4i32 V128:$dst), 8751 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8752 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8753 bits<2> idx; 8754 let Inst{11} = idx{1}; 8755 let Inst{21} = idx{0}; 8756 } 8757} 8758 8759multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8760 SDPatternOperator OpNode> { 8761 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8762 V128, V64, 8763 V128_lo, VectorIndexH, 8764 asm, ".4s", ".4s", ".4h", ".h", 8765 [(set (v4i32 V128:$Rd), 8766 (OpNode (v4i16 V64:$Rn), 8767 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8768 bits<3> idx; 8769 let Inst{11} = idx{2}; 8770 let Inst{21} = idx{1}; 8771 let Inst{20} = idx{0}; 8772 } 8773 8774 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8775 V128, V128, 8776 V128_lo, VectorIndexH, 8777 asm#"2", ".4s", ".4s", ".8h", ".h", 8778 [(set (v4i32 V128:$Rd), 8779 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 8780 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8781 8782 bits<3> idx; 8783 let Inst{11} = idx{2}; 8784 let Inst{21} = idx{1}; 8785 let Inst{20} = idx{0}; 8786 } 8787 8788 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8789 V128, V64, 8790 V128, VectorIndexS, 8791 asm, ".2d", ".2d", ".2s", ".s", 8792 [(set (v2i64 V128:$Rd), 8793 (OpNode (v2i32 V64:$Rn), 8794 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8795 bits<2> idx; 8796 let Inst{11} = idx{1}; 8797 let Inst{21} = idx{0}; 8798 } 8799 8800 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8801 V128, V128, 8802 V128, VectorIndexS, 8803 asm#"2", ".2d", ".2d", ".4s", ".s", 8804 [(set (v2i64 V128:$Rd), 8805 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 8806 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8807 bits<2> idx; 8808 let Inst{11} = idx{1}; 8809 let Inst{21} = idx{0}; 8810 } 8811 8812 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8813 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8814 asm, ".h", "", "", ".h", []> { 8815 bits<3> idx; 8816 let Inst{11} = idx{2}; 8817 let Inst{21} = idx{1}; 8818 let Inst{20} = idx{0}; 8819 } 8820 8821 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8822 FPR64Op, FPR32Op, V128, VectorIndexS, 8823 asm, ".s", "", "", ".s", []> { 8824 bits<2> idx; 8825 let Inst{11} = idx{1}; 8826 let Inst{21} = idx{0}; 8827 } 8828} 8829 8830multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8831 SDPatternOperator Accum> { 8832 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8833 V128, V64, 8834 V128_lo, VectorIndexH, 8835 asm, ".4s", ".4s", ".4h", ".h", 8836 [(set (v4i32 V128:$dst), 8837 (Accum (v4i32 V128:$Rd), 8838 (v4i32 (int_aarch64_neon_sqdmull 8839 (v4i16 V64:$Rn), 8840 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8841 VectorIndexH:$idx))))))]> { 8842 bits<3> idx; 8843 let Inst{11} = idx{2}; 8844 let Inst{21} = idx{1}; 8845 let Inst{20} = idx{0}; 8846 } 8847 8848 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8849 // intermediate EXTRACT_SUBREG would be untyped. 8850 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8851 (i32 (vector_extract (v4i32 8852 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8853 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8854 VectorIndexH:$idx)))), 8855 (i64 0))))), 8856 (EXTRACT_SUBREG 8857 (!cast<Instruction>(NAME # v4i16_indexed) 8858 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8859 V128_lo:$Rm, VectorIndexH:$idx), 8860 ssub)>; 8861 8862 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8863 V128, V128, 8864 V128_lo, VectorIndexH, 8865 asm#"2", ".4s", ".4s", ".8h", ".h", 8866 [(set (v4i32 V128:$dst), 8867 (Accum (v4i32 V128:$Rd), 8868 (v4i32 (int_aarch64_neon_sqdmull 8869 (extract_high_v8i16 (v8i16 V128:$Rn)), 8870 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 8871 bits<3> idx; 8872 let Inst{11} = idx{2}; 8873 let Inst{21} = idx{1}; 8874 let Inst{20} = idx{0}; 8875 } 8876 8877 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8878 V128, V64, 8879 V128, VectorIndexS, 8880 asm, ".2d", ".2d", ".2s", ".s", 8881 [(set (v2i64 V128:$dst), 8882 (Accum (v2i64 V128:$Rd), 8883 (v2i64 (int_aarch64_neon_sqdmull 8884 (v2i32 V64:$Rn), 8885 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8886 VectorIndexS:$idx))))))]> { 8887 bits<2> idx; 8888 let Inst{11} = idx{1}; 8889 let Inst{21} = idx{0}; 8890 } 8891 8892 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8893 V128, V128, 8894 V128, VectorIndexS, 8895 asm#"2", ".2d", ".2d", ".4s", ".s", 8896 [(set (v2i64 V128:$dst), 8897 (Accum (v2i64 V128:$Rd), 8898 (v2i64 (int_aarch64_neon_sqdmull 8899 (extract_high_v4i32 (v4i32 V128:$Rn)), 8900 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 8901 bits<2> idx; 8902 let Inst{11} = idx{1}; 8903 let Inst{21} = idx{0}; 8904 } 8905 8906 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8907 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8908 asm, ".h", "", "", ".h", []> { 8909 bits<3> idx; 8910 let Inst{11} = idx{2}; 8911 let Inst{21} = idx{1}; 8912 let Inst{20} = idx{0}; 8913 } 8914 8915 8916 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8917 FPR64Op, FPR32Op, V128, VectorIndexS, 8918 asm, ".s", "", "", ".s", 8919 [(set (i64 FPR64Op:$dst), 8920 (Accum (i64 FPR64Op:$Rd), 8921 (i64 (int_aarch64_neon_sqdmulls_scalar 8922 (i32 FPR32Op:$Rn), 8923 (i32 (vector_extract (v4i32 V128:$Rm), 8924 VectorIndexS:$idx))))))]> { 8925 8926 bits<2> idx; 8927 let Inst{11} = idx{1}; 8928 let Inst{21} = idx{0}; 8929 } 8930} 8931 8932multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8933 SDPatternOperator OpNode> { 8934 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8935 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8936 V128, V64, 8937 V128_lo, VectorIndexH, 8938 asm, ".4s", ".4s", ".4h", ".h", 8939 [(set (v4i32 V128:$Rd), 8940 (OpNode (v4i16 V64:$Rn), 8941 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8942 bits<3> idx; 8943 let Inst{11} = idx{2}; 8944 let Inst{21} = idx{1}; 8945 let Inst{20} = idx{0}; 8946 } 8947 8948 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8949 V128, V128, 8950 V128_lo, VectorIndexH, 8951 asm#"2", ".4s", ".4s", ".8h", ".h", 8952 [(set (v4i32 V128:$Rd), 8953 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 8954 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8955 8956 bits<3> idx; 8957 let Inst{11} = idx{2}; 8958 let Inst{21} = idx{1}; 8959 let Inst{20} = idx{0}; 8960 } 8961 8962 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8963 V128, V64, 8964 V128, VectorIndexS, 8965 asm, ".2d", ".2d", ".2s", ".s", 8966 [(set (v2i64 V128:$Rd), 8967 (OpNode (v2i32 V64:$Rn), 8968 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8969 bits<2> idx; 8970 let Inst{11} = idx{1}; 8971 let Inst{21} = idx{0}; 8972 } 8973 8974 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8975 V128, V128, 8976 V128, VectorIndexS, 8977 asm#"2", ".2d", ".2d", ".4s", ".s", 8978 [(set (v2i64 V128:$Rd), 8979 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 8980 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8981 bits<2> idx; 8982 let Inst{11} = idx{1}; 8983 let Inst{21} = idx{0}; 8984 } 8985 } 8986} 8987 8988multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8989 SDPatternOperator OpNode> { 8990 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8991 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8992 V128, V64, 8993 V128_lo, VectorIndexH, 8994 asm, ".4s", ".4s", ".4h", ".h", 8995 [(set (v4i32 V128:$dst), 8996 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8997 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8998 bits<3> idx; 8999 let Inst{11} = idx{2}; 9000 let Inst{21} = idx{1}; 9001 let Inst{20} = idx{0}; 9002 } 9003 9004 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9005 V128, V128, 9006 V128_lo, VectorIndexH, 9007 asm#"2", ".4s", ".4s", ".8h", ".h", 9008 [(set (v4i32 V128:$dst), 9009 (OpNode (v4i32 V128:$Rd), 9010 (extract_high_v8i16 (v8i16 V128:$Rn)), 9011 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9012 bits<3> idx; 9013 let Inst{11} = idx{2}; 9014 let Inst{21} = idx{1}; 9015 let Inst{20} = idx{0}; 9016 } 9017 9018 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9019 V128, V64, 9020 V128, VectorIndexS, 9021 asm, ".2d", ".2d", ".2s", ".s", 9022 [(set (v2i64 V128:$dst), 9023 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9024 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9025 bits<2> idx; 9026 let Inst{11} = idx{1}; 9027 let Inst{21} = idx{0}; 9028 } 9029 9030 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9031 V128, V128, 9032 V128, VectorIndexS, 9033 asm#"2", ".2d", ".2d", ".4s", ".s", 9034 [(set (v2i64 V128:$dst), 9035 (OpNode (v2i64 V128:$Rd), 9036 (extract_high_v4i32 (v4i32 V128:$Rn)), 9037 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9038 bits<2> idx; 9039 let Inst{11} = idx{1}; 9040 let Inst{21} = idx{0}; 9041 } 9042 } 9043} 9044 9045//---------------------------------------------------------------------------- 9046// AdvSIMD scalar shift by immediate 9047//---------------------------------------------------------------------------- 9048 9049let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9050class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9051 RegisterClass regtype1, RegisterClass regtype2, 9052 Operand immtype, string asm, list<dag> pattern> 9053 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9054 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9055 Sched<[WriteVd]> { 9056 bits<5> Rd; 9057 bits<5> Rn; 9058 bits<7> imm; 9059 let Inst{31-30} = 0b01; 9060 let Inst{29} = U; 9061 let Inst{28-23} = 0b111110; 9062 let Inst{22-16} = fixed_imm; 9063 let Inst{15-11} = opc; 9064 let Inst{10} = 1; 9065 let Inst{9-5} = Rn; 9066 let Inst{4-0} = Rd; 9067} 9068 9069let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9070class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9071 RegisterClass regtype1, RegisterClass regtype2, 9072 Operand immtype, string asm, list<dag> pattern> 9073 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9074 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9075 Sched<[WriteVd]> { 9076 bits<5> Rd; 9077 bits<5> Rn; 9078 bits<7> imm; 9079 let Inst{31-30} = 0b01; 9080 let Inst{29} = U; 9081 let Inst{28-23} = 0b111110; 9082 let Inst{22-16} = fixed_imm; 9083 let Inst{15-11} = opc; 9084 let Inst{10} = 1; 9085 let Inst{9-5} = Rn; 9086 let Inst{4-0} = Rd; 9087} 9088 9089 9090multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9091 let Predicates = [HasNEON, HasFullFP16] in { 9092 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9093 FPR16, FPR16, vecshiftR16, asm, []> { 9094 let Inst{19-16} = imm{3-0}; 9095 } 9096 } // Predicates = [HasNEON, HasFullFP16] 9097 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9098 FPR32, FPR32, vecshiftR32, asm, []> { 9099 let Inst{20-16} = imm{4-0}; 9100 } 9101 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9102 FPR64, FPR64, vecshiftR64, asm, []> { 9103 let Inst{21-16} = imm{5-0}; 9104 } 9105} 9106 9107multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9108 SDPatternOperator OpNode> { 9109 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9110 FPR64, FPR64, vecshiftR64, asm, 9111 [(set (i64 FPR64:$Rd), 9112 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9113 let Inst{21-16} = imm{5-0}; 9114 } 9115 9116 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9117 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9118} 9119 9120multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9121 SDPatternOperator OpNode = null_frag> { 9122 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9123 FPR64, FPR64, vecshiftR64, asm, 9124 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9125 (i32 vecshiftR64:$imm)))]> { 9126 let Inst{21-16} = imm{5-0}; 9127 } 9128 9129 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9130 (i32 vecshiftR64:$imm))), 9131 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9132 vecshiftR64:$imm)>; 9133} 9134 9135multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9136 SDPatternOperator OpNode> { 9137 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9138 FPR64, FPR64, vecshiftL64, asm, 9139 [(set (i64 FPR64:$Rd), 9140 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9141 let Inst{21-16} = imm{5-0}; 9142 } 9143 9144 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9145 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9146} 9147 9148let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9149multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9150 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9151 FPR64, FPR64, vecshiftL64, asm, []> { 9152 let Inst{21-16} = imm{5-0}; 9153 } 9154} 9155 9156let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9157multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9158 SDPatternOperator OpNode = null_frag> { 9159 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9160 FPR8, FPR16, vecshiftR8, asm, []> { 9161 let Inst{18-16} = imm{2-0}; 9162 } 9163 9164 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9165 FPR16, FPR32, vecshiftR16, asm, []> { 9166 let Inst{19-16} = imm{3-0}; 9167 } 9168 9169 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9170 FPR32, FPR64, vecshiftR32, asm, 9171 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9172 let Inst{20-16} = imm{4-0}; 9173 } 9174} 9175 9176multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9177 SDPatternOperator OpNode> { 9178 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9179 FPR8, FPR8, vecshiftL8, asm, []> { 9180 let Inst{18-16} = imm{2-0}; 9181 } 9182 9183 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9184 FPR16, FPR16, vecshiftL16, asm, []> { 9185 let Inst{19-16} = imm{3-0}; 9186 } 9187 9188 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9189 FPR32, FPR32, vecshiftL32, asm, 9190 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9191 let Inst{20-16} = imm{4-0}; 9192 } 9193 9194 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9195 FPR64, FPR64, vecshiftL64, asm, 9196 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9197 let Inst{21-16} = imm{5-0}; 9198 } 9199 9200 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9201 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9202} 9203 9204multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9205 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9206 FPR8, FPR8, vecshiftR8, asm, []> { 9207 let Inst{18-16} = imm{2-0}; 9208 } 9209 9210 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9211 FPR16, FPR16, vecshiftR16, asm, []> { 9212 let Inst{19-16} = imm{3-0}; 9213 } 9214 9215 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9216 FPR32, FPR32, vecshiftR32, asm, []> { 9217 let Inst{20-16} = imm{4-0}; 9218 } 9219 9220 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9221 FPR64, FPR64, vecshiftR64, asm, []> { 9222 let Inst{21-16} = imm{5-0}; 9223 } 9224} 9225 9226//---------------------------------------------------------------------------- 9227// AdvSIMD vector x indexed element 9228//---------------------------------------------------------------------------- 9229 9230let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9231class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9232 RegisterOperand dst_reg, RegisterOperand src_reg, 9233 Operand immtype, 9234 string asm, string dst_kind, string src_kind, 9235 list<dag> pattern> 9236 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9237 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9238 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9239 Sched<[!if(Q, WriteVq, WriteVd)]> { 9240 bits<5> Rd; 9241 bits<5> Rn; 9242 let Inst{31} = 0; 9243 let Inst{30} = Q; 9244 let Inst{29} = U; 9245 let Inst{28-23} = 0b011110; 9246 let Inst{22-16} = fixed_imm; 9247 let Inst{15-11} = opc; 9248 let Inst{10} = 1; 9249 let Inst{9-5} = Rn; 9250 let Inst{4-0} = Rd; 9251} 9252 9253let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9254class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9255 RegisterOperand vectype1, RegisterOperand vectype2, 9256 Operand immtype, 9257 string asm, string dst_kind, string src_kind, 9258 list<dag> pattern> 9259 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9260 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9261 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9262 Sched<[!if(Q, WriteVq, WriteVd)]> { 9263 bits<5> Rd; 9264 bits<5> Rn; 9265 let Inst{31} = 0; 9266 let Inst{30} = Q; 9267 let Inst{29} = U; 9268 let Inst{28-23} = 0b011110; 9269 let Inst{22-16} = fixed_imm; 9270 let Inst{15-11} = opc; 9271 let Inst{10} = 1; 9272 let Inst{9-5} = Rn; 9273 let Inst{4-0} = Rd; 9274} 9275 9276multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9277 Intrinsic OpNode> { 9278 let Predicates = [HasNEON, HasFullFP16] in { 9279 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9280 V64, V64, vecshiftR16, 9281 asm, ".4h", ".4h", 9282 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9283 bits<4> imm; 9284 let Inst{19-16} = imm; 9285 } 9286 9287 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9288 V128, V128, vecshiftR16, 9289 asm, ".8h", ".8h", 9290 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9291 bits<4> imm; 9292 let Inst{19-16} = imm; 9293 } 9294 } // Predicates = [HasNEON, HasFullFP16] 9295 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9296 V64, V64, vecshiftR32, 9297 asm, ".2s", ".2s", 9298 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9299 bits<5> imm; 9300 let Inst{20-16} = imm; 9301 } 9302 9303 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9304 V128, V128, vecshiftR32, 9305 asm, ".4s", ".4s", 9306 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9307 bits<5> imm; 9308 let Inst{20-16} = imm; 9309 } 9310 9311 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9312 V128, V128, vecshiftR64, 9313 asm, ".2d", ".2d", 9314 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9315 bits<6> imm; 9316 let Inst{21-16} = imm; 9317 } 9318} 9319 9320multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9321 Intrinsic OpNode> { 9322 let Predicates = [HasNEON, HasFullFP16] in { 9323 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9324 V64, V64, vecshiftR16, 9325 asm, ".4h", ".4h", 9326 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9327 bits<4> imm; 9328 let Inst{19-16} = imm; 9329 } 9330 9331 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9332 V128, V128, vecshiftR16, 9333 asm, ".8h", ".8h", 9334 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9335 bits<4> imm; 9336 let Inst{19-16} = imm; 9337 } 9338 } // Predicates = [HasNEON, HasFullFP16] 9339 9340 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9341 V64, V64, vecshiftR32, 9342 asm, ".2s", ".2s", 9343 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9344 bits<5> imm; 9345 let Inst{20-16} = imm; 9346 } 9347 9348 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9349 V128, V128, vecshiftR32, 9350 asm, ".4s", ".4s", 9351 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9352 bits<5> imm; 9353 let Inst{20-16} = imm; 9354 } 9355 9356 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9357 V128, V128, vecshiftR64, 9358 asm, ".2d", ".2d", 9359 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9360 bits<6> imm; 9361 let Inst{21-16} = imm; 9362 } 9363} 9364 9365multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9366 SDPatternOperator OpNode> { 9367 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9368 V64, V128, vecshiftR16Narrow, 9369 asm, ".8b", ".8h", 9370 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9371 bits<3> imm; 9372 let Inst{18-16} = imm; 9373 } 9374 9375 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9376 V128, V128, vecshiftR16Narrow, 9377 asm#"2", ".16b", ".8h", []> { 9378 bits<3> imm; 9379 let Inst{18-16} = imm; 9380 let hasSideEffects = 0; 9381 } 9382 9383 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9384 V64, V128, vecshiftR32Narrow, 9385 asm, ".4h", ".4s", 9386 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9387 bits<4> imm; 9388 let Inst{19-16} = imm; 9389 } 9390 9391 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9392 V128, V128, vecshiftR32Narrow, 9393 asm#"2", ".8h", ".4s", []> { 9394 bits<4> imm; 9395 let Inst{19-16} = imm; 9396 let hasSideEffects = 0; 9397 } 9398 9399 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9400 V64, V128, vecshiftR64Narrow, 9401 asm, ".2s", ".2d", 9402 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9403 bits<5> imm; 9404 let Inst{20-16} = imm; 9405 } 9406 9407 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9408 V128, V128, vecshiftR64Narrow, 9409 asm#"2", ".4s", ".2d", []> { 9410 bits<5> imm; 9411 let Inst{20-16} = imm; 9412 let hasSideEffects = 0; 9413 } 9414 9415 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9416 // themselves, so put them here instead. 9417 9418 // Patterns involving what's effectively an insert high and a normal 9419 // intrinsic, represented by CONCAT_VECTORS. 9420 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9421 vecshiftR16Narrow:$imm)), 9422 (!cast<Instruction>(NAME # "v16i8_shift") 9423 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9424 V128:$Rn, vecshiftR16Narrow:$imm)>; 9425 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9426 vecshiftR32Narrow:$imm)), 9427 (!cast<Instruction>(NAME # "v8i16_shift") 9428 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9429 V128:$Rn, vecshiftR32Narrow:$imm)>; 9430 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9431 vecshiftR64Narrow:$imm)), 9432 (!cast<Instruction>(NAME # "v4i32_shift") 9433 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9434 V128:$Rn, vecshiftR64Narrow:$imm)>; 9435} 9436 9437multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9438 SDPatternOperator OpNode> { 9439 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9440 V64, V64, vecshiftL8, 9441 asm, ".8b", ".8b", 9442 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9443 (i32 vecshiftL8:$imm)))]> { 9444 bits<3> imm; 9445 let Inst{18-16} = imm; 9446 } 9447 9448 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9449 V128, V128, vecshiftL8, 9450 asm, ".16b", ".16b", 9451 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9452 (i32 vecshiftL8:$imm)))]> { 9453 bits<3> imm; 9454 let Inst{18-16} = imm; 9455 } 9456 9457 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9458 V64, V64, vecshiftL16, 9459 asm, ".4h", ".4h", 9460 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9461 (i32 vecshiftL16:$imm)))]> { 9462 bits<4> imm; 9463 let Inst{19-16} = imm; 9464 } 9465 9466 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9467 V128, V128, vecshiftL16, 9468 asm, ".8h", ".8h", 9469 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9470 (i32 vecshiftL16:$imm)))]> { 9471 bits<4> imm; 9472 let Inst{19-16} = imm; 9473 } 9474 9475 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9476 V64, V64, vecshiftL32, 9477 asm, ".2s", ".2s", 9478 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9479 (i32 vecshiftL32:$imm)))]> { 9480 bits<5> imm; 9481 let Inst{20-16} = imm; 9482 } 9483 9484 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9485 V128, V128, vecshiftL32, 9486 asm, ".4s", ".4s", 9487 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9488 (i32 vecshiftL32:$imm)))]> { 9489 bits<5> imm; 9490 let Inst{20-16} = imm; 9491 } 9492 9493 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9494 V128, V128, vecshiftL64, 9495 asm, ".2d", ".2d", 9496 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9497 (i32 vecshiftL64:$imm)))]> { 9498 bits<6> imm; 9499 let Inst{21-16} = imm; 9500 } 9501} 9502 9503multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9504 SDPatternOperator OpNode> { 9505 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9506 V64, V64, vecshiftR8, 9507 asm, ".8b", ".8b", 9508 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9509 (i32 vecshiftR8:$imm)))]> { 9510 bits<3> imm; 9511 let Inst{18-16} = imm; 9512 } 9513 9514 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9515 V128, V128, vecshiftR8, 9516 asm, ".16b", ".16b", 9517 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9518 (i32 vecshiftR8:$imm)))]> { 9519 bits<3> imm; 9520 let Inst{18-16} = imm; 9521 } 9522 9523 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9524 V64, V64, vecshiftR16, 9525 asm, ".4h", ".4h", 9526 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9527 (i32 vecshiftR16:$imm)))]> { 9528 bits<4> imm; 9529 let Inst{19-16} = imm; 9530 } 9531 9532 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9533 V128, V128, vecshiftR16, 9534 asm, ".8h", ".8h", 9535 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9536 (i32 vecshiftR16:$imm)))]> { 9537 bits<4> imm; 9538 let Inst{19-16} = imm; 9539 } 9540 9541 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9542 V64, V64, vecshiftR32, 9543 asm, ".2s", ".2s", 9544 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9545 (i32 vecshiftR32:$imm)))]> { 9546 bits<5> imm; 9547 let Inst{20-16} = imm; 9548 } 9549 9550 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9551 V128, V128, vecshiftR32, 9552 asm, ".4s", ".4s", 9553 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9554 (i32 vecshiftR32:$imm)))]> { 9555 bits<5> imm; 9556 let Inst{20-16} = imm; 9557 } 9558 9559 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9560 V128, V128, vecshiftR64, 9561 asm, ".2d", ".2d", 9562 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9563 (i32 vecshiftR64:$imm)))]> { 9564 bits<6> imm; 9565 let Inst{21-16} = imm; 9566 } 9567} 9568 9569let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9570multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9571 SDPatternOperator OpNode = null_frag> { 9572 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9573 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9574 [(set (v8i8 V64:$dst), 9575 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9576 (i32 vecshiftR8:$imm)))]> { 9577 bits<3> imm; 9578 let Inst{18-16} = imm; 9579 } 9580 9581 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9582 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9583 [(set (v16i8 V128:$dst), 9584 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9585 (i32 vecshiftR8:$imm)))]> { 9586 bits<3> imm; 9587 let Inst{18-16} = imm; 9588 } 9589 9590 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9591 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9592 [(set (v4i16 V64:$dst), 9593 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9594 (i32 vecshiftR16:$imm)))]> { 9595 bits<4> imm; 9596 let Inst{19-16} = imm; 9597 } 9598 9599 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9600 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9601 [(set (v8i16 V128:$dst), 9602 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9603 (i32 vecshiftR16:$imm)))]> { 9604 bits<4> imm; 9605 let Inst{19-16} = imm; 9606 } 9607 9608 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9609 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9610 [(set (v2i32 V64:$dst), 9611 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9612 (i32 vecshiftR32:$imm)))]> { 9613 bits<5> imm; 9614 let Inst{20-16} = imm; 9615 } 9616 9617 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9618 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9619 [(set (v4i32 V128:$dst), 9620 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9621 (i32 vecshiftR32:$imm)))]> { 9622 bits<5> imm; 9623 let Inst{20-16} = imm; 9624 } 9625 9626 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9627 V128, V128, vecshiftR64, 9628 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9629 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9630 (i32 vecshiftR64:$imm)))]> { 9631 bits<6> imm; 9632 let Inst{21-16} = imm; 9633 } 9634} 9635 9636multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9637 SDPatternOperator OpNode = null_frag> { 9638 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9639 V64, V64, vecshiftL8, 9640 asm, ".8b", ".8b", 9641 [(set (v8i8 V64:$dst), 9642 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9643 (i32 vecshiftL8:$imm)))]> { 9644 bits<3> imm; 9645 let Inst{18-16} = imm; 9646 } 9647 9648 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9649 V128, V128, vecshiftL8, 9650 asm, ".16b", ".16b", 9651 [(set (v16i8 V128:$dst), 9652 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9653 (i32 vecshiftL8:$imm)))]> { 9654 bits<3> imm; 9655 let Inst{18-16} = imm; 9656 } 9657 9658 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9659 V64, V64, vecshiftL16, 9660 asm, ".4h", ".4h", 9661 [(set (v4i16 V64:$dst), 9662 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9663 (i32 vecshiftL16:$imm)))]> { 9664 bits<4> imm; 9665 let Inst{19-16} = imm; 9666 } 9667 9668 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9669 V128, V128, vecshiftL16, 9670 asm, ".8h", ".8h", 9671 [(set (v8i16 V128:$dst), 9672 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9673 (i32 vecshiftL16:$imm)))]> { 9674 bits<4> imm; 9675 let Inst{19-16} = imm; 9676 } 9677 9678 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9679 V64, V64, vecshiftL32, 9680 asm, ".2s", ".2s", 9681 [(set (v2i32 V64:$dst), 9682 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9683 (i32 vecshiftL32:$imm)))]> { 9684 bits<5> imm; 9685 let Inst{20-16} = imm; 9686 } 9687 9688 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9689 V128, V128, vecshiftL32, 9690 asm, ".4s", ".4s", 9691 [(set (v4i32 V128:$dst), 9692 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9693 (i32 vecshiftL32:$imm)))]> { 9694 bits<5> imm; 9695 let Inst{20-16} = imm; 9696 } 9697 9698 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9699 V128, V128, vecshiftL64, 9700 asm, ".2d", ".2d", 9701 [(set (v2i64 V128:$dst), 9702 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9703 (i32 vecshiftL64:$imm)))]> { 9704 bits<6> imm; 9705 let Inst{21-16} = imm; 9706 } 9707} 9708 9709multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9710 SDPatternOperator OpNode> { 9711 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9712 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9713 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9714 bits<3> imm; 9715 let Inst{18-16} = imm; 9716 } 9717 9718 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9719 V128, V128, vecshiftL8, 9720 asm#"2", ".8h", ".16b", 9721 [(set (v8i16 V128:$Rd), 9722 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 9723 bits<3> imm; 9724 let Inst{18-16} = imm; 9725 } 9726 9727 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9728 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9729 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9730 bits<4> imm; 9731 let Inst{19-16} = imm; 9732 } 9733 9734 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9735 V128, V128, vecshiftL16, 9736 asm#"2", ".4s", ".8h", 9737 [(set (v4i32 V128:$Rd), 9738 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 9739 9740 bits<4> imm; 9741 let Inst{19-16} = imm; 9742 } 9743 9744 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9745 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9746 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9747 bits<5> imm; 9748 let Inst{20-16} = imm; 9749 } 9750 9751 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9752 V128, V128, vecshiftL32, 9753 asm#"2", ".2d", ".4s", 9754 [(set (v2i64 V128:$Rd), 9755 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 9756 bits<5> imm; 9757 let Inst{20-16} = imm; 9758 } 9759} 9760 9761 9762//--- 9763// Vector load/store 9764//--- 9765// SIMD ldX/stX no-index memory references don't allow the optional 9766// ", #0" constant and handle post-indexing explicitly, so we use 9767// a more specialized parse method for them. Otherwise, it's the same as 9768// the general GPR64sp handling. 9769 9770class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9771 string asm, dag oops, dag iops, list<dag> pattern> 9772 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9773 bits<5> Vt; 9774 bits<5> Rn; 9775 let Inst{31} = 0; 9776 let Inst{30} = Q; 9777 let Inst{29-23} = 0b0011000; 9778 let Inst{22} = L; 9779 let Inst{21-16} = 0b000000; 9780 let Inst{15-12} = opcode; 9781 let Inst{11-10} = size; 9782 let Inst{9-5} = Rn; 9783 let Inst{4-0} = Vt; 9784} 9785 9786class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9787 string asm, dag oops, dag iops> 9788 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9789 bits<5> Vt; 9790 bits<5> Rn; 9791 bits<5> Xm; 9792 let Inst{31} = 0; 9793 let Inst{30} = Q; 9794 let Inst{29-23} = 0b0011001; 9795 let Inst{22} = L; 9796 let Inst{21} = 0; 9797 let Inst{20-16} = Xm; 9798 let Inst{15-12} = opcode; 9799 let Inst{11-10} = size; 9800 let Inst{9-5} = Rn; 9801 let Inst{4-0} = Vt; 9802} 9803 9804// The immediate form of AdvSIMD post-indexed addressing is encoded with 9805// register post-index addressing from the zero register. 9806multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9807 int Offset, int Size> { 9808 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9809 // "ld1\t$Vt, [$Rn], #16" 9810 // may get mapped to 9811 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9812 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9813 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9814 GPR64sp:$Rn, 9815 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9816 XZR), 1>; 9817 9818 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9819 // "ld1.8b\t$Vt, [$Rn], #16" 9820 // may get mapped to 9821 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9822 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9823 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9824 GPR64sp:$Rn, 9825 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9826 XZR), 0>; 9827 9828 // E.g. "ld1.8b { v0, v1 }, [x1]" 9829 // "ld1\t$Vt, [$Rn]" 9830 // may get mapped to 9831 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9832 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9833 (!cast<Instruction>(BaseName # Count # "v" # layout) 9834 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9835 GPR64sp:$Rn), 0>; 9836 9837 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9838 // "ld1\t$Vt, [$Rn], $Xm" 9839 // may get mapped to 9840 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9841 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9842 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9843 GPR64sp:$Rn, 9844 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9845 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9846} 9847 9848multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9849 int Offset128, int Offset64, bits<4> opcode> { 9850 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9851 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9852 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9853 (ins GPR64sp:$Rn), []>; 9854 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9855 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9856 (ins GPR64sp:$Rn), []>; 9857 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9858 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9859 (ins GPR64sp:$Rn), []>; 9860 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9861 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9862 (ins GPR64sp:$Rn), []>; 9863 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9864 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9865 (ins GPR64sp:$Rn), []>; 9866 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9867 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9868 (ins GPR64sp:$Rn), []>; 9869 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9870 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9871 (ins GPR64sp:$Rn), []>; 9872 9873 9874 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9875 (outs GPR64sp:$wback, 9876 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9877 (ins GPR64sp:$Rn, 9878 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9879 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9880 (outs GPR64sp:$wback, 9881 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9882 (ins GPR64sp:$Rn, 9883 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9884 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9885 (outs GPR64sp:$wback, 9886 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9887 (ins GPR64sp:$Rn, 9888 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9889 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9890 (outs GPR64sp:$wback, 9891 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9892 (ins GPR64sp:$Rn, 9893 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9894 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9895 (outs GPR64sp:$wback, 9896 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9897 (ins GPR64sp:$Rn, 9898 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9899 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9900 (outs GPR64sp:$wback, 9901 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9902 (ins GPR64sp:$Rn, 9903 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9904 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9905 (outs GPR64sp:$wback, 9906 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9907 (ins GPR64sp:$Rn, 9908 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9909 } 9910 9911 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9912 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9913 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9914 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9915 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9916 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9917 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9918} 9919 9920// Only ld1/st1 has a v1d version. 9921multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9922 int Offset128, int Offset64, bits<4> opcode> { 9923 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9924 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9925 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9926 GPR64sp:$Rn), []>; 9927 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9928 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9929 GPR64sp:$Rn), []>; 9930 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9931 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9932 GPR64sp:$Rn), []>; 9933 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9934 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9935 GPR64sp:$Rn), []>; 9936 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9937 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9938 GPR64sp:$Rn), []>; 9939 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9940 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9941 GPR64sp:$Rn), []>; 9942 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9943 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9944 GPR64sp:$Rn), []>; 9945 9946 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9947 (outs GPR64sp:$wback), 9948 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9949 GPR64sp:$Rn, 9950 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9951 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9952 (outs GPR64sp:$wback), 9953 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9954 GPR64sp:$Rn, 9955 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9956 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9957 (outs GPR64sp:$wback), 9958 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9959 GPR64sp:$Rn, 9960 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9961 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9962 (outs GPR64sp:$wback), 9963 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9964 GPR64sp:$Rn, 9965 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9966 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9967 (outs GPR64sp:$wback), 9968 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9969 GPR64sp:$Rn, 9970 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9971 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9972 (outs GPR64sp:$wback), 9973 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9974 GPR64sp:$Rn, 9975 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9976 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9977 (outs GPR64sp:$wback), 9978 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9979 GPR64sp:$Rn, 9980 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9981 } 9982 9983 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9984 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9985 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9986 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9987 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9988 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9989 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9990} 9991 9992multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9993 int Offset128, int Offset64, bits<4> opcode> 9994 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9995 9996 // LD1 instructions have extra "1d" variants. 9997 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9998 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9999 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 10000 (ins GPR64sp:$Rn), []>; 10001 10002 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 10003 (outs GPR64sp:$wback, 10004 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10005 (ins GPR64sp:$Rn, 10006 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10007 } 10008 10009 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10010} 10011 10012multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10013 int Offset128, int Offset64, bits<4> opcode> 10014 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10015 10016 // ST1 instructions have extra "1d" variants. 10017 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10018 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10019 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10020 GPR64sp:$Rn), []>; 10021 10022 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10023 (outs GPR64sp:$wback), 10024 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10025 GPR64sp:$Rn, 10026 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10027 } 10028 10029 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10030} 10031 10032multiclass SIMDLd1Multiple<string asm> { 10033 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10034 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10035 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10036 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10037} 10038 10039multiclass SIMDSt1Multiple<string asm> { 10040 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10041 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10042 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10043 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10044} 10045 10046multiclass SIMDLd2Multiple<string asm> { 10047 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10048} 10049 10050multiclass SIMDSt2Multiple<string asm> { 10051 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10052} 10053 10054multiclass SIMDLd3Multiple<string asm> { 10055 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10056} 10057 10058multiclass SIMDSt3Multiple<string asm> { 10059 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10060} 10061 10062multiclass SIMDLd4Multiple<string asm> { 10063 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10064} 10065 10066multiclass SIMDSt4Multiple<string asm> { 10067 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10068} 10069 10070//--- 10071// AdvSIMD Load/store single-element 10072//--- 10073 10074class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10075 string asm, string operands, string cst, 10076 dag oops, dag iops, list<dag> pattern> 10077 : I<oops, iops, asm, operands, cst, pattern> { 10078 bits<5> Vt; 10079 bits<5> Rn; 10080 let Inst{31} = 0; 10081 let Inst{29-24} = 0b001101; 10082 let Inst{22} = L; 10083 let Inst{21} = R; 10084 let Inst{15-13} = opcode; 10085 let Inst{9-5} = Rn; 10086 let Inst{4-0} = Vt; 10087} 10088 10089class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10090 string asm, string operands, string cst, 10091 dag oops, dag iops, list<dag> pattern> 10092 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10093 bits<5> Vt; 10094 bits<5> Rn; 10095 let Inst{31} = 0; 10096 let Inst{29-24} = 0b001101; 10097 let Inst{22} = L; 10098 let Inst{21} = R; 10099 let Inst{15-13} = opcode; 10100 let Inst{9-5} = Rn; 10101 let Inst{4-0} = Vt; 10102} 10103 10104 10105let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10106class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10107 DAGOperand listtype> 10108 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10109 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10110 []> { 10111 let Inst{30} = Q; 10112 let Inst{23} = 0; 10113 let Inst{20-16} = 0b00000; 10114 let Inst{12} = S; 10115 let Inst{11-10} = size; 10116} 10117let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10118class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10119 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10120 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10121 "$Rn = $wback", 10122 (outs GPR64sp:$wback, listtype:$Vt), 10123 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10124 bits<5> Xm; 10125 let Inst{30} = Q; 10126 let Inst{23} = 1; 10127 let Inst{20-16} = Xm; 10128 let Inst{12} = S; 10129 let Inst{11-10} = size; 10130} 10131 10132multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10133 int Offset, int Size> { 10134 // E.g. "ld1r { v0.8b }, [x1], #1" 10135 // "ld1r.8b\t$Vt, [$Rn], #1" 10136 // may get mapped to 10137 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10138 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10139 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10140 GPR64sp:$Rn, 10141 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10142 XZR), 1>; 10143 10144 // E.g. "ld1r.8b { v0 }, [x1], #1" 10145 // "ld1r.8b\t$Vt, [$Rn], #1" 10146 // may get mapped to 10147 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10148 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10149 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10150 GPR64sp:$Rn, 10151 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10152 XZR), 0>; 10153 10154 // E.g. "ld1r.8b { v0 }, [x1]" 10155 // "ld1r.8b\t$Vt, [$Rn]" 10156 // may get mapped to 10157 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10158 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10159 (!cast<Instruction>(BaseName # "v" # layout) 10160 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10161 GPR64sp:$Rn), 0>; 10162 10163 // E.g. "ld1r.8b { v0 }, [x1], x2" 10164 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10165 // may get mapped to 10166 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10167 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10168 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10169 GPR64sp:$Rn, 10170 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10171 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10172} 10173 10174multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10175 int Offset1, int Offset2, int Offset4, int Offset8> { 10176 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10177 !cast<DAGOperand>("VecList" # Count # "8b")>; 10178 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10179 !cast<DAGOperand>("VecList" # Count #"16b")>; 10180 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10181 !cast<DAGOperand>("VecList" # Count #"4h")>; 10182 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10183 !cast<DAGOperand>("VecList" # Count #"8h")>; 10184 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10185 !cast<DAGOperand>("VecList" # Count #"2s")>; 10186 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10187 !cast<DAGOperand>("VecList" # Count #"4s")>; 10188 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10189 !cast<DAGOperand>("VecList" # Count #"1d")>; 10190 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10191 !cast<DAGOperand>("VecList" # Count #"2d")>; 10192 10193 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10194 !cast<DAGOperand>("VecList" # Count # "8b"), 10195 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10196 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10197 !cast<DAGOperand>("VecList" # Count # "16b"), 10198 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10199 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10200 !cast<DAGOperand>("VecList" # Count # "4h"), 10201 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10202 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10203 !cast<DAGOperand>("VecList" # Count # "8h"), 10204 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10205 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10206 !cast<DAGOperand>("VecList" # Count # "2s"), 10207 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10208 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10209 !cast<DAGOperand>("VecList" # Count # "4s"), 10210 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10211 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10212 !cast<DAGOperand>("VecList" # Count # "1d"), 10213 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10214 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10215 !cast<DAGOperand>("VecList" # Count # "2d"), 10216 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10217 10218 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10219 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10220 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10221 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10222 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10223 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10224 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10225 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10226} 10227 10228class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10229 dag oops, dag iops, list<dag> pattern> 10230 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10231 pattern> { 10232 // idx encoded in Q:S:size fields. 10233 bits<4> idx; 10234 let Inst{30} = idx{3}; 10235 let Inst{23} = 0; 10236 let Inst{20-16} = 0b00000; 10237 let Inst{12} = idx{2}; 10238 let Inst{11-10} = idx{1-0}; 10239} 10240class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10241 dag oops, dag iops, list<dag> pattern> 10242 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10243 oops, iops, pattern> { 10244 // idx encoded in Q:S:size fields. 10245 bits<4> idx; 10246 let Inst{30} = idx{3}; 10247 let Inst{23} = 0; 10248 let Inst{20-16} = 0b00000; 10249 let Inst{12} = idx{2}; 10250 let Inst{11-10} = idx{1-0}; 10251} 10252class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10253 dag oops, dag iops> 10254 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10255 "$Rn = $wback", oops, iops, []> { 10256 // idx encoded in Q:S:size fields. 10257 bits<4> idx; 10258 bits<5> Xm; 10259 let Inst{30} = idx{3}; 10260 let Inst{23} = 1; 10261 let Inst{20-16} = Xm; 10262 let Inst{12} = idx{2}; 10263 let Inst{11-10} = idx{1-0}; 10264} 10265class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10266 dag oops, dag iops> 10267 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10268 "$Rn = $wback", oops, iops, []> { 10269 // idx encoded in Q:S:size fields. 10270 bits<4> idx; 10271 bits<5> Xm; 10272 let Inst{30} = idx{3}; 10273 let Inst{23} = 1; 10274 let Inst{20-16} = Xm; 10275 let Inst{12} = idx{2}; 10276 let Inst{11-10} = idx{1-0}; 10277} 10278 10279class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10280 dag oops, dag iops, list<dag> pattern> 10281 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10282 pattern> { 10283 // idx encoded in Q:S:size<1> fields. 10284 bits<3> idx; 10285 let Inst{30} = idx{2}; 10286 let Inst{23} = 0; 10287 let Inst{20-16} = 0b00000; 10288 let Inst{12} = idx{1}; 10289 let Inst{11} = idx{0}; 10290 let Inst{10} = size; 10291} 10292class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10293 dag oops, dag iops, list<dag> pattern> 10294 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10295 oops, iops, pattern> { 10296 // idx encoded in Q:S:size<1> fields. 10297 bits<3> idx; 10298 let Inst{30} = idx{2}; 10299 let Inst{23} = 0; 10300 let Inst{20-16} = 0b00000; 10301 let Inst{12} = idx{1}; 10302 let Inst{11} = idx{0}; 10303 let Inst{10} = size; 10304} 10305 10306class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10307 dag oops, dag iops> 10308 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10309 "$Rn = $wback", oops, iops, []> { 10310 // idx encoded in Q:S:size<1> fields. 10311 bits<3> idx; 10312 bits<5> Xm; 10313 let Inst{30} = idx{2}; 10314 let Inst{23} = 1; 10315 let Inst{20-16} = Xm; 10316 let Inst{12} = idx{1}; 10317 let Inst{11} = idx{0}; 10318 let Inst{10} = size; 10319} 10320class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10321 dag oops, dag iops> 10322 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10323 "$Rn = $wback", oops, iops, []> { 10324 // idx encoded in Q:S:size<1> fields. 10325 bits<3> idx; 10326 bits<5> Xm; 10327 let Inst{30} = idx{2}; 10328 let Inst{23} = 1; 10329 let Inst{20-16} = Xm; 10330 let Inst{12} = idx{1}; 10331 let Inst{11} = idx{0}; 10332 let Inst{10} = size; 10333} 10334class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10335 dag oops, dag iops, list<dag> pattern> 10336 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10337 pattern> { 10338 // idx encoded in Q:S fields. 10339 bits<2> idx; 10340 let Inst{30} = idx{1}; 10341 let Inst{23} = 0; 10342 let Inst{20-16} = 0b00000; 10343 let Inst{12} = idx{0}; 10344 let Inst{11-10} = size; 10345} 10346class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10347 dag oops, dag iops, list<dag> pattern> 10348 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10349 oops, iops, pattern> { 10350 // idx encoded in Q:S fields. 10351 bits<2> idx; 10352 let Inst{30} = idx{1}; 10353 let Inst{23} = 0; 10354 let Inst{20-16} = 0b00000; 10355 let Inst{12} = idx{0}; 10356 let Inst{11-10} = size; 10357} 10358class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10359 string asm, dag oops, dag iops> 10360 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10361 "$Rn = $wback", oops, iops, []> { 10362 // idx encoded in Q:S fields. 10363 bits<2> idx; 10364 bits<5> Xm; 10365 let Inst{30} = idx{1}; 10366 let Inst{23} = 1; 10367 let Inst{20-16} = Xm; 10368 let Inst{12} = idx{0}; 10369 let Inst{11-10} = size; 10370} 10371class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10372 string asm, dag oops, dag iops> 10373 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10374 "$Rn = $wback", oops, iops, []> { 10375 // idx encoded in Q:S fields. 10376 bits<2> idx; 10377 bits<5> Xm; 10378 let Inst{30} = idx{1}; 10379 let Inst{23} = 1; 10380 let Inst{20-16} = Xm; 10381 let Inst{12} = idx{0}; 10382 let Inst{11-10} = size; 10383} 10384class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10385 dag oops, dag iops, list<dag> pattern> 10386 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10387 pattern> { 10388 // idx encoded in Q field. 10389 bits<1> idx; 10390 let Inst{30} = idx; 10391 let Inst{23} = 0; 10392 let Inst{20-16} = 0b00000; 10393 let Inst{12} = 0; 10394 let Inst{11-10} = size; 10395} 10396class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10397 dag oops, dag iops, list<dag> pattern> 10398 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10399 oops, iops, pattern> { 10400 // idx encoded in Q field. 10401 bits<1> idx; 10402 let Inst{30} = idx; 10403 let Inst{23} = 0; 10404 let Inst{20-16} = 0b00000; 10405 let Inst{12} = 0; 10406 let Inst{11-10} = size; 10407} 10408class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10409 string asm, dag oops, dag iops> 10410 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10411 "$Rn = $wback", oops, iops, []> { 10412 // idx encoded in Q field. 10413 bits<1> idx; 10414 bits<5> Xm; 10415 let Inst{30} = idx; 10416 let Inst{23} = 1; 10417 let Inst{20-16} = Xm; 10418 let Inst{12} = 0; 10419 let Inst{11-10} = size; 10420} 10421class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10422 string asm, dag oops, dag iops> 10423 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10424 "$Rn = $wback", oops, iops, []> { 10425 // idx encoded in Q field. 10426 bits<1> idx; 10427 bits<5> Xm; 10428 let Inst{30} = idx; 10429 let Inst{23} = 1; 10430 let Inst{20-16} = Xm; 10431 let Inst{12} = 0; 10432 let Inst{11-10} = size; 10433} 10434 10435let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10436multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10437 RegisterOperand listtype, 10438 RegisterOperand GPR64pi> { 10439 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10440 (outs listtype:$dst), 10441 (ins listtype:$Vt, VectorIndexB:$idx, 10442 GPR64sp:$Rn), []>; 10443 10444 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10445 (outs GPR64sp:$wback, listtype:$dst), 10446 (ins listtype:$Vt, VectorIndexB:$idx, 10447 GPR64sp:$Rn, GPR64pi:$Xm)>; 10448} 10449let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10450multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10451 RegisterOperand listtype, 10452 RegisterOperand GPR64pi> { 10453 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10454 (outs listtype:$dst), 10455 (ins listtype:$Vt, VectorIndexH:$idx, 10456 GPR64sp:$Rn), []>; 10457 10458 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10459 (outs GPR64sp:$wback, listtype:$dst), 10460 (ins listtype:$Vt, VectorIndexH:$idx, 10461 GPR64sp:$Rn, GPR64pi:$Xm)>; 10462} 10463let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10464multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10465 RegisterOperand listtype, 10466 RegisterOperand GPR64pi> { 10467 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10468 (outs listtype:$dst), 10469 (ins listtype:$Vt, VectorIndexS:$idx, 10470 GPR64sp:$Rn), []>; 10471 10472 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10473 (outs GPR64sp:$wback, listtype:$dst), 10474 (ins listtype:$Vt, VectorIndexS:$idx, 10475 GPR64sp:$Rn, GPR64pi:$Xm)>; 10476} 10477let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10478multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10479 RegisterOperand listtype, RegisterOperand GPR64pi> { 10480 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10481 (outs listtype:$dst), 10482 (ins listtype:$Vt, VectorIndexD:$idx, 10483 GPR64sp:$Rn), []>; 10484 10485 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10486 (outs GPR64sp:$wback, listtype:$dst), 10487 (ins listtype:$Vt, VectorIndexD:$idx, 10488 GPR64sp:$Rn, GPR64pi:$Xm)>; 10489} 10490let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10491multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10492 RegisterOperand listtype, RegisterOperand GPR64pi> { 10493 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10494 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10495 GPR64sp:$Rn), []>; 10496 10497 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10498 (outs GPR64sp:$wback), 10499 (ins listtype:$Vt, VectorIndexB:$idx, 10500 GPR64sp:$Rn, GPR64pi:$Xm)>; 10501} 10502let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10503multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10504 RegisterOperand listtype, RegisterOperand GPR64pi> { 10505 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10506 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10507 GPR64sp:$Rn), []>; 10508 10509 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10510 (outs GPR64sp:$wback), 10511 (ins listtype:$Vt, VectorIndexH:$idx, 10512 GPR64sp:$Rn, GPR64pi:$Xm)>; 10513} 10514let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10515multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10516 RegisterOperand listtype, RegisterOperand GPR64pi> { 10517 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10518 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10519 GPR64sp:$Rn), []>; 10520 10521 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10522 (outs GPR64sp:$wback), 10523 (ins listtype:$Vt, VectorIndexS:$idx, 10524 GPR64sp:$Rn, GPR64pi:$Xm)>; 10525} 10526let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10527multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10528 RegisterOperand listtype, RegisterOperand GPR64pi> { 10529 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10530 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10531 GPR64sp:$Rn), []>; 10532 10533 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10534 (outs GPR64sp:$wback), 10535 (ins listtype:$Vt, VectorIndexD:$idx, 10536 GPR64sp:$Rn, GPR64pi:$Xm)>; 10537} 10538 10539multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10540 string Count, int Offset, Operand idxtype> { 10541 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10542 // "ld1\t$Vt, [$Rn], #1" 10543 // may get mapped to 10544 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10545 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10546 (!cast<Instruction>(NAME # Type # "_POST") 10547 GPR64sp:$Rn, 10548 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10549 idxtype:$idx, XZR), 1>; 10550 10551 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10552 // "ld1.8b\t$Vt, [$Rn], #1" 10553 // may get mapped to 10554 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10555 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10556 (!cast<Instruction>(NAME # Type # "_POST") 10557 GPR64sp:$Rn, 10558 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10559 idxtype:$idx, XZR), 0>; 10560 10561 // E.g. "ld1.8b { v0 }[0], [x1]" 10562 // "ld1.8b\t$Vt, [$Rn]" 10563 // may get mapped to 10564 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10565 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10566 (!cast<Instruction>(NAME # Type) 10567 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10568 idxtype:$idx, GPR64sp:$Rn), 0>; 10569 10570 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10571 // "ld1.8b\t$Vt, [$Rn], $Xm" 10572 // may get mapped to 10573 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10574 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10575 (!cast<Instruction>(NAME # Type # "_POST") 10576 GPR64sp:$Rn, 10577 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10578 idxtype:$idx, 10579 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10580} 10581 10582multiclass SIMDLdSt1SingleAliases<string asm> { 10583 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10584 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10585 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10586 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10587} 10588 10589multiclass SIMDLdSt2SingleAliases<string asm> { 10590 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10591 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10592 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10593 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10594} 10595 10596multiclass SIMDLdSt3SingleAliases<string asm> { 10597 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10598 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10599 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10600 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10601} 10602 10603multiclass SIMDLdSt4SingleAliases<string asm> { 10604 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10605 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10606 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10607 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10608} 10609} // end of 'let Predicates = [HasNEON]' 10610 10611//---------------------------------------------------------------------------- 10612// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10613//---------------------------------------------------------------------------- 10614 10615let Predicates = [HasNEON, HasRDM] in { 10616 10617class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10618 RegisterOperand regtype, string asm, 10619 string kind, list<dag> pattern> 10620 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10621 pattern> { 10622} 10623multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10624 SDPatternOperator op> { 10625 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10626 [(set (v4i16 V64:$dst), 10627 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 10628 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10629 [(set (v8i16 V128:$dst), 10630 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 10631 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10632 [(set (v2i32 V64:$dst), 10633 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 10634 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10635 [(set (v4i32 V128:$dst), 10636 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 10637} 10638 10639multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10640 SDPatternOperator op> { 10641 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10642 V64, V64, V128_lo, VectorIndexH, 10643 asm, ".4h", ".4h", ".4h", ".h", 10644 [(set (v4i16 V64:$dst), 10645 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10646 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10647 VectorIndexH:$idx)))))]> { 10648 bits<3> idx; 10649 let Inst{11} = idx{2}; 10650 let Inst{21} = idx{1}; 10651 let Inst{20} = idx{0}; 10652 } 10653 10654 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10655 V128, V128, V128_lo, VectorIndexH, 10656 asm, ".8h", ".8h", ".8h", ".h", 10657 [(set (v8i16 V128:$dst), 10658 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10659 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10660 VectorIndexH:$idx)))))]> { 10661 bits<3> idx; 10662 let Inst{11} = idx{2}; 10663 let Inst{21} = idx{1}; 10664 let Inst{20} = idx{0}; 10665 } 10666 10667 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10668 V64, V64, V128, VectorIndexS, 10669 asm, ".2s", ".2s", ".2s", ".s", 10670 [(set (v2i32 V64:$dst), 10671 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10672 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10673 VectorIndexS:$idx)))))]> { 10674 bits<2> idx; 10675 let Inst{11} = idx{1}; 10676 let Inst{21} = idx{0}; 10677 } 10678 10679 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10680 V128, V128, V128, VectorIndexS, 10681 asm, ".4s", ".4s", ".4s", ".s", 10682 [(set (v4i32 V128:$dst), 10683 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10684 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10685 VectorIndexS:$idx)))))]> { 10686 bits<2> idx; 10687 let Inst{11} = idx{1}; 10688 let Inst{21} = idx{0}; 10689 } 10690 10691 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10692 FPR16Op, FPR16Op, V128_lo, 10693 VectorIndexH, asm, ".h", "", "", ".h", 10694 []> { 10695 bits<3> idx; 10696 let Inst{11} = idx{2}; 10697 let Inst{21} = idx{1}; 10698 let Inst{20} = idx{0}; 10699 } 10700 10701 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10702 FPR32Op, FPR32Op, V128, VectorIndexS, 10703 asm, ".s", "", "", ".s", 10704 [(set (i32 FPR32Op:$dst), 10705 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 10706 (i32 (vector_extract (v4i32 V128:$Rm), 10707 VectorIndexS:$idx)))))]> { 10708 bits<2> idx; 10709 let Inst{11} = idx{1}; 10710 let Inst{21} = idx{0}; 10711 } 10712} 10713} // let Predicates = [HasNeon, HasRDM] 10714 10715//---------------------------------------------------------------------------- 10716// ARMv8.3 Complex ADD/MLA instructions 10717//---------------------------------------------------------------------------- 10718 10719class ComplexRotationOperand<int Angle, int Remainder, string Type> 10720 : AsmOperandClass { 10721 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10722 let DiagnosticType = "InvalidComplexRotation" # Type; 10723 let Name = "ComplexRotation" # Type; 10724} 10725def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10726 SDNodeXForm<imm, [{ 10727 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10728}]>> { 10729 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10730 let PrintMethod = "printComplexRotationOp<90, 0>"; 10731} 10732def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10733 SDNodeXForm<imm, [{ 10734 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10735}]>> { 10736 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10737 let PrintMethod = "printComplexRotationOp<180, 90>"; 10738} 10739let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10740class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10741 RegisterOperand regtype, Operand rottype, 10742 string asm, string kind, list<dag> pattern> 10743 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10744 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10745 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10746 Sched<[!if(Q, WriteVq, WriteVd)]> { 10747 bits<5> Rd; 10748 bits<5> Rn; 10749 bits<5> Rm; 10750 bits<1> rot; 10751 let Inst{31} = 0; 10752 let Inst{30} = Q; 10753 let Inst{29} = U; 10754 let Inst{28-24} = 0b01110; 10755 let Inst{23-22} = size; 10756 let Inst{21} = 0; 10757 let Inst{20-16} = Rm; 10758 let Inst{15-13} = opcode; 10759 // Non-tied version (FCADD) only has one rotation bit 10760 let Inst{12} = rot; 10761 let Inst{11} = 0; 10762 let Inst{10} = 1; 10763 let Inst{9-5} = Rn; 10764 let Inst{4-0} = Rd; 10765} 10766 10767//8.3 CompNum - Floating-point complex number support 10768multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10769 string asm, SDPatternOperator OpNode>{ 10770 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10771 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10772 asm, ".4h", 10773 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10774 (v4f16 V64:$Rn), 10775 (v4f16 V64:$Rm), 10776 (i32 rottype:$rot)))]>; 10777 10778 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10779 asm, ".8h", 10780 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10781 (v8f16 V128:$Rn), 10782 (v8f16 V128:$Rm), 10783 (i32 rottype:$rot)))]>; 10784 } 10785 10786 let Predicates = [HasComplxNum, HasNEON] in { 10787 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10788 asm, ".2s", 10789 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10790 (v2f32 V64:$Rn), 10791 (v2f32 V64:$Rm), 10792 (i32 rottype:$rot)))]>; 10793 10794 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10795 asm, ".4s", 10796 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10797 (v4f32 V128:$Rn), 10798 (v4f32 V128:$Rm), 10799 (i32 rottype:$rot)))]>; 10800 10801 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10802 asm, ".2d", 10803 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10804 (v2f64 V128:$Rn), 10805 (v2f64 V128:$Rm), 10806 (i32 rottype:$rot)))]>; 10807 } 10808} 10809 10810let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10811class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10812 bits<3> opcode, 10813 RegisterOperand regtype, 10814 Operand rottype, string asm, 10815 string kind, list<dag> pattern> 10816 : I<(outs regtype:$dst), 10817 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10818 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10819 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10820 Sched<[!if(Q, WriteVq, WriteVd)]> { 10821 bits<5> Rd; 10822 bits<5> Rn; 10823 bits<5> Rm; 10824 bits<2> rot; 10825 let Inst{31} = 0; 10826 let Inst{30} = Q; 10827 let Inst{29} = U; 10828 let Inst{28-24} = 0b01110; 10829 let Inst{23-22} = size; 10830 let Inst{21} = 0; 10831 let Inst{20-16} = Rm; 10832 let Inst{15-13} = opcode; 10833 let Inst{12-11} = rot; 10834 let Inst{10} = 1; 10835 let Inst{9-5} = Rn; 10836 let Inst{4-0} = Rd; 10837} 10838 10839multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10840 Operand rottype, string asm, 10841 SDPatternOperator OpNode> { 10842 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10843 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10844 rottype, asm, ".4h", 10845 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10846 (v4f16 V64:$Rn), 10847 (v4f16 V64:$Rm), 10848 (i32 rottype:$rot)))]>; 10849 10850 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10851 rottype, asm, ".8h", 10852 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10853 (v8f16 V128:$Rn), 10854 (v8f16 V128:$Rm), 10855 (i32 rottype:$rot)))]>; 10856 } 10857 10858 let Predicates = [HasComplxNum, HasNEON] in { 10859 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10860 rottype, asm, ".2s", 10861 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10862 (v2f32 V64:$Rn), 10863 (v2f32 V64:$Rm), 10864 (i32 rottype:$rot)))]>; 10865 10866 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10867 rottype, asm, ".4s", 10868 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10869 (v4f32 V128:$Rn), 10870 (v4f32 V128:$Rm), 10871 (i32 rottype:$rot)))]>; 10872 10873 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10874 rottype, asm, ".2d", 10875 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10876 (v2f64 V128:$Rn), 10877 (v2f64 V128:$Rm), 10878 (i32 rottype:$rot)))]>; 10879 } 10880} 10881 10882let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10883class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10884 bit opc1, bit opc2, RegisterOperand dst_reg, 10885 RegisterOperand lhs_reg, 10886 RegisterOperand rhs_reg, Operand vec_idx, 10887 Operand rottype, string asm, string apple_kind, 10888 string dst_kind, string lhs_kind, 10889 string rhs_kind, list<dag> pattern> 10890 : I<(outs dst_reg:$dst), 10891 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10892 asm, 10893 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10894 "$idx, $rot" # "|" # apple_kind # 10895 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10896 Sched<[!if(Q, WriteVq, WriteVd)]> { 10897 bits<5> Rd; 10898 bits<5> Rn; 10899 bits<5> Rm; 10900 bits<2> rot; 10901 10902 let Inst{31} = 0; 10903 let Inst{30} = Q; 10904 let Inst{29} = U; 10905 let Inst{28} = Scalar; 10906 let Inst{27-24} = 0b1111; 10907 let Inst{23-22} = size; 10908 // Bit 21 must be set by the derived class. 10909 let Inst{20-16} = Rm; 10910 let Inst{15} = opc1; 10911 let Inst{14-13} = rot; 10912 let Inst{12} = opc2; 10913 // Bit 11 must be set by the derived class. 10914 let Inst{10} = 0; 10915 let Inst{9-5} = Rn; 10916 let Inst{4-0} = Rd; 10917} 10918 10919// The complex instructions index by pairs of elements, so the VectorIndexes 10920// don't match the lane types, and the index bits are different to the other 10921// classes. 10922multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 10923 string asm> { 10924 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10925 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10926 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10927 ".4h", ".h", []> { 10928 bits<1> idx; 10929 let Inst{11} = 0; 10930 let Inst{21} = idx{0}; 10931 } 10932 10933 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10934 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10935 ".8h", ".8h", ".h", []> { 10936 bits<2> idx; 10937 let Inst{11} = idx{1}; 10938 let Inst{21} = idx{0}; 10939 } 10940 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10941 10942 let Predicates = [HasComplxNum, HasNEON] in { 10943 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10944 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10945 ".4s", ".4s", ".s", []> { 10946 bits<1> idx; 10947 let Inst{11} = idx{0}; 10948 let Inst{21} = 0; 10949 } 10950 } // Predicates = [HasComplxNum, HasNEON] 10951} 10952 10953//---------------------------------------------------------------------------- 10954// Crypto extensions 10955//---------------------------------------------------------------------------- 10956 10957let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10958class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10959 list<dag> pat> 10960 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10961 Sched<[WriteVq]>{ 10962 bits<5> Rd; 10963 bits<5> Rn; 10964 let Inst{31-16} = 0b0100111000101000; 10965 let Inst{15-12} = opc; 10966 let Inst{11-10} = 0b10; 10967 let Inst{9-5} = Rn; 10968 let Inst{4-0} = Rd; 10969} 10970 10971class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10972 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10973 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10974 10975class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10976 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10977 "$Rd = $dst", 10978 [(set (v16i8 V128:$dst), 10979 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10980 10981let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10982class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10983 dag oops, dag iops, list<dag> pat> 10984 : I<oops, iops, asm, 10985 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10986 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10987 Sched<[WriteVq]>{ 10988 bits<5> Rd; 10989 bits<5> Rn; 10990 bits<5> Rm; 10991 let Inst{31-21} = 0b01011110000; 10992 let Inst{20-16} = Rm; 10993 let Inst{15} = 0; 10994 let Inst{14-12} = opc; 10995 let Inst{11-10} = 0b00; 10996 let Inst{9-5} = Rn; 10997 let Inst{4-0} = Rd; 10998} 10999 11000class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 11001 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11002 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 11003 [(set (v4i32 FPR128:$dst), 11004 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11005 (v4i32 V128:$Rm)))]>; 11006 11007class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11008 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11009 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11010 [(set (v4i32 V128:$dst), 11011 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11012 (v4i32 V128:$Rm)))]>; 11013 11014class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11015 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11016 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11017 [(set (v4i32 FPR128:$dst), 11018 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11019 (v4i32 V128:$Rm)))]>; 11020 11021let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11022class SHA2OpInst<bits<4> opc, string asm, string kind, 11023 string cstr, dag oops, dag iops, 11024 list<dag> pat> 11025 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11026 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11027 Sched<[WriteVq]>{ 11028 bits<5> Rd; 11029 bits<5> Rn; 11030 let Inst{31-16} = 0b0101111000101000; 11031 let Inst{15-12} = opc; 11032 let Inst{11-10} = 0b10; 11033 let Inst{9-5} = Rn; 11034 let Inst{4-0} = Rd; 11035} 11036 11037class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11038 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11039 (ins V128:$Rd, V128:$Rn), 11040 [(set (v4i32 V128:$dst), 11041 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11042 11043class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11044 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11045 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11046 11047// Armv8.2-A Crypto extensions 11048class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11049 list<dag> pattern> 11050 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11051 bits<5> Vd; 11052 bits<5> Vn; 11053 let Inst{31-25} = 0b1100111; 11054 let Inst{9-5} = Vn; 11055 let Inst{4-0} = Vd; 11056} 11057 11058class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11059 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11060 "$Vd = $Vdst", []> { 11061 let Inst{31-25} = 0b1100111; 11062 let Inst{24-21} = 0b0110; 11063 let Inst{20-15} = 0b000001; 11064 let Inst{14} = op0; 11065 let Inst{13-12} = 0b00; 11066 let Inst{11-10} = op1; 11067} 11068class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11069 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11070class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11071 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11072 11073class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11074 string asmops, string cst> 11075 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11076 bits<5> Vm; 11077 let Inst{24-21} = 0b0011; 11078 let Inst{20-16} = Vm; 11079 let Inst{15} = 0b1; 11080 let Inst{14} = op0; 11081 let Inst{13-12} = 0b00; 11082 let Inst{11-10} = op1; 11083} 11084class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11085 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11086 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11087class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11088 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11089 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11090class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11091 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11092 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11093class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11094 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11095 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11096class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11097 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11098 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11099 11100class CryptoRRRR<bits<2>op0, string asm, string asmops> 11101 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11102 asmops, "", []> { 11103 bits<5> Vm; 11104 bits<5> Va; 11105 let Inst{24-23} = 0b00; 11106 let Inst{22-21} = op0; 11107 let Inst{20-16} = Vm; 11108 let Inst{15} = 0b0; 11109 let Inst{14-10} = Va; 11110} 11111class CryptoRRRR_16B<bits<2>op0, string asm> 11112 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11113 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11114} 11115class CryptoRRRR_4S<bits<2>op0, string asm> 11116 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11117 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11118} 11119 11120class CryptoRRRi6<string asm> 11121 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11122 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11123 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11124 bits<6> imm; 11125 bits<5> Vm; 11126 let Inst{24-21} = 0b0100; 11127 let Inst{20-16} = Vm; 11128 let Inst{15-10} = imm; 11129 let Inst{9-5} = Vn; 11130 let Inst{4-0} = Vd; 11131} 11132 11133class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11134 : BaseCryptoV82<(outs V128:$Vdst), 11135 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11136 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11137 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11138 bits<2> imm; 11139 bits<5> Vm; 11140 let Inst{24-21} = 0b0010; 11141 let Inst{20-16} = Vm; 11142 let Inst{15} = 0b1; 11143 let Inst{14} = op0; 11144 let Inst{13-12} = imm; 11145 let Inst{11-10} = op1; 11146} 11147 11148//---------------------------------------------------------------------------- 11149// v8.1 atomic instructions extension: 11150// * CAS 11151// * CASP 11152// * SWP 11153// * LDOPregister<OP>, and aliases STOPregister<OP> 11154 11155// Instruction encodings: 11156// 11157// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11158// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11159// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11160// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11161// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11162// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11163 11164// Instruction syntax: 11165// 11166// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11167// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11168// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11169// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11170// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11171// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11172// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11173// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11174// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11175// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11176 11177let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11178class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11179 string cstr, list<dag> pattern> 11180 : I<oops, iops, asm, operands, cstr, pattern> { 11181 bits<2> Sz; 11182 bit NP; 11183 bit Acq; 11184 bit Rel; 11185 bits<5> Rs; 11186 bits<5> Rn; 11187 bits<5> Rt; 11188 let Inst{31-30} = Sz; 11189 let Inst{29-24} = 0b001000; 11190 let Inst{23} = NP; 11191 let Inst{22} = Acq; 11192 let Inst{21} = 0b1; 11193 let Inst{20-16} = Rs; 11194 let Inst{15} = Rel; 11195 let Inst{14-10} = 0b11111; 11196 let Inst{9-5} = Rn; 11197 let Inst{4-0} = Rt; 11198 let Predicates = [HasLSE]; 11199} 11200 11201class BaseCAS<string order, string size, RegisterClass RC> 11202 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11203 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11204 "$out = $Rs",[]>, 11205 Sched<[WriteAtomic]> { 11206 let NP = 1; 11207} 11208 11209multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11210 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11211 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11212 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11213 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11214} 11215 11216class BaseCASP<string order, string size, RegisterOperand RC> 11217 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11218 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11219 "$out = $Rs",[]>, 11220 Sched<[WriteAtomic]> { 11221 let NP = 0; 11222} 11223 11224multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11225 let Sz = 0b00, Acq = Acq, Rel = Rel in 11226 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11227 let Sz = 0b01, Acq = Acq, Rel = Rel in 11228 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11229} 11230 11231let Predicates = [HasLSE] in 11232class BaseSWP<string order, string size, RegisterClass RC> 11233 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11234 "\t$Rs, $Rt, [$Rn]","",[]>, 11235 Sched<[WriteAtomic]> { 11236 bits<2> Sz; 11237 bit Acq; 11238 bit Rel; 11239 bits<5> Rs; 11240 bits<3> opc = 0b000; 11241 bits<5> Rn; 11242 bits<5> Rt; 11243 let Inst{31-30} = Sz; 11244 let Inst{29-24} = 0b111000; 11245 let Inst{23} = Acq; 11246 let Inst{22} = Rel; 11247 let Inst{21} = 0b1; 11248 let Inst{20-16} = Rs; 11249 let Inst{15} = 0b1; 11250 let Inst{14-12} = opc; 11251 let Inst{11-10} = 0b00; 11252 let Inst{9-5} = Rn; 11253 let Inst{4-0} = Rt; 11254 let Predicates = [HasLSE]; 11255} 11256 11257multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11258 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11259 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11260 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11261 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11262} 11263 11264let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11265class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11266 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11267 "\t$Rs, $Rt, [$Rn]","",[]>, 11268 Sched<[WriteAtomic]> { 11269 bits<2> Sz; 11270 bit Acq; 11271 bit Rel; 11272 bits<5> Rs; 11273 bits<3> opc; 11274 bits<5> Rn; 11275 bits<5> Rt; 11276 let Inst{31-30} = Sz; 11277 let Inst{29-24} = 0b111000; 11278 let Inst{23} = Acq; 11279 let Inst{22} = Rel; 11280 let Inst{21} = 0b1; 11281 let Inst{20-16} = Rs; 11282 let Inst{15} = 0b0; 11283 let Inst{14-12} = opc; 11284 let Inst{11-10} = 0b00; 11285 let Inst{9-5} = Rn; 11286 let Inst{4-0} = Rt; 11287 let Predicates = [HasLSE]; 11288} 11289 11290multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11291 string order> { 11292 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11293 def B : BaseLDOPregister<op, order, "b", GPR32>; 11294 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11295 def H : BaseLDOPregister<op, order, "h", GPR32>; 11296 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11297 def W : BaseLDOPregister<op, order, "", GPR32>; 11298 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11299 def X : BaseLDOPregister<op, order, "", GPR64>; 11300} 11301 11302// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11303// complex DAG for DstRHS. 11304let Predicates = [HasLSE] in 11305multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11306 string size, dag SrcRHS, dag DstRHS> { 11307 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11308 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11309 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11310 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11311 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11312 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11313 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11314 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11315 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11316 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11317} 11318 11319multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11320 string size, dag RHS> { 11321 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11322} 11323 11324multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11325 string size, dag LHS, dag RHS> { 11326 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11327} 11328 11329multiclass LDOPregister_patterns<string inst, string op> { 11330 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11331 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11332 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11333 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11334} 11335 11336multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11337 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11338 (i64 GPR64:$Rm), 11339 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11340 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11341 (i32 GPR32:$Rm), 11342 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11343 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11344 (i32 GPR32:$Rm), 11345 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11346 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11347 (i32 GPR32:$Rm), 11348 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11349} 11350 11351let Predicates = [HasLSE] in 11352multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11353 string size, dag OLD, dag NEW> { 11354 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11355 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11356 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11357 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11358 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11359 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11360 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11361 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11362 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11363 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11364} 11365 11366multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11367 string size, dag OLD, dag NEW> { 11368 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11369} 11370 11371multiclass CASregister_patterns<string inst, string op> { 11372 defm : CASregister_patterns_ord<inst, "X", op, "64", 11373 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11374 defm : CASregister_patterns_ord<inst, "W", op, "32", 11375 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11376 defm : CASregister_patterns_ord<inst, "H", op, "16", 11377 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11378 defm : CASregister_patterns_ord<inst, "B", op, "8", 11379 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11380} 11381 11382let Predicates = [HasLSE] in 11383class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11384 Instruction inst> : 11385 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11386 11387multiclass STOPregister<string asm, string instr> { 11388 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11389 !cast<Instruction>(instr # "LB")>; 11390 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11391 !cast<Instruction>(instr # "LH")>; 11392 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11393 !cast<Instruction>(instr # "LW")>; 11394 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11395 !cast<Instruction>(instr # "LX")>; 11396 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11397 !cast<Instruction>(instr # "B")>; 11398 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11399 !cast<Instruction>(instr # "H")>; 11400 def : BaseSTOPregister<asm, GPR32, WZR, 11401 !cast<Instruction>(instr # "W")>; 11402 def : BaseSTOPregister<asm, GPR64, XZR, 11403 !cast<Instruction>(instr # "X")>; 11404} 11405 11406class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11407 dag iops, dag oops, list<dag> pat> 11408 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11409 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11410 bits<5> Rt; 11411 bits<5> Rn; 11412 let Inst{31-21} = 0b11111000001; 11413 let Inst{15} = 1; 11414 let Inst{14-12} = opc; 11415 let Inst{11-10} = 0b00; 11416 let Inst{9-5} = Rn; 11417 let Inst{4-0} = Rt; 11418 11419 let Predicates = [HasV8_7a]; 11420} 11421 11422class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11423 list<dag> pat = []> 11424 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11425 let Inst{20-16} = 0b11111; 11426} 11427 11428class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11429 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11430 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11431 bits<5> Rs; 11432 let Inst{20-16} = Rs; 11433} 11434 11435class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 11436 bits<2> op2, string asm> 11437 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 11438 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 11439 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 11440 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 11441 Sched<[]> { 11442 bits<5> Rd; 11443 bits<5> Rs; 11444 bits<5> Rn; 11445 let Inst{31-27} = 0b00011; 11446 let Inst{26} = isMove; 11447 let Inst{25-24} = 0b01; 11448 let Inst{23-22} = opcode; 11449 let Inst{21} = 0b0; 11450 let Inst{20-16} = Rs; 11451 let Inst{15-14} = op2; 11452 let Inst{13-12} = op1; 11453 let Inst{11-10} = 0b01; 11454 let Inst{9-5} = Rn; 11455 let Inst{4-0} = Rd; 11456 11457 let DecoderMethod = "DecodeCPYMemOpInstruction"; 11458 let mayLoad = 1; 11459 let mayStore = 1; 11460} 11461 11462class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11463 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 11464 11465class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11466 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 11467 11468class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 11469 string asm> 11470 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 11471 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 11472 asm, "\t[$Rd]!, $Rn!, $Rm", 11473 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 11474 Sched<[]> { 11475 bits<5> Rd; 11476 bits<5> Rn; 11477 bits<5> Rm; 11478 let Inst{31-27} = 0b00011; 11479 let Inst{26} = isTagging; 11480 let Inst{25-21} = 0b01110; 11481 let Inst{20-16} = Rm; 11482 let Inst{15-14} = opcode; 11483 let Inst{13} = op2; 11484 let Inst{12} = op1; 11485 let Inst{11-10} = 0b01; 11486 let Inst{9-5} = Rn; 11487 let Inst{4-0} = Rd; 11488 11489 let DecoderMethod = "DecodeSETMemOpInstruction"; 11490 let mayLoad = 0; 11491 let mayStore = 1; 11492} 11493 11494class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 11495 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 11496 11497class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 11498 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 11499 11500multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 11501 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 11502 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 11503 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 11504 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 11505 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 11506 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 11507 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 11508 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 11509 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 11510 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 11511 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 11512 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 11513 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 11514 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 11515 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 11516 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 11517} 11518 11519multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 11520 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 11521 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 11522 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 11523 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 11524 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 11525 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 11526 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 11527 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 11528 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 11529 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 11530 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 11531 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 11532 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 11533 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 11534 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 11535 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 11536} 11537 11538multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 11539 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 11540 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 11541 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 11542 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 11543} 11544 11545multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 11546 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 11547 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 11548 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 11549 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 11550} 11551 11552//---------------------------------------------------------------------------- 11553// Allow the size specifier tokens to be upper case, not just lower. 11554def : TokenAlias<".4B", ".4b">; // Add dot product 11555def : TokenAlias<".8B", ".8b">; 11556def : TokenAlias<".4H", ".4h">; 11557def : TokenAlias<".2S", ".2s">; 11558def : TokenAlias<".1D", ".1d">; 11559def : TokenAlias<".16B", ".16b">; 11560def : TokenAlias<".8H", ".8h">; 11561def : TokenAlias<".4S", ".4s">; 11562def : TokenAlias<".2D", ".2d">; 11563def : TokenAlias<".1Q", ".1q">; 11564def : TokenAlias<".2H", ".2h">; 11565def : TokenAlias<".B", ".b">; 11566def : TokenAlias<".H", ".h">; 11567def : TokenAlias<".S", ".s">; 11568def : TokenAlias<".D", ".d">; 11569def : TokenAlias<".Q", ".q">; 11570