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 1171def arith_uxtx : ComplexPattern<i64, 2, "SelectArithUXTXRegister", []>; 1172 1173// Floating-point immediate. 1174 1175def fpimm16XForm : SDNodeXForm<fpimm, [{ 1176 APFloat InVal = N->getValueAPF(); 1177 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1178 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1179 }]>; 1180 1181def fpimm32XForm : SDNodeXForm<fpimm, [{ 1182 APFloat InVal = N->getValueAPF(); 1183 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1184 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1185 }]>; 1186 1187def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{ 1188 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF() 1189 .bitcastToAPInt() 1190 .getZExtValue()); 1191 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1192 }]>; 1193 1194def fpimm64XForm : SDNodeXForm<fpimm, [{ 1195 APFloat InVal = N->getValueAPF(); 1196 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1197 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1198 }]>; 1199 1200def fpimm16 : Operand<f16>, 1201 FPImmLeaf<f16, [{ 1202 return AArch64_AM::getFP16Imm(Imm) != -1; 1203 }], fpimm16XForm> { 1204 let ParserMatchClass = FPImmOperand; 1205 let PrintMethod = "printFPImmOperand"; 1206} 1207 1208def fpimm32 : Operand<f32>, 1209 FPImmLeaf<f32, [{ 1210 return AArch64_AM::getFP32Imm(Imm) != -1; 1211 }], fpimm32XForm> { 1212 let ParserMatchClass = FPImmOperand; 1213 let PrintMethod = "printFPImmOperand"; 1214} 1215 1216def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{ 1217 uint64_t Enc = Imm.bitcastToAPInt().getZExtValue(); 1218 return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc); 1219 }], fpimm32SIMDModImmType4XForm> { 1220} 1221 1222def fpimm64 : Operand<f64>, 1223 FPImmLeaf<f64, [{ 1224 return AArch64_AM::getFP64Imm(Imm) != -1; 1225 }], fpimm64XForm> { 1226 let ParserMatchClass = FPImmOperand; 1227 let PrintMethod = "printFPImmOperand"; 1228} 1229 1230def fpimm8 : Operand<i32> { 1231 let ParserMatchClass = FPImmOperand; 1232 let PrintMethod = "printFPImmOperand"; 1233} 1234 1235def fpimm0 : FPImmLeaf<fAny, [{ 1236 return Imm.isExactlyValue(+0.0); 1237}]>; 1238 1239def fpimm_minus0 : FPImmLeaf<fAny, [{ 1240 return Imm.isExactlyValue(-0.0); 1241}]>; 1242 1243def fpimm_half : FPImmLeaf<fAny, [{ 1244 return Imm.isExactlyValue(+0.5); 1245}]>; 1246 1247def fpimm_one : FPImmLeaf<fAny, [{ 1248 return Imm.isExactlyValue(+1.0); 1249}]>; 1250 1251def fpimm_two : FPImmLeaf<fAny, [{ 1252 return Imm.isExactlyValue(+2.0); 1253}]>; 1254 1255def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1256 GISDNodeXFormEquiv<fpimm16XForm>; 1257def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1258 GISDNodeXFormEquiv<fpimm32XForm>; 1259def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1260 GISDNodeXFormEquiv<fpimm64XForm>; 1261def gi_fpimm32SIMDModImmType4 : 1262 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, 1263 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>; 1264 1265// Vector lane operands 1266class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1267 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1268 let DiagnosticType = "Invalid" # Name; 1269 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1270 let RenderMethod = "addVectorIndexOperands"; 1271} 1272 1273class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1274 : Operand<ty> { 1275 let ParserMatchClass = mc; 1276 let PrintMethod = "printVectorIndex"; 1277} 1278 1279multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1280 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1281 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1282} 1283 1284def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1285def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1286def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1287def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1288def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1289def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1290 1291let OperandNamespace = "AArch64" in { 1292 let OperandType = "OPERAND_IMPLICIT_IMM_0" in { 1293 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1294 [{ return ((uint64_t)Imm) == 0; }]>; 1295 } 1296} 1297defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1298 [{ return ((uint64_t)Imm) == 1; }]>; 1299defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1300 [{ return ((uint64_t)Imm) < 16; }]>; 1301defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1302 [{ return ((uint64_t)Imm) < 8; }]>; 1303defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1304 [{ return ((uint64_t)Imm) < 4; }]>; 1305defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1306 [{ return ((uint64_t)Imm) < 2; }]>; 1307 1308defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1309 [{ return ((uint64_t)Imm) == 1; }]>; 1310defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1311 [{ return ((uint64_t)Imm) < 16; }]>; 1312defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1313 [{ return ((uint64_t)Imm) < 8; }]>; 1314defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1315 [{ return ((uint64_t)Imm) < 4; }]>; 1316defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1317 [{ return ((uint64_t)Imm) < 2; }]>; 1318 1319def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1320def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1321def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1322def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1323def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1324 1325defm sve_elm_idx_extdup_b 1326 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1327 [{ return ((uint64_t)Imm) < 64; }]>; 1328defm sve_elm_idx_extdup_h 1329 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1330 [{ return ((uint64_t)Imm) < 32; }]>; 1331defm sve_elm_idx_extdup_s 1332 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1333 [{ return ((uint64_t)Imm) < 16; }]>; 1334defm sve_elm_idx_extdup_d 1335 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1336 [{ return ((uint64_t)Imm) < 8; }]>; 1337defm sve_elm_idx_extdup_q 1338 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1339 [{ return ((uint64_t)Imm) < 4; }]>; 1340 1341def sme_elm_idx0_0 : Operand<i64>, ImmLeaf<i64, [{ 1342 return ((uint64_t)Imm) == 0; 1343}]> { 1344 let ParserMatchClass = Imm0_0Operand; 1345 let PrintMethod = "printMatrixIndex"; 1346 let OperandNamespace = "AArch64"; 1347 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1348} 1349def sme_elm_idx0_1 : Operand<i64>, ImmLeaf<i64, [{ 1350 return ((uint64_t)Imm) <= 1; 1351}]> { 1352 let ParserMatchClass = Imm0_1Operand; 1353 let PrintMethod = "printMatrixIndex"; 1354} 1355def sme_elm_idx0_3 : Operand<i64>, ImmLeaf<i64, [{ 1356 return ((uint64_t)Imm) <= 3; 1357}]> { 1358 let ParserMatchClass = Imm0_3Operand; 1359 let PrintMethod = "printMatrixIndex"; 1360} 1361def sme_elm_idx0_7 : Operand<i64>, ImmLeaf<i64, [{ 1362 return ((uint64_t)Imm) <= 7; 1363}]> { 1364 let ParserMatchClass = Imm0_7Operand; 1365 let PrintMethod = "printMatrixIndex"; 1366} 1367def sme_elm_idx0_15 : Operand<i64>, ImmLeaf<i64, [{ 1368 return ((uint64_t)Imm) <= 15; 1369}]> { 1370 let ParserMatchClass = Imm0_15Operand; 1371 let PrintMethod = "printMatrixIndex"; 1372} 1373 1374// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1375// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1376// are encoded as the eight bit value 'abcdefgh'. 1377def simdimmtype10 : Operand<i32>, 1378 FPImmLeaf<f64, [{ 1379 return AArch64_AM::isAdvSIMDModImmType10( 1380 Imm.bitcastToAPInt().getZExtValue()); 1381 }], SDNodeXForm<fpimm, [{ 1382 APFloat InVal = N->getValueAPF(); 1383 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1384 .bitcastToAPInt() 1385 .getZExtValue()); 1386 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1387 }]>> { 1388 let ParserMatchClass = SIMDImmType10Operand; 1389 let PrintMethod = "printSIMDType10Operand"; 1390} 1391 1392 1393//--- 1394// System management 1395//--- 1396 1397// Base encoding for system instruction operands. 1398let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1399class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1400 list<dag> pattern = []> 1401 : I<oops, iops, asm, operands, "", pattern> { 1402 let Inst{31-22} = 0b1101010100; 1403 let Inst{21} = L; 1404} 1405 1406// System instructions which do not have an Rt register. 1407class SimpleSystemI<bit L, dag iops, string asm, string operands, 1408 list<dag> pattern = []> 1409 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1410 let Inst{4-0} = 0b11111; 1411} 1412 1413// System instructions which have an Rt register. 1414class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1415 list<dag> pattern = []> 1416 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1417 Sched<[WriteSys]> { 1418 bits<5> Rt; 1419 let Inst{4-0} = Rt; 1420} 1421 1422// System instructions for transactional memory extension 1423class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1424 string asm, string operands, list<dag> pattern> 1425 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1426 Sched<[WriteSys]> { 1427 let Inst{20-12} = 0b000110011; 1428 let Inst{11-8} = CRm; 1429 let Inst{7-5} = op2; 1430 let DecoderMethod = ""; 1431 1432 let mayLoad = 1; 1433 let mayStore = 1; 1434} 1435 1436// System instructions for transactional memory - single input operand 1437class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1438 : TMBaseSystemI<0b1, CRm, 0b011, 1439 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1440 bits<5> Rt; 1441 let Inst{4-0} = Rt; 1442} 1443 1444// System instructions that pass a register argument 1445// This class assumes the register is for input rather than output. 1446class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1447 list<dag> pattern = []> 1448 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1449 let Inst{20-12} = 0b000110001; 1450 let Inst{11-8} = CRm; 1451 let Inst{7-5} = Op2; 1452} 1453 1454// System instructions for transactional memory - no operand 1455class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1456 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1457 let Inst{4-0} = 0b11111; 1458} 1459 1460// System instructions for exit from transactions 1461class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1462 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1463 Sched<[WriteSys]> { 1464 bits<16> imm; 1465 let Inst{31-24} = 0b11010100; 1466 let Inst{23-21} = op1; 1467 let Inst{20-5} = imm; 1468 let Inst{4-0} = 0b00000; 1469} 1470 1471// Hint instructions that take both a CRm and a 3-bit immediate. 1472// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1473// model patterns with sufficiently fine granularity 1474let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1475 class HintI<string mnemonic> 1476 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1477 [(int_aarch64_hint imm0_127:$imm)]>, 1478 Sched<[WriteHint]> { 1479 bits <7> imm; 1480 let Inst{20-12} = 0b000110010; 1481 let Inst{11-5} = imm; 1482 } 1483 1484// System instructions taking a single literal operand which encodes into 1485// CRm. op2 differentiates the opcodes. 1486def BarrierAsmOperand : AsmOperandClass { 1487 let Name = "Barrier"; 1488 let ParserMethod = "tryParseBarrierOperand"; 1489} 1490def barrier_op : Operand<i32> { 1491 let PrintMethod = "printBarrierOption"; 1492 let ParserMatchClass = BarrierAsmOperand; 1493} 1494def BarriernXSAsmOperand : AsmOperandClass { 1495 let Name = "BarriernXS"; 1496 let ParserMethod = "tryParseBarriernXSOperand"; 1497} 1498def barrier_nxs_op : Operand<i32> { 1499 let PrintMethod = "printBarriernXSOption"; 1500 let ParserMatchClass = BarriernXSAsmOperand; 1501} 1502class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1503 list<dag> pattern = []> 1504 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1505 Sched<[WriteBarrier]> { 1506 bits<4> CRm; 1507 let Inst{20-12} = 0b000110011; 1508 let Inst{11-8} = CRm; 1509 let Inst{7-5} = opc; 1510} 1511 1512class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1513 : SimpleSystemI<0, (ins), asm, "", pattern>, 1514 Sched<[WriteHint]> { 1515 bits<4> CRm; 1516 let CRm = 0b0011; 1517 let Inst{31-12} = 0b11010101000000110010; 1518 let Inst{11-8} = CRm; 1519 let Inst{7-5} = op2; 1520 let Inst{4-0} = 0b11111; 1521} 1522 1523// MRS/MSR system instructions. These have different operand classes because 1524// a different subset of registers can be accessed through each instruction. 1525def MRSSystemRegisterOperand : AsmOperandClass { 1526 let Name = "MRSSystemRegister"; 1527 let ParserMethod = "tryParseSysReg"; 1528 let DiagnosticType = "MRS"; 1529} 1530// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1531def mrs_sysreg_op : Operand<i32> { 1532 let ParserMatchClass = MRSSystemRegisterOperand; 1533 let DecoderMethod = "DecodeMRSSystemRegister"; 1534 let PrintMethod = "printMRSSystemRegister"; 1535} 1536 1537def MSRSystemRegisterOperand : AsmOperandClass { 1538 let Name = "MSRSystemRegister"; 1539 let ParserMethod = "tryParseSysReg"; 1540 let DiagnosticType = "MSR"; 1541} 1542def msr_sysreg_op : Operand<i32> { 1543 let ParserMatchClass = MSRSystemRegisterOperand; 1544 let DecoderMethod = "DecodeMSRSystemRegister"; 1545 let PrintMethod = "printMSRSystemRegister"; 1546} 1547 1548def PSBHintOperand : AsmOperandClass { 1549 let Name = "PSBHint"; 1550 let ParserMethod = "tryParsePSBHint"; 1551} 1552def psbhint_op : Operand<i32> { 1553 let ParserMatchClass = PSBHintOperand; 1554 let PrintMethod = "printPSBHintOp"; 1555 let MCOperandPredicate = [{ 1556 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1557 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1558 if (!MCOp.isImm()) 1559 return false; 1560 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1561 }]; 1562} 1563 1564def BTIHintOperand : AsmOperandClass { 1565 let Name = "BTIHint"; 1566 let ParserMethod = "tryParseBTIHint"; 1567} 1568def btihint_op : Operand<i32> { 1569 let ParserMatchClass = BTIHintOperand; 1570 let PrintMethod = "printBTIHintOp"; 1571 let MCOperandPredicate = [{ 1572 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1573 if (!MCOp.isImm()) 1574 return false; 1575 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1576 }]; 1577} 1578 1579class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1580 "mrs", "\t$Rt, $systemreg"> { 1581 bits<16> systemreg; 1582 let Inst{20-5} = systemreg; 1583 let DecoderNamespace = "Fallback"; 1584 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1585 // require doing this. The alternative was to explicitly model each one, but 1586 // it feels like it is unnecessary because it seems there are no negative 1587 // consequences setting these flags for all. 1588 let Defs = [NZCV]; 1589} 1590 1591// FIXME: Some of these def NZCV, others don't. Best way to model that? 1592// Explicitly modeling each of the system register as a register class 1593// would do it, but feels like overkill at this point. 1594class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1595 "msr", "\t$systemreg, $Rt"> { 1596 bits<16> systemreg; 1597 let Inst{20-5} = systemreg; 1598 let DecoderNamespace = "Fallback"; 1599} 1600 1601def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1602 let Name = "SystemPStateFieldWithImm0_15"; 1603 let ParserMethod = "tryParseSysReg"; 1604} 1605def pstatefield4_op : Operand<i32> { 1606 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1607 let PrintMethod = "printSystemPStateField"; 1608} 1609 1610// Instructions to modify PSTATE, no input reg 1611let Defs = [NZCV] in 1612class PstateWriteSimple<dag iops, string asm, string operands> 1613 : SimpleSystemI<0, iops, asm, operands> { 1614 1615 let Inst{20-19} = 0b00; 1616 let Inst{15-12} = 0b0100; 1617} 1618 1619class MSRpstateImm0_15 1620 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1621 "\t$pstatefield, $imm">, 1622 Sched<[WriteSys]> { 1623 1624 bits<6> pstatefield; 1625 bits<4> imm; 1626 let Inst{18-16} = pstatefield{5-3}; 1627 let Inst{11-8} = imm; 1628 let Inst{7-5} = pstatefield{2-0}; 1629 1630 let DecoderMethod = "DecodeSystemPStateInstruction"; 1631 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1632 // Fail the decoder should attempt to decode the instruction as MSRI. 1633 let hasCompleteDecoder = 0; 1634} 1635 1636def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1637 let Name = "SystemPStateFieldWithImm0_1"; 1638 let ParserMethod = "tryParseSysReg"; 1639} 1640def pstatefield1_op : Operand<i32> { 1641 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1642 let PrintMethod = "printSystemPStateField"; 1643} 1644 1645class MSRpstateImm0_1 1646 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1647 "\t$pstatefield, $imm">, 1648 Sched<[WriteSys]> { 1649 1650 bits<6> pstatefield; 1651 bit imm; 1652 let Inst{18-16} = pstatefield{5-3}; 1653 let Inst{11-9} = 0b000; 1654 let Inst{8} = imm; 1655 let Inst{7-5} = pstatefield{2-0}; 1656 1657 let DecoderMethod = "DecodeSystemPStateInstruction"; 1658 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1659 // Fail the decoder should attempt to decode the instruction as MSRI. 1660 let hasCompleteDecoder = 0; 1661} 1662 1663// SYS and SYSL generic system instructions. 1664def SysCRAsmOperand : AsmOperandClass { 1665 let Name = "SysCR"; 1666 let ParserMethod = "tryParseSysCROperand"; 1667} 1668 1669def sys_cr_op : Operand<i32> { 1670 let PrintMethod = "printSysCROperand"; 1671 let ParserMatchClass = SysCRAsmOperand; 1672} 1673 1674class SystemXtI<bit L, string asm> 1675 : RtSystemI<L, (outs), 1676 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1677 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1678 bits<3> op1; 1679 bits<4> Cn; 1680 bits<4> Cm; 1681 bits<3> op2; 1682 let Inst{20-19} = 0b01; 1683 let Inst{18-16} = op1; 1684 let Inst{15-12} = Cn; 1685 let Inst{11-8} = Cm; 1686 let Inst{7-5} = op2; 1687} 1688 1689class SystemLXtI<bit L, string asm> 1690 : RtSystemI<L, (outs), 1691 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1692 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1693 bits<3> op1; 1694 bits<4> Cn; 1695 bits<4> Cm; 1696 bits<3> op2; 1697 let Inst{20-19} = 0b01; 1698 let Inst{18-16} = op1; 1699 let Inst{15-12} = Cn; 1700 let Inst{11-8} = Cm; 1701 let Inst{7-5} = op2; 1702} 1703 1704 1705// Branch (register) instructions: 1706// 1707// case opc of 1708// 0001 blr 1709// 0000 br 1710// 0101 dret 1711// 0100 eret 1712// 0010 ret 1713// otherwise UNDEFINED 1714class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1715 string operands, list<dag> pattern> 1716 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1717 let Inst{31-25} = 0b1101011; 1718 let Inst{24-21} = opc; 1719 let Inst{20-16} = 0b11111; 1720 let Inst{15-10} = 0b000000; 1721 let Inst{4-0} = 0b00000; 1722} 1723 1724class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1725 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1726 bits<5> Rn; 1727 let Inst{9-5} = Rn; 1728} 1729 1730let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1731class SpecialReturn<bits<4> opc, string asm> 1732 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1733 let Inst{9-5} = 0b11111; 1734} 1735 1736let mayLoad = 1 in 1737class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1738 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1739 Sched<[]> { 1740 bits<5> Rn; 1741 bits<5> Rt; 1742 let Inst{31-30} = sz; 1743 let Inst{29-10} = 0b11100010111111110000; 1744 let Inst{9-5} = Rn; 1745 let Inst{4-0} = Rt; 1746} 1747 1748class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1749 list<dag> pattern> 1750 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1751 let isAuthenticated = 1; 1752 let Inst{31-25} = 0b1101011; 1753 let Inst{20-11} = 0b1111100001; 1754 let Inst{10} = M; 1755 let Inst{4-0} = 0b11111; 1756} 1757 1758class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1759 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1760 bits<5> Rn; 1761 bits<5> Rm; 1762 let Inst{24-22} = 0b100; 1763 let Inst{21} = op; 1764 let Inst{9-5} = Rn; 1765 let Inst{4-0} = Rm; 1766} 1767 1768class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1769 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1770 bits<5> Rn; 1771 let Inst{24} = 0; 1772 let Inst{23-21} = opc; 1773 let Inst{9-5} = Rn; 1774} 1775 1776let Uses = [LR,SP] in 1777class AuthReturn<bits<3> op, bits<1> M, string asm> 1778 : AuthBase<M, (outs), (ins), asm, "", []> { 1779 let Inst{24} = 0; 1780 let Inst{23-21} = op; 1781 let Inst{9-0} = 0b1111111111; 1782} 1783 1784let mayLoad = 1 in 1785class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1786 string operands, string cstr> 1787 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1788 bits<10> offset; 1789 bits<5> Rn; 1790 bits<5> Rt; 1791 let isAuthenticated = 1; 1792 let Inst{31-24} = 0b11111000; 1793 let Inst{23} = M; 1794 let Inst{22} = offset{9}; 1795 let Inst{21} = 1; 1796 let Inst{20-12} = offset{8-0}; 1797 let Inst{11} = W; 1798 let Inst{10} = 1; 1799 let Inst{9-5} = Rn; 1800 let Inst{4-0} = Rt; 1801 1802 let DecoderMethod = "DecodeAuthLoadInstruction"; 1803} 1804 1805multiclass AuthLoad<bit M, string asm, Operand opr> { 1806 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1807 (ins GPR64sp:$Rn, opr:$offset), 1808 asm, "\t$Rt, [$Rn, $offset]", "">; 1809 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1810 (ins GPR64sp:$Rn, opr:$offset), 1811 asm, "\t$Rt, [$Rn, $offset]!", 1812 "$Rn = $wback,@earlyclobber $wback">; 1813 1814 def : InstAlias<asm # "\t$Rt, [$Rn]", 1815 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1816 1817 def : InstAlias<asm # "\t$Rt, [$wback]!", 1818 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1819} 1820 1821//--- 1822// Conditional branch instruction. 1823//--- 1824 1825// Condition code. 1826// 4-bit immediate. Pretty-printed as <cc> 1827def ccode : Operand<i32> { 1828 let PrintMethod = "printCondCode"; 1829 let ParserMatchClass = CondCode; 1830} 1831def inv_ccode : Operand<i32> { 1832 // AL and NV are invalid in the aliases which use inv_ccode 1833 let PrintMethod = "printInverseCondCode"; 1834 let ParserMatchClass = CondCode; 1835 let MCOperandPredicate = [{ 1836 return MCOp.isImm() && 1837 MCOp.getImm() != AArch64CC::AL && 1838 MCOp.getImm() != AArch64CC::NV; 1839 }]; 1840} 1841 1842// Conditional branch target. 19-bit immediate. The low two bits of the target 1843// offset are implied zero and so are not part of the immediate. 1844def am_brcond : Operand<OtherVT> { 1845 let EncoderMethod = "getCondBranchTargetOpValue"; 1846 let DecoderMethod = "DecodePCRelLabel19"; 1847 let PrintMethod = "printAlignedLabel"; 1848 let ParserMatchClass = PCRelLabel19Operand; 1849 let OperandType = "OPERAND_PCREL"; 1850} 1851 1852class BranchCond<bit bit4, string mnemonic> 1853 : I<(outs), (ins ccode:$cond, am_brcond:$target), 1854 mnemonic, ".$cond\t$target", "", 1855 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 1856 let isBranch = 1; 1857 let isTerminator = 1; 1858 let Uses = [NZCV]; 1859 1860 bits<4> cond; 1861 bits<19> target; 1862 let Inst{31-24} = 0b01010100; 1863 let Inst{23-5} = target; 1864 let Inst{4} = bit4; 1865 let Inst{3-0} = cond; 1866} 1867 1868//--- 1869// Compare-and-branch instructions. 1870//--- 1871class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1872 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1873 asm, "\t$Rt, $target", "", 1874 [(node regtype:$Rt, bb:$target)]>, 1875 Sched<[WriteBr]> { 1876 let isBranch = 1; 1877 let isTerminator = 1; 1878 1879 bits<5> Rt; 1880 bits<19> target; 1881 let Inst{30-25} = 0b011010; 1882 let Inst{24} = op; 1883 let Inst{23-5} = target; 1884 let Inst{4-0} = Rt; 1885} 1886 1887multiclass CmpBranch<bit op, string asm, SDNode node> { 1888 def W : BaseCmpBranch<GPR32, op, asm, node> { 1889 let Inst{31} = 0; 1890 } 1891 def X : BaseCmpBranch<GPR64, op, asm, node> { 1892 let Inst{31} = 1; 1893 } 1894} 1895 1896//--- 1897// Test-bit-and-branch instructions. 1898//--- 1899// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1900// the target offset are implied zero and so are not part of the immediate. 1901def am_tbrcond : Operand<OtherVT> { 1902 let EncoderMethod = "getTestBranchTargetOpValue"; 1903 let PrintMethod = "printAlignedLabel"; 1904 let ParserMatchClass = BranchTarget14Operand; 1905 let OperandType = "OPERAND_PCREL"; 1906} 1907 1908// AsmOperand classes to emit (or not) special diagnostics 1909def TBZImm0_31Operand : AsmOperandClass { 1910 let Name = "TBZImm0_31"; 1911 let PredicateMethod = "isImmInRange<0,31>"; 1912 let RenderMethod = "addImmOperands"; 1913} 1914def TBZImm32_63Operand : AsmOperandClass { 1915 let Name = "Imm32_63"; 1916 let PredicateMethod = "isImmInRange<32,63>"; 1917 let DiagnosticType = "InvalidImm0_63"; 1918 let RenderMethod = "addImmOperands"; 1919} 1920 1921class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1922 return (((uint32_t)Imm) < 32); 1923}]> { 1924 let ParserMatchClass = matcher; 1925} 1926 1927def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1928def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1929 1930def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1931 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1932}]> { 1933 let ParserMatchClass = TBZImm32_63Operand; 1934} 1935 1936class BaseTestBranch<RegisterClass regtype, Operand immtype, 1937 bit op, string asm, SDNode node> 1938 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1939 asm, "\t$Rt, $bit_off, $target", "", 1940 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1941 Sched<[WriteBr]> { 1942 let isBranch = 1; 1943 let isTerminator = 1; 1944 1945 bits<5> Rt; 1946 bits<6> bit_off; 1947 bits<14> target; 1948 1949 let Inst{30-25} = 0b011011; 1950 let Inst{24} = op; 1951 let Inst{23-19} = bit_off{4-0}; 1952 let Inst{18-5} = target; 1953 let Inst{4-0} = Rt; 1954 1955 let DecoderMethod = "DecodeTestAndBranch"; 1956} 1957 1958multiclass TestBranch<bit op, string asm, SDNode node> { 1959 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1960 let Inst{31} = 0; 1961 } 1962 1963 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1964 let Inst{31} = 1; 1965 } 1966 1967 // Alias X-reg with 0-31 imm to W-Reg. 1968 def : InstAlias<asm # "\t$Rd, $imm, $target", 1969 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1970 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1971 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1972 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1973 tbz_imm0_31_diag:$imm, bb:$target)>; 1974} 1975 1976//--- 1977// Unconditional branch (immediate) instructions. 1978//--- 1979def am_b_target : Operand<OtherVT> { 1980 let EncoderMethod = "getBranchTargetOpValue"; 1981 let PrintMethod = "printAlignedLabel"; 1982 let ParserMatchClass = BranchTarget26Operand; 1983 let OperandType = "OPERAND_PCREL"; 1984} 1985def am_bl_target : Operand<i64> { 1986 let EncoderMethod = "getBranchTargetOpValue"; 1987 let PrintMethod = "printAlignedLabel"; 1988 let ParserMatchClass = BranchTarget26Operand; 1989 let OperandType = "OPERAND_PCREL"; 1990} 1991 1992class BImm<bit op, dag iops, string asm, list<dag> pattern> 1993 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1994 bits<26> addr; 1995 let Inst{31} = op; 1996 let Inst{30-26} = 0b00101; 1997 let Inst{25-0} = addr; 1998 1999 let DecoderMethod = "DecodeUnconditionalBranch"; 2000} 2001 2002class BranchImm<bit op, string asm, list<dag> pattern> 2003 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 2004class CallImm<bit op, string asm, list<dag> pattern> 2005 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 2006 2007//--- 2008// Basic one-operand data processing instructions. 2009//--- 2010 2011let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2012class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 2013 SDPatternOperator node> 2014 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 2015 [(set regtype:$Rd, (node regtype:$Rn))]>, 2016 Sched<[WriteI, ReadI]> { 2017 bits<5> Rd; 2018 bits<5> Rn; 2019 2020 let Inst{30-13} = 0b101101011000000000; 2021 let Inst{12-10} = opc; 2022 let Inst{9-5} = Rn; 2023 let Inst{4-0} = Rd; 2024} 2025 2026let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2027multiclass OneOperandData<bits<3> opc, string asm, 2028 SDPatternOperator node = null_frag> { 2029 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 2030 let Inst{31} = 0; 2031 } 2032 2033 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 2034 let Inst{31} = 1; 2035 } 2036} 2037 2038class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 2039 : BaseOneOperandData<opc, GPR32, asm, node> { 2040 let Inst{31} = 0; 2041} 2042 2043class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 2044 : BaseOneOperandData<opc, GPR64, asm, node> { 2045 let Inst{31} = 1; 2046} 2047 2048class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2049 SDPatternOperator op> 2050 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2051 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2052 Sched<[WriteI, ReadI]> { 2053 bits<5> Rd; 2054 bits<5> Rn; 2055 let Inst{31-15} = 0b11011010110000010; 2056 let Inst{14-12} = opcode_prefix; 2057 let Inst{11-10} = opcode; 2058 let Inst{9-5} = Rn; 2059 let Inst{4-0} = Rd; 2060} 2061 2062class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2063 SDPatternOperator op> 2064 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2065 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2066 Sched<[]> { 2067 bits<5> Rd; 2068 let Inst{31-15} = 0b11011010110000010; 2069 let Inst{14-12} = opcode_prefix; 2070 let Inst{11-10} = opcode; 2071 let Inst{9-5} = 0b11111; 2072 let Inst{4-0} = Rd; 2073} 2074 2075class SignAuthTwoOperand<bits<4> opc, string asm, 2076 SDPatternOperator OpNode> 2077 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2078 asm, "\t$Rd, $Rn, $Rm", "", 2079 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2080 Sched<[WriteI, ReadI, ReadI]> { 2081 bits<5> Rd; 2082 bits<5> Rn; 2083 bits<5> Rm; 2084 let Inst{31-21} = 0b10011010110; 2085 let Inst{20-16} = Rm; 2086 let Inst{15-14} = 0b00; 2087 let Inst{13-10} = opc; 2088 let Inst{9-5} = Rn; 2089 let Inst{4-0} = Rd; 2090} 2091 2092class ClearAuth<bits<1> data, string asm> 2093 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2094 bits<5> Rd; 2095 let Inst{31-11} = 0b110110101100000101000; 2096 let Inst{10} = data; 2097 let Inst{9-5} = 0b11111; 2098 let Inst{4-0} = Rd; 2099} 2100 2101// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2102class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2103 : I<(outs), iops, asm, ops, "", []>, 2104 Sched<[WriteI, ReadI, ReadI]> { 2105 let Uses = [NZCV]; 2106 let Defs = [NZCV]; 2107 bits<5> Rn; 2108 let Inst{31} = sf; 2109 let Inst{30-15} = 0b0111010000000000; 2110 let Inst{14} = sz; 2111 let Inst{13-10} = 0b0010; 2112 let Inst{9-5} = Rn; 2113 let Inst{4-0} = 0b01101; 2114} 2115 2116class FlagRotate<dag iops, string asm, string ops> 2117 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2118 bits<6> imm; 2119 bits<4> mask; 2120 let Inst{20-15} = imm; 2121 let Inst{13-10} = 0b0001; 2122 let Inst{4} = 0b0; 2123 let Inst{3-0} = mask; 2124} 2125 2126//--- 2127// Basic two-operand data processing instructions. 2128//--- 2129class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2130 list<dag> pattern> 2131 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2132 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2133 Sched<[WriteI, ReadI, ReadI]> { 2134 let Uses = [NZCV]; 2135 bits<5> Rd; 2136 bits<5> Rn; 2137 bits<5> Rm; 2138 let Inst{30} = isSub; 2139 let Inst{28-21} = 0b11010000; 2140 let Inst{20-16} = Rm; 2141 let Inst{15-10} = 0; 2142 let Inst{9-5} = Rn; 2143 let Inst{4-0} = Rd; 2144} 2145 2146class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2147 SDNode OpNode> 2148 : BaseBaseAddSubCarry<isSub, regtype, asm, 2149 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2150 2151class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2152 SDNode OpNode> 2153 : BaseBaseAddSubCarry<isSub, regtype, asm, 2154 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2155 (implicit NZCV)]> { 2156 let Defs = [NZCV]; 2157} 2158 2159multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2160 SDNode OpNode, SDNode OpNode_setflags> { 2161 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2162 let Inst{31} = 0; 2163 let Inst{29} = 0; 2164 } 2165 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2166 let Inst{31} = 1; 2167 let Inst{29} = 0; 2168 } 2169 2170 // Sets flags. 2171 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2172 OpNode_setflags> { 2173 let Inst{31} = 0; 2174 let Inst{29} = 1; 2175 } 2176 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2177 OpNode_setflags> { 2178 let Inst{31} = 1; 2179 let Inst{29} = 1; 2180 } 2181} 2182 2183class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2184 SDPatternOperator OpNode, 2185 RegisterClass in1regtype = regtype, 2186 RegisterClass in2regtype = regtype> 2187 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2188 asm, "\t$Rd, $Rn, $Rm", "", 2189 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2190 bits<5> Rd; 2191 bits<5> Rn; 2192 bits<5> Rm; 2193 let Inst{30-21} = 0b0011010110; 2194 let Inst{20-16} = Rm; 2195 let Inst{15-14} = 0b00; 2196 let Inst{13-10} = opc; 2197 let Inst{9-5} = Rn; 2198 let Inst{4-0} = Rd; 2199} 2200 2201class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2202 SDPatternOperator OpNode> 2203 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2204 let Inst{10} = isSigned; 2205} 2206 2207multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2208 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2209 Sched<[WriteID32, ReadID, ReadID]> { 2210 let Inst{31} = 0; 2211 } 2212 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2213 Sched<[WriteID64, ReadID, ReadID]> { 2214 let Inst{31} = 1; 2215 } 2216} 2217 2218class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2219 SDPatternOperator OpNode = null_frag> 2220 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2221 Sched<[WriteIS, ReadI]> { 2222 let Inst{11-10} = shift_type; 2223} 2224 2225multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2226 def Wr : BaseShift<shift_type, GPR32, asm> { 2227 let Inst{31} = 0; 2228 } 2229 2230 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2231 let Inst{31} = 1; 2232 } 2233 2234 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2235 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2236 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2237 2238 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2239 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2240 2241 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2242 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2243 2244 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2245 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2246 2247 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2248 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2249 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2250 2251 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2252 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2253 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2254} 2255 2256class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2257 : InstAlias<asm#"\t$dst, $src1, $src2", 2258 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2259 2260class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2261 RegisterClass addtype, string asm, 2262 list<dag> pattern> 2263 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2264 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2265 bits<5> Rd; 2266 bits<5> Rn; 2267 bits<5> Rm; 2268 bits<5> Ra; 2269 let Inst{30-24} = 0b0011011; 2270 let Inst{23-21} = opc; 2271 let Inst{20-16} = Rm; 2272 let Inst{15} = isSub; 2273 let Inst{14-10} = Ra; 2274 let Inst{9-5} = Rn; 2275 let Inst{4-0} = Rd; 2276} 2277 2278multiclass MulAccum<bit isSub, string asm> { 2279 // MADD/MSUB generation is decided by MachineCombiner.cpp 2280 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2281 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2282 let Inst{31} = 0; 2283 } 2284 2285 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2286 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2287 let Inst{31} = 1; 2288 } 2289} 2290 2291class WideMulAccum<bit isSub, bits<3> opc, string asm, 2292 SDNode AccNode, SDNode ExtNode> 2293 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2294 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2295 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2296 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2297 let Inst{31} = 1; 2298} 2299 2300class MulHi<bits<3> opc, string asm, SDNode OpNode> 2301 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2302 asm, "\t$Rd, $Rn, $Rm", "", 2303 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2304 Sched<[WriteIM64, ReadIM, ReadIM]> { 2305 bits<5> Rd; 2306 bits<5> Rn; 2307 bits<5> Rm; 2308 let Inst{31-24} = 0b10011011; 2309 let Inst{23-21} = opc; 2310 let Inst{20-16} = Rm; 2311 let Inst{15} = 0; 2312 let Inst{9-5} = Rn; 2313 let Inst{4-0} = Rd; 2314 2315 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2316 // (i.e. all bits 1) but is ignored by the processor. 2317 let PostEncoderMethod = "fixMulHigh"; 2318} 2319 2320class MulAccumWAlias<string asm, Instruction inst> 2321 : InstAlias<asm#"\t$dst, $src1, $src2", 2322 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2323class MulAccumXAlias<string asm, Instruction inst> 2324 : InstAlias<asm#"\t$dst, $src1, $src2", 2325 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2326class WideMulAccumAlias<string asm, Instruction inst> 2327 : InstAlias<asm#"\t$dst, $src1, $src2", 2328 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2329 2330class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2331 SDPatternOperator OpNode, string asm> 2332 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2333 asm, "\t$Rd, $Rn, $Rm", "", 2334 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2335 Sched<[WriteISReg, ReadI, ReadISReg]> { 2336 bits<5> Rd; 2337 bits<5> Rn; 2338 bits<5> Rm; 2339 2340 let Inst{31} = sf; 2341 let Inst{30-21} = 0b0011010110; 2342 let Inst{20-16} = Rm; 2343 let Inst{15-13} = 0b010; 2344 let Inst{12} = C; 2345 let Inst{11-10} = sz; 2346 let Inst{9-5} = Rn; 2347 let Inst{4-0} = Rd; 2348 let Predicates = [HasCRC]; 2349} 2350 2351//--- 2352// Address generation. 2353//--- 2354 2355class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2356 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2357 pattern>, 2358 Sched<[WriteI]> { 2359 bits<5> Xd; 2360 bits<21> label; 2361 let Inst{31} = page; 2362 let Inst{30-29} = label{1-0}; 2363 let Inst{28-24} = 0b10000; 2364 let Inst{23-5} = label{20-2}; 2365 let Inst{4-0} = Xd; 2366 2367 let DecoderMethod = "DecodeAdrInstruction"; 2368} 2369 2370//--- 2371// Move immediate. 2372//--- 2373 2374def movimm32_imm : Operand<i32> { 2375 let ParserMatchClass = AsmImmRange<0, 65535>; 2376 let EncoderMethod = "getMoveWideImmOpValue"; 2377 let PrintMethod = "printImm"; 2378} 2379def movimm32_shift : Operand<i32> { 2380 let PrintMethod = "printShifter"; 2381 let ParserMatchClass = MovImm32ShifterOperand; 2382} 2383def movimm64_shift : Operand<i32> { 2384 let PrintMethod = "printShifter"; 2385 let ParserMatchClass = MovImm64ShifterOperand; 2386} 2387 2388let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2389class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2390 string asm> 2391 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2392 asm, "\t$Rd, $imm$shift", "", []>, 2393 Sched<[WriteImm]> { 2394 bits<5> Rd; 2395 bits<16> imm; 2396 bits<6> shift; 2397 let Inst{30-29} = opc; 2398 let Inst{28-23} = 0b100101; 2399 let Inst{22-21} = shift{5-4}; 2400 let Inst{20-5} = imm; 2401 let Inst{4-0} = Rd; 2402 2403 let DecoderMethod = "DecodeMoveImmInstruction"; 2404} 2405 2406multiclass MoveImmediate<bits<2> opc, string asm> { 2407 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2408 let Inst{31} = 0; 2409 } 2410 2411 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2412 let Inst{31} = 1; 2413 } 2414} 2415 2416let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2417class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2418 string asm> 2419 : I<(outs regtype:$Rd), 2420 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2421 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2422 Sched<[WriteI, ReadI]> { 2423 bits<5> Rd; 2424 bits<16> imm; 2425 bits<6> shift; 2426 let Inst{30-29} = opc; 2427 let Inst{28-23} = 0b100101; 2428 let Inst{22-21} = shift{5-4}; 2429 let Inst{20-5} = imm; 2430 let Inst{4-0} = Rd; 2431 2432 let DecoderMethod = "DecodeMoveImmInstruction"; 2433} 2434 2435multiclass InsertImmediate<bits<2> opc, string asm> { 2436 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2437 let Inst{31} = 0; 2438 } 2439 2440 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2441 let Inst{31} = 1; 2442 } 2443} 2444 2445//--- 2446// Add/Subtract 2447//--- 2448 2449class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2450 string asm_inst, string asm_ops, 2451 dag inputs, dag pattern> 2452 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2453 Sched<[WriteI, ReadI]> { 2454 bits<5> Rd; 2455 bits<5> Rn; 2456 let Inst{30} = isSub; 2457 let Inst{29} = setFlags; 2458 let Inst{28-24} = 0b10001; 2459 let Inst{9-5} = Rn; 2460 let Inst{4-0} = Rd; 2461} 2462 2463class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2464 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2465 string asm_inst, SDPatternOperator OpNode> 2466 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2467 (ins srcRegtype:$Rn, immtype:$imm), 2468 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2469 bits<14> imm; 2470 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2471 let Inst{21-10} = imm{11-0}; 2472 let DecoderMethod = "DecodeAddSubImmShift"; 2473} 2474 2475class BaseAddSubRegPseudo<RegisterClass regtype, 2476 SDPatternOperator OpNode> 2477 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2478 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2479 Sched<[WriteI, ReadI, ReadI]>; 2480 2481class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2482 arith_shifted_reg shifted_regtype, string asm, 2483 SDPatternOperator OpNode> 2484 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2485 asm, "\t$Rd, $Rn, $Rm", "", 2486 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2487 Sched<[WriteISReg, ReadI, ReadISReg]> { 2488 // The operands are in order to match the 'addr' MI operands, so we 2489 // don't need an encoder method and by-name matching. Just use the default 2490 // in-order handling. Since we're using by-order, make sure the names 2491 // do not match. 2492 bits<5> dst; 2493 bits<5> src1; 2494 bits<5> src2; 2495 bits<8> shift; 2496 let Inst{30} = isSub; 2497 let Inst{29} = setFlags; 2498 let Inst{28-24} = 0b01011; 2499 let Inst{23-22} = shift{7-6}; 2500 let Inst{21} = 0; 2501 let Inst{20-16} = src2; 2502 let Inst{15-10} = shift{5-0}; 2503 let Inst{9-5} = src1; 2504 let Inst{4-0} = dst; 2505 2506 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2507} 2508 2509class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2510 RegisterClass src1Regtype, Operand src2Regtype, 2511 string asm, SDPatternOperator OpNode> 2512 : I<(outs dstRegtype:$R1), 2513 (ins src1Regtype:$R2, src2Regtype:$R3), 2514 asm, "\t$R1, $R2, $R3", "", 2515 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2516 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2517 bits<5> Rd; 2518 bits<5> Rn; 2519 bits<5> Rm; 2520 bits<6> ext; 2521 let Inst{30} = isSub; 2522 let Inst{29} = setFlags; 2523 let Inst{28-24} = 0b01011; 2524 let Inst{23-21} = 0b001; 2525 let Inst{20-16} = Rm; 2526 let Inst{15-13} = ext{5-3}; 2527 let Inst{12-10} = ext{2-0}; 2528 let Inst{9-5} = Rn; 2529 let Inst{4-0} = Rd; 2530 2531 let DecoderMethod = "DecodeAddSubERegInstruction"; 2532} 2533 2534let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2535class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2536 RegisterClass src1Regtype, RegisterClass src2Regtype, 2537 Operand ext_op, string asm> 2538 : I<(outs dstRegtype:$Rd), 2539 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2540 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2541 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2542 bits<5> Rd; 2543 bits<5> Rn; 2544 bits<5> Rm; 2545 bits<6> ext; 2546 let Inst{30} = isSub; 2547 let Inst{29} = setFlags; 2548 let Inst{28-24} = 0b01011; 2549 let Inst{23-21} = 0b001; 2550 let Inst{20-16} = Rm; 2551 let Inst{15} = ext{5}; 2552 let Inst{12-10} = ext{2-0}; 2553 let Inst{9-5} = Rn; 2554 let Inst{4-0} = Rd; 2555 2556 let DecoderMethod = "DecodeAddSubERegInstruction"; 2557} 2558 2559// Aliases for register+register add/subtract. 2560class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2561 RegisterClass src1Regtype, RegisterClass src2Regtype, 2562 int shiftExt> 2563 : InstAlias<asm#"\t$dst, $src1, $src2", 2564 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2565 shiftExt)>; 2566 2567multiclass AddSub<bit isSub, string mnemonic, string alias, 2568 SDPatternOperator OpNode = null_frag> { 2569 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2570 // Add/Subtract immediate 2571 // Increase the weight of the immediate variant to try to match it before 2572 // the extended register variant. 2573 // We used to match the register variant before the immediate when the 2574 // register argument could be implicitly zero-extended. 2575 let AddedComplexity = 6 in 2576 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2577 mnemonic, OpNode> { 2578 let Inst{31} = 0; 2579 } 2580 let AddedComplexity = 6 in 2581 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2582 mnemonic, OpNode> { 2583 let Inst{31} = 1; 2584 } 2585 2586 // Add/Subtract register - Only used for CodeGen 2587 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2588 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2589 2590 // Add/Subtract shifted register 2591 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2592 OpNode> { 2593 let Inst{31} = 0; 2594 } 2595 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2596 OpNode> { 2597 let Inst{31} = 1; 2598 } 2599 } 2600 2601 // Add/Subtract extended register 2602 let AddedComplexity = 1, hasSideEffects = 0 in { 2603 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2604 arith_extended_reg32_i32, mnemonic, OpNode> { 2605 let Inst{31} = 0; 2606 } 2607 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2608 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2609 let Inst{31} = 1; 2610 } 2611 } 2612 2613 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2614 arith_extendlsl64, mnemonic> { 2615 // UXTX and SXTX only. 2616 let Inst{14-13} = 0b11; 2617 let Inst{31} = 1; 2618 } 2619 2620 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2621 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2622 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2623 addsub_shifted_imm32_neg:$imm), 0>; 2624 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2625 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2626 addsub_shifted_imm64_neg:$imm), 0>; 2627 2628 // Register/register aliases with no shift when SP is not used. 2629 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2630 GPR32, GPR32, GPR32, 0>; 2631 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2632 GPR64, GPR64, GPR64, 0>; 2633 2634 // Register/register aliases with no shift when either the destination or 2635 // first source register is SP. 2636 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2637 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2638 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2639 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2640 def : AddSubRegAlias<mnemonic, 2641 !cast<Instruction>(NAME#"Xrx64"), 2642 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2643 def : AddSubRegAlias<mnemonic, 2644 !cast<Instruction>(NAME#"Xrx64"), 2645 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2646} 2647 2648multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2649 string alias, string cmpAlias> { 2650 let isCompare = 1, Defs = [NZCV] in { 2651 // Add/Subtract immediate 2652 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2653 mnemonic, OpNode> { 2654 let Inst{31} = 0; 2655 } 2656 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2657 mnemonic, OpNode> { 2658 let Inst{31} = 1; 2659 } 2660 2661 // Add/Subtract register 2662 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2663 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2664 2665 // Add/Subtract shifted register 2666 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2667 OpNode> { 2668 let Inst{31} = 0; 2669 } 2670 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2671 OpNode> { 2672 let Inst{31} = 1; 2673 } 2674 2675 // Add/Subtract extended register 2676 let AddedComplexity = 1 in { 2677 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2678 arith_extended_reg32_i32, mnemonic, OpNode> { 2679 let Inst{31} = 0; 2680 } 2681 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2682 arith_extended_reg32_i64, mnemonic, OpNode> { 2683 let Inst{31} = 1; 2684 } 2685 } 2686 2687 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2688 arith_extendlsl64, mnemonic> { 2689 // UXTX and SXTX only. 2690 let Inst{14-13} = 0b11; 2691 let Inst{31} = 1; 2692 } 2693 } // Defs = [NZCV] 2694 2695 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2696 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2697 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2698 addsub_shifted_imm32_neg:$imm), 0>; 2699 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2700 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2701 addsub_shifted_imm64_neg:$imm), 0>; 2702 2703 // Compare aliases 2704 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2705 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2706 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2707 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2708 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2709 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2710 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2711 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2712 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2713 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2714 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2715 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2716 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2717 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2718 2719 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2720 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2721 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2722 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2723 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2724 2725 // Compare shorthands 2726 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2727 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2728 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2729 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2730 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2731 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2732 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2733 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2734 2735 // Register/register aliases with no shift when SP is not used. 2736 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2737 GPR32, GPR32, GPR32, 0>; 2738 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2739 GPR64, GPR64, GPR64, 0>; 2740 2741 // Register/register aliases with no shift when the first source register 2742 // is SP. 2743 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2744 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2745 def : AddSubRegAlias<mnemonic, 2746 !cast<Instruction>(NAME#"Xrx64"), 2747 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2748} 2749 2750class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2751 : BaseAddSubImm< 2752 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2753 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2754 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2755 bits<6> imm6; 2756 bits<4> imm4; 2757 let Inst{31} = 1; 2758 let Inst{23-22} = 0b10; 2759 let Inst{21-16} = imm6; 2760 let Inst{15-14} = 0b00; 2761 let Inst{13-10} = imm4; 2762 let Unpredictable{15-14} = 0b11; 2763} 2764 2765class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2766 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2767 let Inst{31} = 1; 2768 let Inst{29} = setsFlags; 2769} 2770 2771//--- 2772// Extract 2773//--- 2774def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2775 SDTCisPtrTy<3>]>; 2776def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2777 2778class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2779 list<dag> patterns> 2780 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2781 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2782 Sched<[WriteExtr, ReadExtrHi]> { 2783 bits<5> Rd; 2784 bits<5> Rn; 2785 bits<5> Rm; 2786 bits<6> imm; 2787 2788 let Inst{30-23} = 0b00100111; 2789 let Inst{21} = 0; 2790 let Inst{20-16} = Rm; 2791 let Inst{15-10} = imm; 2792 let Inst{9-5} = Rn; 2793 let Inst{4-0} = Rd; 2794} 2795 2796multiclass ExtractImm<string asm> { 2797 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2798 [(set GPR32:$Rd, 2799 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2800 let Inst{31} = 0; 2801 let Inst{22} = 0; 2802 // imm<5> must be zero. 2803 let imm{5} = 0; 2804 } 2805 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2806 [(set GPR64:$Rd, 2807 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2808 2809 let Inst{31} = 1; 2810 let Inst{22} = 1; 2811 } 2812} 2813 2814//--- 2815// Bitfield 2816//--- 2817 2818let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2819class BaseBitfieldImm<bits<2> opc, 2820 RegisterClass regtype, Operand imm_type, string asm> 2821 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2822 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2823 Sched<[WriteIS, ReadI]> { 2824 bits<5> Rd; 2825 bits<5> Rn; 2826 bits<6> immr; 2827 bits<6> imms; 2828 2829 let Inst{30-29} = opc; 2830 let Inst{28-23} = 0b100110; 2831 let Inst{21-16} = immr; 2832 let Inst{15-10} = imms; 2833 let Inst{9-5} = Rn; 2834 let Inst{4-0} = Rd; 2835} 2836 2837multiclass BitfieldImm<bits<2> opc, string asm> { 2838 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2839 let Inst{31} = 0; 2840 let Inst{22} = 0; 2841 // imms<5> and immr<5> must be zero, else ReservedValue(). 2842 let Inst{21} = 0; 2843 let Inst{15} = 0; 2844 } 2845 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2846 let Inst{31} = 1; 2847 let Inst{22} = 1; 2848 } 2849} 2850 2851let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2852class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2853 RegisterClass regtype, Operand imm_type, string asm> 2854 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2855 imm_type:$imms), 2856 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2857 Sched<[WriteIS, ReadI]> { 2858 bits<5> Rd; 2859 bits<5> Rn; 2860 bits<6> immr; 2861 bits<6> imms; 2862 2863 let Inst{30-29} = opc; 2864 let Inst{28-23} = 0b100110; 2865 let Inst{21-16} = immr; 2866 let Inst{15-10} = imms; 2867 let Inst{9-5} = Rn; 2868 let Inst{4-0} = Rd; 2869} 2870 2871multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2872 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2873 let Inst{31} = 0; 2874 let Inst{22} = 0; 2875 // imms<5> and immr<5> must be zero, else ReservedValue(). 2876 let Inst{21} = 0; 2877 let Inst{15} = 0; 2878 } 2879 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2880 let Inst{31} = 1; 2881 let Inst{22} = 1; 2882 } 2883} 2884 2885//--- 2886// Logical 2887//--- 2888 2889// Logical (immediate) 2890class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2891 RegisterClass sregtype, Operand imm_type, string asm, 2892 list<dag> pattern> 2893 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2894 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2895 Sched<[WriteI, ReadI]> { 2896 bits<5> Rd; 2897 bits<5> Rn; 2898 bits<13> imm; 2899 let Inst{30-29} = opc; 2900 let Inst{28-23} = 0b100100; 2901 let Inst{22} = imm{12}; 2902 let Inst{21-16} = imm{11-6}; 2903 let Inst{15-10} = imm{5-0}; 2904 let Inst{9-5} = Rn; 2905 let Inst{4-0} = Rd; 2906 2907 let DecoderMethod = "DecodeLogicalImmInstruction"; 2908} 2909 2910// Logical (shifted register) 2911class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2912 logical_shifted_reg shifted_regtype, string asm, 2913 list<dag> pattern> 2914 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2915 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2916 Sched<[WriteISReg, ReadI, ReadISReg]> { 2917 // The operands are in order to match the 'addr' MI operands, so we 2918 // don't need an encoder method and by-name matching. Just use the default 2919 // in-order handling. Since we're using by-order, make sure the names 2920 // do not match. 2921 bits<5> dst; 2922 bits<5> src1; 2923 bits<5> src2; 2924 bits<8> shift; 2925 let Inst{30-29} = opc; 2926 let Inst{28-24} = 0b01010; 2927 let Inst{23-22} = shift{7-6}; 2928 let Inst{21} = N; 2929 let Inst{20-16} = src2; 2930 let Inst{15-10} = shift{5-0}; 2931 let Inst{9-5} = src1; 2932 let Inst{4-0} = dst; 2933 2934 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2935} 2936 2937// Aliases for register+register logical instructions. 2938class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2939 : InstAlias<asm#"\t$dst, $src1, $src2", 2940 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2941 2942multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2943 string Alias> { 2944 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2945 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2946 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2947 logical_imm32:$imm))]> { 2948 let Inst{31} = 0; 2949 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2950 } 2951 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2952 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2953 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2954 logical_imm64:$imm))]> { 2955 let Inst{31} = 1; 2956 } 2957 2958 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2959 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2960 logical_imm32_not:$imm), 0>; 2961 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2962 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2963 logical_imm64_not:$imm), 0>; 2964} 2965 2966multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2967 string Alias> { 2968 let isCompare = 1, Defs = [NZCV] in { 2969 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2970 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2971 let Inst{31} = 0; 2972 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2973 } 2974 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2975 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2976 let Inst{31} = 1; 2977 } 2978 } // end Defs = [NZCV] 2979 2980 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2981 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2982 logical_imm32_not:$imm), 0>; 2983 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2984 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2985 logical_imm64_not:$imm), 0>; 2986} 2987 2988class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2989 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2990 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2991 Sched<[WriteI, ReadI, ReadI]>; 2992 2993// Split from LogicalImm as not all instructions have both. 2994multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2995 SDPatternOperator OpNode> { 2996 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2997 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2998 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2999 } 3000 3001 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3002 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3003 logical_shifted_reg32:$Rm))]> { 3004 let Inst{31} = 0; 3005 } 3006 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3007 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3008 logical_shifted_reg64:$Rm))]> { 3009 let Inst{31} = 1; 3010 } 3011 3012 def : LogicalRegAlias<mnemonic, 3013 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3014 def : LogicalRegAlias<mnemonic, 3015 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3016} 3017 3018// Split from LogicalReg to allow setting NZCV Defs 3019multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3020 SDPatternOperator OpNode = null_frag> { 3021 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3022 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3023 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3024 3025 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3026 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 3027 let Inst{31} = 0; 3028 } 3029 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3030 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 3031 let Inst{31} = 1; 3032 } 3033 } // Defs = [NZCV] 3034 3035 def : LogicalRegAlias<mnemonic, 3036 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3037 def : LogicalRegAlias<mnemonic, 3038 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3039} 3040 3041//--- 3042// Conditionally set flags 3043//--- 3044 3045let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3046class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3047 string mnemonic, SDNode OpNode> 3048 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3049 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3050 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3051 (i32 imm:$cond), NZCV))]>, 3052 Sched<[WriteI, ReadI]> { 3053 let Uses = [NZCV]; 3054 let Defs = [NZCV]; 3055 3056 bits<5> Rn; 3057 bits<5> imm; 3058 bits<4> nzcv; 3059 bits<4> cond; 3060 3061 let Inst{30} = op; 3062 let Inst{29-21} = 0b111010010; 3063 let Inst{20-16} = imm; 3064 let Inst{15-12} = cond; 3065 let Inst{11-10} = 0b10; 3066 let Inst{9-5} = Rn; 3067 let Inst{4} = 0b0; 3068 let Inst{3-0} = nzcv; 3069} 3070 3071let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3072class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3073 SDNode OpNode> 3074 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3075 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3076 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3077 (i32 imm:$cond), NZCV))]>, 3078 Sched<[WriteI, ReadI, ReadI]> { 3079 let Uses = [NZCV]; 3080 let Defs = [NZCV]; 3081 3082 bits<5> Rn; 3083 bits<5> Rm; 3084 bits<4> nzcv; 3085 bits<4> cond; 3086 3087 let Inst{30} = op; 3088 let Inst{29-21} = 0b111010010; 3089 let Inst{20-16} = Rm; 3090 let Inst{15-12} = cond; 3091 let Inst{11-10} = 0b00; 3092 let Inst{9-5} = Rn; 3093 let Inst{4} = 0b0; 3094 let Inst{3-0} = nzcv; 3095} 3096 3097multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3098 // immediate operand variants 3099 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3100 let Inst{31} = 0; 3101 } 3102 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3103 let Inst{31} = 1; 3104 } 3105 // register operand variants 3106 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3107 let Inst{31} = 0; 3108 } 3109 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3110 let Inst{31} = 1; 3111 } 3112} 3113 3114//--- 3115// Conditional select 3116//--- 3117 3118class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3119 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3120 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3121 [(set regtype:$Rd, 3122 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3123 Sched<[WriteI, ReadI, ReadI]> { 3124 let Uses = [NZCV]; 3125 3126 bits<5> Rd; 3127 bits<5> Rn; 3128 bits<5> Rm; 3129 bits<4> cond; 3130 3131 let Inst{30} = op; 3132 let Inst{29-21} = 0b011010100; 3133 let Inst{20-16} = Rm; 3134 let Inst{15-12} = cond; 3135 let Inst{11-10} = op2; 3136 let Inst{9-5} = Rn; 3137 let Inst{4-0} = Rd; 3138} 3139 3140multiclass CondSelect<bit op, bits<2> op2, string asm> { 3141 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3142 let Inst{31} = 0; 3143 } 3144 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3145 let Inst{31} = 1; 3146 } 3147} 3148 3149class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3150 PatFrag frag> 3151 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3152 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3153 [(set regtype:$Rd, 3154 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3155 (i32 imm:$cond), NZCV))]>, 3156 Sched<[WriteI, ReadI, ReadI]> { 3157 let Uses = [NZCV]; 3158 3159 bits<5> Rd; 3160 bits<5> Rn; 3161 bits<5> Rm; 3162 bits<4> cond; 3163 3164 let Inst{30} = op; 3165 let Inst{29-21} = 0b011010100; 3166 let Inst{20-16} = Rm; 3167 let Inst{15-12} = cond; 3168 let Inst{11-10} = op2; 3169 let Inst{9-5} = Rn; 3170 let Inst{4-0} = Rd; 3171} 3172 3173def inv_cond_XFORM : SDNodeXForm<imm, [{ 3174 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3175 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3176 MVT::i32); 3177}]>; 3178 3179multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3180 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3181 let Inst{31} = 0; 3182 } 3183 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3184 let Inst{31} = 1; 3185 } 3186 3187 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3188 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3189 (inv_cond_XFORM imm:$cond))>; 3190 3191 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3192 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3193 (inv_cond_XFORM imm:$cond))>; 3194} 3195 3196//--- 3197// Special Mask Value 3198//--- 3199def maski8_or_more : Operand<i32>, 3200 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3201} 3202def maski16_or_more : Operand<i32>, 3203 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3204} 3205 3206 3207//--- 3208// Load/store 3209//--- 3210 3211// (unsigned immediate) 3212// Indexed for 8-bit registers. offset is in range [0,4095]. 3213def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3214def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3215def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3216def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3217def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3218 3219// (unsigned immediate) 3220// Indexed for 8-bit registers. offset is in range [0,63]. 3221def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3222def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3223def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3224def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3225 3226def gi_am_indexed8 : 3227 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3228 GIComplexPatternEquiv<am_indexed8>; 3229def gi_am_indexed16 : 3230 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3231 GIComplexPatternEquiv<am_indexed16>; 3232def gi_am_indexed32 : 3233 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3234 GIComplexPatternEquiv<am_indexed32>; 3235def gi_am_indexed64 : 3236 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3237 GIComplexPatternEquiv<am_indexed64>; 3238def gi_am_indexed128 : 3239 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3240 GIComplexPatternEquiv<am_indexed128>; 3241 3242class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3243 let Name = "UImm12Offset" # Scale; 3244 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3245 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3246 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3247} 3248 3249def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3250def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3251def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3252def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3253def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3254 3255class uimm12_scaled<int Scale> : Operand<i64> { 3256 let ParserMatchClass 3257 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3258 let EncoderMethod 3259 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3260 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3261} 3262 3263def uimm12s1 : uimm12_scaled<1>; 3264def uimm12s2 : uimm12_scaled<2>; 3265def uimm12s4 : uimm12_scaled<4>; 3266def uimm12s8 : uimm12_scaled<8>; 3267def uimm12s16 : uimm12_scaled<16>; 3268 3269class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3270 string asm, list<dag> pattern> 3271 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3272 bits<5> Rt; 3273 3274 bits<5> Rn; 3275 bits<12> offset; 3276 3277 let Inst{31-30} = sz; 3278 let Inst{29-27} = 0b111; 3279 let Inst{26} = V; 3280 let Inst{25-24} = 0b01; 3281 let Inst{23-22} = opc; 3282 let Inst{21-10} = offset; 3283 let Inst{9-5} = Rn; 3284 let Inst{4-0} = Rt; 3285 3286 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3287} 3288 3289multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3290 Operand indextype, string asm, list<dag> pattern> { 3291 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3292 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3293 (ins GPR64sp:$Rn, indextype:$offset), 3294 asm, pattern>, 3295 Sched<[WriteLD]>; 3296 3297 def : InstAlias<asm # "\t$Rt, [$Rn]", 3298 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3299} 3300 3301multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3302 Operand indextype, string asm, list<dag> pattern> { 3303 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3304 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3305 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3306 asm, pattern>, 3307 Sched<[WriteST]>; 3308 3309 def : InstAlias<asm # "\t$Rt, [$Rn]", 3310 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3311} 3312 3313// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3314// substitute zero-registers automatically. 3315// 3316// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3317// into StoreUI. 3318multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3319 Operand indextype, string asm, list<dag> pattern> { 3320 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3321 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3322 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3323 asm, pattern>, 3324 Sched<[WriteST]>; 3325 3326 def : InstAlias<asm # "\t$Rt, [$Rn]", 3327 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3328} 3329 3330def PrefetchOperand : AsmOperandClass { 3331 let Name = "Prefetch"; 3332 let ParserMethod = "tryParsePrefetch"; 3333} 3334def prfop : Operand<i32> { 3335 let PrintMethod = "printPrefetchOp"; 3336 let ParserMatchClass = PrefetchOperand; 3337} 3338 3339let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3340class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3341 : BaseLoadStoreUI<sz, V, opc, 3342 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3343 asm, pat>, 3344 Sched<[WriteLD]>; 3345 3346//--- 3347// Load literal 3348//--- 3349 3350// Load literal address: 19-bit immediate. The low two bits of the target 3351// offset are implied zero and so are not part of the immediate. 3352def am_ldrlit : Operand<iPTR> { 3353 let EncoderMethod = "getLoadLiteralOpValue"; 3354 let DecoderMethod = "DecodePCRelLabel19"; 3355 let PrintMethod = "printAlignedLabel"; 3356 let ParserMatchClass = PCRelLabel19Operand; 3357 let OperandType = "OPERAND_PCREL"; 3358} 3359 3360let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3361class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3362 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3363 asm, "\t$Rt, $label", "", pat>, 3364 Sched<[WriteLD]> { 3365 bits<5> Rt; 3366 bits<19> label; 3367 let Inst{31-30} = opc; 3368 let Inst{29-27} = 0b011; 3369 let Inst{26} = V; 3370 let Inst{25-24} = 0b00; 3371 let Inst{23-5} = label; 3372 let Inst{4-0} = Rt; 3373} 3374 3375let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3376class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3377 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3378 asm, "\t$Rt, $label", "", pat>, 3379 Sched<[WriteLD]> { 3380 bits<5> Rt; 3381 bits<19> label; 3382 let Inst{31-30} = opc; 3383 let Inst{29-27} = 0b011; 3384 let Inst{26} = V; 3385 let Inst{25-24} = 0b00; 3386 let Inst{23-5} = label; 3387 let Inst{4-0} = Rt; 3388} 3389 3390//--- 3391// Load/store register offset 3392//--- 3393 3394def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3395def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3396def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3397def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3398def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3399 3400def gi_ro_Xindexed8 : 3401 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3402 GIComplexPatternEquiv<ro_Xindexed8>; 3403def gi_ro_Xindexed16 : 3404 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3405 GIComplexPatternEquiv<ro_Xindexed16>; 3406def gi_ro_Xindexed32 : 3407 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3408 GIComplexPatternEquiv<ro_Xindexed32>; 3409def gi_ro_Xindexed64 : 3410 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3411 GIComplexPatternEquiv<ro_Xindexed64>; 3412def gi_ro_Xindexed128 : 3413 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3414 GIComplexPatternEquiv<ro_Xindexed128>; 3415 3416def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3417def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3418def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3419def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3420def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3421 3422def gi_ro_Windexed8 : 3423 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3424 GIComplexPatternEquiv<ro_Windexed8>; 3425def gi_ro_Windexed16 : 3426 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3427 GIComplexPatternEquiv<ro_Windexed16>; 3428def gi_ro_Windexed32 : 3429 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3430 GIComplexPatternEquiv<ro_Windexed32>; 3431def gi_ro_Windexed64 : 3432 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3433 GIComplexPatternEquiv<ro_Windexed64>; 3434def gi_ro_Windexed128 : 3435 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3436 GIComplexPatternEquiv<ro_Windexed128>; 3437 3438class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3439 let Name = "Mem" # Reg # "Extend" # Width; 3440 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3441 let RenderMethod = "addMemExtendOperands"; 3442 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3443} 3444 3445def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3446 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3447 // the trivial shift. 3448 let RenderMethod = "addMemExtend8Operands"; 3449} 3450def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3451def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3452def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3453def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3454 3455def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3456 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3457 // the trivial shift. 3458 let RenderMethod = "addMemExtend8Operands"; 3459} 3460def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3461def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3462def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3463def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3464 3465class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3466 : Operand<i32> { 3467 let ParserMatchClass = ParserClass; 3468 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3469 let DecoderMethod = "DecodeMemExtend"; 3470 let EncoderMethod = "getMemExtendOpValue"; 3471 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3472} 3473 3474def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3475def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3476def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3477def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3478def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3479 3480def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3481def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3482def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3483def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3484def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3485 3486class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3487 Operand wextend, Operand xextend> { 3488 // CodeGen-level pattern covering the entire addressing mode. 3489 ComplexPattern Wpat = windex; 3490 ComplexPattern Xpat = xindex; 3491 3492 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3493 Operand Wext = wextend; 3494 Operand Xext = xextend; 3495} 3496 3497def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3498def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3499def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3500def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3501def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3502 ro_Xextend128>; 3503 3504class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3505 dag outs, list<dag> pat> 3506 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3507 bits<5> Rt; 3508 bits<5> Rn; 3509 bits<5> Rm; 3510 bits<2> extend; 3511 let Inst{31-30} = sz; 3512 let Inst{29-27} = 0b111; 3513 let Inst{26} = V; 3514 let Inst{25-24} = 0b00; 3515 let Inst{23-22} = opc; 3516 let Inst{21} = 1; 3517 let Inst{20-16} = Rm; 3518 let Inst{15} = extend{1}; // sign extend Rm? 3519 let Inst{14} = 1; 3520 let Inst{12} = extend{0}; // do shift? 3521 let Inst{11-10} = 0b10; 3522 let Inst{9-5} = Rn; 3523 let Inst{4-0} = Rt; 3524} 3525 3526class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3527 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3528 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3529 3530multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3531 string asm, ValueType Ty, SDPatternOperator loadop> { 3532 let AddedComplexity = 10 in 3533 def roW : LoadStore8RO<sz, V, opc, asm, 3534 (outs regtype:$Rt), 3535 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3536 [(set (Ty regtype:$Rt), 3537 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3538 ro_Wextend8:$extend)))]>, 3539 Sched<[WriteLDIdx, ReadAdrBase]> { 3540 let Inst{13} = 0b0; 3541 } 3542 3543 let AddedComplexity = 10 in 3544 def roX : LoadStore8RO<sz, V, opc, asm, 3545 (outs regtype:$Rt), 3546 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3547 [(set (Ty regtype:$Rt), 3548 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3549 ro_Xextend8:$extend)))]>, 3550 Sched<[WriteLDIdx, ReadAdrBase]> { 3551 let Inst{13} = 0b1; 3552 } 3553 3554 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3555} 3556 3557multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3558 string asm, ValueType Ty, SDPatternOperator storeop> { 3559 let AddedComplexity = 10 in 3560 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3561 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3562 [(storeop (Ty regtype:$Rt), 3563 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3564 ro_Wextend8:$extend))]>, 3565 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3566 let Inst{13} = 0b0; 3567 } 3568 3569 let AddedComplexity = 10 in 3570 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3571 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3572 [(storeop (Ty regtype:$Rt), 3573 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3574 ro_Xextend8:$extend))]>, 3575 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3576 let Inst{13} = 0b1; 3577 } 3578 3579 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3580} 3581 3582class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3583 dag outs, list<dag> pat> 3584 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3585 bits<5> Rt; 3586 bits<5> Rn; 3587 bits<5> Rm; 3588 bits<2> extend; 3589 let Inst{31-30} = sz; 3590 let Inst{29-27} = 0b111; 3591 let Inst{26} = V; 3592 let Inst{25-24} = 0b00; 3593 let Inst{23-22} = opc; 3594 let Inst{21} = 1; 3595 let Inst{20-16} = Rm; 3596 let Inst{15} = extend{1}; // sign extend Rm? 3597 let Inst{14} = 1; 3598 let Inst{12} = extend{0}; // do shift? 3599 let Inst{11-10} = 0b10; 3600 let Inst{9-5} = Rn; 3601 let Inst{4-0} = Rt; 3602} 3603 3604multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3605 string asm, ValueType Ty, SDPatternOperator loadop> { 3606 let AddedComplexity = 10 in 3607 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3608 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3609 [(set (Ty regtype:$Rt), 3610 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3611 ro_Wextend16:$extend)))]>, 3612 Sched<[WriteLDIdx, ReadAdrBase]> { 3613 let Inst{13} = 0b0; 3614 } 3615 3616 let AddedComplexity = 10 in 3617 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3618 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3619 [(set (Ty regtype:$Rt), 3620 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3621 ro_Xextend16:$extend)))]>, 3622 Sched<[WriteLDIdx, ReadAdrBase]> { 3623 let Inst{13} = 0b1; 3624 } 3625 3626 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3627} 3628 3629multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3630 string asm, ValueType Ty, SDPatternOperator storeop> { 3631 let AddedComplexity = 10 in 3632 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3633 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3634 [(storeop (Ty regtype:$Rt), 3635 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3636 ro_Wextend16:$extend))]>, 3637 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3638 let Inst{13} = 0b0; 3639 } 3640 3641 let AddedComplexity = 10 in 3642 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3643 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3644 [(storeop (Ty regtype:$Rt), 3645 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3646 ro_Xextend16:$extend))]>, 3647 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3648 let Inst{13} = 0b1; 3649 } 3650 3651 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3652} 3653 3654class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3655 dag outs, list<dag> pat> 3656 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3657 bits<5> Rt; 3658 bits<5> Rn; 3659 bits<5> Rm; 3660 bits<2> extend; 3661 let Inst{31-30} = sz; 3662 let Inst{29-27} = 0b111; 3663 let Inst{26} = V; 3664 let Inst{25-24} = 0b00; 3665 let Inst{23-22} = opc; 3666 let Inst{21} = 1; 3667 let Inst{20-16} = Rm; 3668 let Inst{15} = extend{1}; // sign extend Rm? 3669 let Inst{14} = 1; 3670 let Inst{12} = extend{0}; // do shift? 3671 let Inst{11-10} = 0b10; 3672 let Inst{9-5} = Rn; 3673 let Inst{4-0} = Rt; 3674} 3675 3676multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3677 string asm, ValueType Ty, SDPatternOperator loadop> { 3678 let AddedComplexity = 10 in 3679 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3680 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3681 [(set (Ty regtype:$Rt), 3682 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3683 ro_Wextend32:$extend)))]>, 3684 Sched<[WriteLDIdx, ReadAdrBase]> { 3685 let Inst{13} = 0b0; 3686 } 3687 3688 let AddedComplexity = 10 in 3689 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3690 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3691 [(set (Ty regtype:$Rt), 3692 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3693 ro_Xextend32:$extend)))]>, 3694 Sched<[WriteLDIdx, ReadAdrBase]> { 3695 let Inst{13} = 0b1; 3696 } 3697 3698 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3699} 3700 3701multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3702 string asm, ValueType Ty, SDPatternOperator storeop> { 3703 let AddedComplexity = 10 in 3704 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 3705 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3706 [(storeop (Ty regtype:$Rt), 3707 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3708 ro_Wextend32:$extend))]>, 3709 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3710 let Inst{13} = 0b0; 3711 } 3712 3713 let AddedComplexity = 10 in 3714 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 3715 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3716 [(storeop (Ty regtype:$Rt), 3717 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3718 ro_Xextend32:$extend))]>, 3719 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3720 let Inst{13} = 0b1; 3721 } 3722 3723 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3724} 3725 3726class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3727 dag outs, list<dag> pat> 3728 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3729 bits<5> Rt; 3730 bits<5> Rn; 3731 bits<5> Rm; 3732 bits<2> extend; 3733 let Inst{31-30} = sz; 3734 let Inst{29-27} = 0b111; 3735 let Inst{26} = V; 3736 let Inst{25-24} = 0b00; 3737 let Inst{23-22} = opc; 3738 let Inst{21} = 1; 3739 let Inst{20-16} = Rm; 3740 let Inst{15} = extend{1}; // sign extend Rm? 3741 let Inst{14} = 1; 3742 let Inst{12} = extend{0}; // do shift? 3743 let Inst{11-10} = 0b10; 3744 let Inst{9-5} = Rn; 3745 let Inst{4-0} = Rt; 3746} 3747 3748multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3749 string asm, ValueType Ty, SDPatternOperator loadop> { 3750 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3751 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3752 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3753 [(set (Ty regtype:$Rt), 3754 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3755 ro_Wextend64:$extend)))]>, 3756 Sched<[WriteLDIdx, ReadAdrBase]> { 3757 let Inst{13} = 0b0; 3758 } 3759 3760 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3761 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3762 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3763 [(set (Ty regtype:$Rt), 3764 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3765 ro_Xextend64:$extend)))]>, 3766 Sched<[WriteLDIdx, ReadAdrBase]> { 3767 let Inst{13} = 0b1; 3768 } 3769 3770 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3771} 3772 3773multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3774 string asm, ValueType Ty, SDPatternOperator storeop> { 3775 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3776 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 3777 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3778 [(storeop (Ty regtype:$Rt), 3779 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3780 ro_Wextend64:$extend))]>, 3781 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3782 let Inst{13} = 0b0; 3783 } 3784 3785 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3786 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 3787 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3788 [(storeop (Ty regtype:$Rt), 3789 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3790 ro_Xextend64:$extend))]>, 3791 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3792 let Inst{13} = 0b1; 3793 } 3794 3795 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3796} 3797 3798class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3799 dag outs, list<dag> pat> 3800 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3801 bits<5> Rt; 3802 bits<5> Rn; 3803 bits<5> Rm; 3804 bits<2> extend; 3805 let Inst{31-30} = sz; 3806 let Inst{29-27} = 0b111; 3807 let Inst{26} = V; 3808 let Inst{25-24} = 0b00; 3809 let Inst{23-22} = opc; 3810 let Inst{21} = 1; 3811 let Inst{20-16} = Rm; 3812 let Inst{15} = extend{1}; // sign extend Rm? 3813 let Inst{14} = 1; 3814 let Inst{12} = extend{0}; // do shift? 3815 let Inst{11-10} = 0b10; 3816 let Inst{9-5} = Rn; 3817 let Inst{4-0} = Rt; 3818} 3819 3820multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3821 string asm, ValueType Ty, SDPatternOperator loadop> { 3822 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3823 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3824 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3825 [(set (Ty regtype:$Rt), 3826 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3827 ro_Wextend128:$extend)))]>, 3828 Sched<[WriteLDIdx, ReadAdrBase]> { 3829 let Inst{13} = 0b0; 3830 } 3831 3832 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3833 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3834 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3835 [(set (Ty regtype:$Rt), 3836 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3837 ro_Xextend128:$extend)))]>, 3838 Sched<[WriteLDIdx, ReadAdrBase]> { 3839 let Inst{13} = 0b1; 3840 } 3841 3842 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3843} 3844 3845multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3846 string asm> { 3847 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3848 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 3849 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3850 []>, 3851 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3852 let Inst{13} = 0b0; 3853 } 3854 3855 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3856 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 3857 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3858 []>, 3859 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3860 let Inst{13} = 0b1; 3861 } 3862 3863 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3864} 3865 3866let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3867class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3868 string asm, list<dag> pat> 3869 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3870 Sched<[WriteLD]> { 3871 bits<5> Rt; 3872 bits<5> Rn; 3873 bits<5> Rm; 3874 bits<2> extend; 3875 let Inst{31-30} = sz; 3876 let Inst{29-27} = 0b111; 3877 let Inst{26} = V; 3878 let Inst{25-24} = 0b00; 3879 let Inst{23-22} = opc; 3880 let Inst{21} = 1; 3881 let Inst{20-16} = Rm; 3882 let Inst{15} = extend{1}; // sign extend Rm? 3883 let Inst{14} = 1; 3884 let Inst{12} = extend{0}; // do shift? 3885 let Inst{11-10} = 0b10; 3886 let Inst{9-5} = Rn; 3887 let Inst{4-0} = Rt; 3888} 3889 3890multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3891 def roW : BasePrefetchRO<sz, V, opc, (outs), 3892 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3893 asm, [(AArch64Prefetch imm:$Rt, 3894 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3895 ro_Wextend64:$extend))]> { 3896 let Inst{13} = 0b0; 3897 } 3898 3899 def roX : BasePrefetchRO<sz, V, opc, (outs), 3900 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3901 asm, [(AArch64Prefetch imm:$Rt, 3902 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3903 ro_Xextend64:$extend))]> { 3904 let Inst{13} = 0b1; 3905 } 3906 3907 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3908 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3909 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3910} 3911 3912//--- 3913// Load/store unscaled immediate 3914//--- 3915 3916def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 3917def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 3918def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 3919def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 3920def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 3921 3922def gi_am_unscaled8 : 3923 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3924 GIComplexPatternEquiv<am_unscaled8>; 3925def gi_am_unscaled16 : 3926 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3927 GIComplexPatternEquiv<am_unscaled16>; 3928def gi_am_unscaled32 : 3929 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3930 GIComplexPatternEquiv<am_unscaled32>; 3931def gi_am_unscaled64 : 3932 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3933 GIComplexPatternEquiv<am_unscaled64>; 3934def gi_am_unscaled128 : 3935 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3936 GIComplexPatternEquiv<am_unscaled128>; 3937 3938 3939class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3940 string asm, list<dag> pattern> 3941 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3942 bits<5> Rt; 3943 bits<5> Rn; 3944 bits<9> offset; 3945 let Inst{31-30} = sz; 3946 let Inst{29-27} = 0b111; 3947 let Inst{26} = V; 3948 let Inst{25-24} = 0b00; 3949 let Inst{23-22} = opc; 3950 let Inst{21} = 0; 3951 let Inst{20-12} = offset; 3952 let Inst{11-10} = 0b00; 3953 let Inst{9-5} = Rn; 3954 let Inst{4-0} = Rt; 3955 3956 let DecoderMethod = "DecodeSignedLdStInstruction"; 3957} 3958 3959// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3960multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3961 DAGOperand regtype > { 3962 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3963 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3964 Sched<[WriteST]> { 3965 let Inst{29} = 0; 3966 let Inst{24} = 1; 3967 } 3968 def : InstAlias<asm # "\t$Rt, [$Rn]", 3969 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3970} 3971 3972multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3973 DAGOperand regtype > { 3974 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3975 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3976 asm, []>, 3977 Sched<[WriteST]> { 3978 let Inst{29} = 0; 3979 let Inst{24} = 1; 3980 } 3981 def : InstAlias<asm # "\t$Rt, [$Rn]", 3982 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3983} 3984 3985multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3986 string asm, list<dag> pattern> { 3987 let AddedComplexity = 1 in // try this before LoadUI 3988 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3989 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3990 Sched<[WriteLD]>; 3991 3992 def : InstAlias<asm # "\t$Rt, [$Rn]", 3993 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3994} 3995 3996multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3997 string asm, list<dag> pattern> { 3998 let AddedComplexity = 1 in // try this before StoreUI 3999 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4000 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4001 asm, pattern>, 4002 Sched<[WriteST]>; 4003 4004 def : InstAlias<asm # "\t$Rt, [$Rn]", 4005 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4006} 4007 4008multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4009 list<dag> pat> { 4010 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4011 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4012 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4013 asm, pat>, 4014 Sched<[WriteLD]>; 4015 4016 def : InstAlias<asm # "\t$Rt, [$Rn]", 4017 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4018} 4019 4020//--- 4021// Load/store unscaled immediate, unprivileged 4022//--- 4023 4024class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4025 dag oops, dag iops, string asm> 4026 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4027 bits<5> Rt; 4028 bits<5> Rn; 4029 bits<9> offset; 4030 let Inst{31-30} = sz; 4031 let Inst{29-27} = 0b111; 4032 let Inst{26} = V; 4033 let Inst{25-24} = 0b00; 4034 let Inst{23-22} = opc; 4035 let Inst{21} = 0; 4036 let Inst{20-12} = offset; 4037 let Inst{11-10} = 0b10; 4038 let Inst{9-5} = Rn; 4039 let Inst{4-0} = Rt; 4040 4041 let DecoderMethod = "DecodeSignedLdStInstruction"; 4042} 4043 4044multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4045 RegisterClass regtype, string asm> { 4046 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4047 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4048 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4049 Sched<[WriteLD]>; 4050 4051 def : InstAlias<asm # "\t$Rt, [$Rn]", 4052 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4053} 4054 4055multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4056 RegisterClass regtype, string asm> { 4057 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4058 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4059 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4060 asm>, 4061 Sched<[WriteST]>; 4062 4063 def : InstAlias<asm # "\t$Rt, [$Rn]", 4064 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4065} 4066 4067//--- 4068// Load/store pre-indexed 4069//--- 4070 4071class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4072 string asm, string cstr, list<dag> pat> 4073 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4074 bits<5> Rt; 4075 bits<5> Rn; 4076 bits<9> offset; 4077 let Inst{31-30} = sz; 4078 let Inst{29-27} = 0b111; 4079 let Inst{26} = V; 4080 let Inst{25-24} = 0; 4081 let Inst{23-22} = opc; 4082 let Inst{21} = 0; 4083 let Inst{20-12} = offset; 4084 let Inst{11-10} = 0b11; 4085 let Inst{9-5} = Rn; 4086 let Inst{4-0} = Rt; 4087 4088 let DecoderMethod = "DecodeSignedLdStInstruction"; 4089} 4090 4091let hasSideEffects = 0 in { 4092let mayStore = 0, mayLoad = 1 in 4093class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4094 string asm> 4095 : BaseLoadStorePreIdx<sz, V, opc, 4096 (outs GPR64sp:$wback, regtype:$Rt), 4097 (ins GPR64sp:$Rn, simm9:$offset), asm, 4098 "$Rn = $wback,@earlyclobber $wback", []>, 4099 Sched<[WriteAdr, WriteLD]>; 4100 4101let mayStore = 1, mayLoad = 0 in 4102class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4103 string asm, SDPatternOperator storeop, ValueType Ty> 4104 : BaseLoadStorePreIdx<sz, V, opc, 4105 (outs GPR64sp:$wback), 4106 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4107 asm, "$Rn = $wback,@earlyclobber $wback", 4108 [(set GPR64sp:$wback, 4109 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4110 Sched<[WriteAdr, WriteST]>; 4111} // hasSideEffects = 0 4112 4113//--- 4114// Load/store post-indexed 4115//--- 4116 4117class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4118 string asm, string cstr, list<dag> pat> 4119 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4120 bits<5> Rt; 4121 bits<5> Rn; 4122 bits<9> offset; 4123 let Inst{31-30} = sz; 4124 let Inst{29-27} = 0b111; 4125 let Inst{26} = V; 4126 let Inst{25-24} = 0b00; 4127 let Inst{23-22} = opc; 4128 let Inst{21} = 0b0; 4129 let Inst{20-12} = offset; 4130 let Inst{11-10} = 0b01; 4131 let Inst{9-5} = Rn; 4132 let Inst{4-0} = Rt; 4133 4134 let DecoderMethod = "DecodeSignedLdStInstruction"; 4135} 4136 4137let hasSideEffects = 0 in { 4138let mayStore = 0, mayLoad = 1 in 4139class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4140 string asm> 4141 : BaseLoadStorePostIdx<sz, V, opc, 4142 (outs GPR64sp:$wback, regtype:$Rt), 4143 (ins GPR64sp:$Rn, simm9:$offset), 4144 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4145 Sched<[WriteAdr, WriteLD]>; 4146 4147let mayStore = 1, mayLoad = 0 in 4148class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4149 string asm, SDPatternOperator storeop, ValueType Ty> 4150 : BaseLoadStorePostIdx<sz, V, opc, 4151 (outs GPR64sp:$wback), 4152 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4153 asm, "$Rn = $wback,@earlyclobber $wback", 4154 [(set GPR64sp:$wback, 4155 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4156 Sched<[WriteAdr, WriteST]>; 4157} // hasSideEffects = 0 4158 4159 4160//--- 4161// Load/store pair 4162//--- 4163 4164// (indexed, offset) 4165 4166class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4167 string asm> 4168 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4169 bits<5> Rt; 4170 bits<5> Rt2; 4171 bits<5> Rn; 4172 bits<7> offset; 4173 let Inst{31-30} = opc; 4174 let Inst{29-27} = 0b101; 4175 let Inst{26} = V; 4176 let Inst{25-23} = 0b010; 4177 let Inst{22} = L; 4178 let Inst{21-15} = offset; 4179 let Inst{14-10} = Rt2; 4180 let Inst{9-5} = Rn; 4181 let Inst{4-0} = Rt; 4182 4183 let DecoderMethod = "DecodePairLdStInstruction"; 4184} 4185 4186multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4187 Operand indextype, string asm> { 4188 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4189 def i : BaseLoadStorePairOffset<opc, V, 1, 4190 (outs regtype:$Rt, regtype:$Rt2), 4191 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4192 Sched<[WriteLD, WriteLDHi]>; 4193 4194 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4195 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4196 GPR64sp:$Rn, 0)>; 4197} 4198 4199 4200multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4201 Operand indextype, string asm> { 4202 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4203 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4204 (ins regtype:$Rt, regtype:$Rt2, 4205 GPR64sp:$Rn, indextype:$offset), 4206 asm>, 4207 Sched<[WriteSTP]>; 4208 4209 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4210 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4211 GPR64sp:$Rn, 0)>; 4212} 4213 4214// (pre-indexed) 4215class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4216 string asm> 4217 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4218 bits<5> Rt; 4219 bits<5> Rt2; 4220 bits<5> Rn; 4221 bits<7> offset; 4222 let Inst{31-30} = opc; 4223 let Inst{29-27} = 0b101; 4224 let Inst{26} = V; 4225 let Inst{25-23} = 0b011; 4226 let Inst{22} = L; 4227 let Inst{21-15} = offset; 4228 let Inst{14-10} = Rt2; 4229 let Inst{9-5} = Rn; 4230 let Inst{4-0} = Rt; 4231 4232 let DecoderMethod = "DecodePairLdStInstruction"; 4233} 4234 4235let hasSideEffects = 0 in { 4236let mayStore = 0, mayLoad = 1 in 4237class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4238 Operand indextype, string asm> 4239 : BaseLoadStorePairPreIdx<opc, V, 1, 4240 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4241 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4242 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4243 4244let mayStore = 1, mayLoad = 0 in 4245class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4246 Operand indextype, string asm> 4247 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4248 (ins regtype:$Rt, regtype:$Rt2, 4249 GPR64sp:$Rn, indextype:$offset), 4250 asm>, 4251 Sched<[WriteAdr, WriteSTP]>; 4252} // hasSideEffects = 0 4253 4254// (post-indexed) 4255 4256class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4257 string asm> 4258 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4259 bits<5> Rt; 4260 bits<5> Rt2; 4261 bits<5> Rn; 4262 bits<7> offset; 4263 let Inst{31-30} = opc; 4264 let Inst{29-27} = 0b101; 4265 let Inst{26} = V; 4266 let Inst{25-23} = 0b001; 4267 let Inst{22} = L; 4268 let Inst{21-15} = offset; 4269 let Inst{14-10} = Rt2; 4270 let Inst{9-5} = Rn; 4271 let Inst{4-0} = Rt; 4272 4273 let DecoderMethod = "DecodePairLdStInstruction"; 4274} 4275 4276let hasSideEffects = 0 in { 4277let mayStore = 0, mayLoad = 1 in 4278class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4279 Operand idxtype, string asm> 4280 : BaseLoadStorePairPostIdx<opc, V, 1, 4281 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4282 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4283 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4284 4285let mayStore = 1, mayLoad = 0 in 4286class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4287 Operand idxtype, string asm> 4288 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4289 (ins regtype:$Rt, regtype:$Rt2, 4290 GPR64sp:$Rn, idxtype:$offset), 4291 asm>, 4292 Sched<[WriteAdr, WriteSTP]>; 4293} // hasSideEffects = 0 4294 4295// (no-allocate) 4296 4297class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4298 string asm> 4299 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4300 bits<5> Rt; 4301 bits<5> Rt2; 4302 bits<5> Rn; 4303 bits<7> offset; 4304 let Inst{31-30} = opc; 4305 let Inst{29-27} = 0b101; 4306 let Inst{26} = V; 4307 let Inst{25-23} = 0b000; 4308 let Inst{22} = L; 4309 let Inst{21-15} = offset; 4310 let Inst{14-10} = Rt2; 4311 let Inst{9-5} = Rn; 4312 let Inst{4-0} = Rt; 4313 4314 let DecoderMethod = "DecodePairLdStInstruction"; 4315} 4316 4317multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4318 Operand indextype, string asm> { 4319 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4320 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4321 (outs regtype:$Rt, regtype:$Rt2), 4322 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4323 Sched<[WriteLD, WriteLDHi]>; 4324 4325 4326 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4327 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4328 GPR64sp:$Rn, 0)>; 4329} 4330 4331multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4332 Operand indextype, string asm> { 4333 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4334 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4335 (ins regtype:$Rt, regtype:$Rt2, 4336 GPR64sp:$Rn, indextype:$offset), 4337 asm>, 4338 Sched<[WriteSTP]>; 4339 4340 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4341 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4342 GPR64sp:$Rn, 0)>; 4343} 4344 4345//--- 4346// Load/store exclusive 4347//--- 4348 4349// True exclusive operations write to and/or read from the system's exclusive 4350// monitors, which as far as a compiler is concerned can be modelled as a 4351// random shared memory address. Hence LoadExclusive mayStore. 4352// 4353// Since these instructions have the undefined register bits set to 1 in 4354// their canonical form, we need a post encoder method to set those bits 4355// to 1 when encoding these instructions. We do this using the 4356// fixLoadStoreExclusive function. This function has template parameters: 4357// 4358// fixLoadStoreExclusive<int hasRs, int hasRt2> 4359// 4360// hasRs indicates that the instruction uses the Rs field, so we won't set 4361// it to 1 (and the same for Rt2). We don't need template parameters for 4362// the other register fields since Rt and Rn are always used. 4363// 4364let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4365class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4366 dag oops, dag iops, string asm, string operands> 4367 : I<oops, iops, asm, operands, "", []> { 4368 let Inst{31-30} = sz; 4369 let Inst{29-24} = 0b001000; 4370 let Inst{23} = o2; 4371 let Inst{22} = L; 4372 let Inst{21} = o1; 4373 let Inst{15} = o0; 4374 4375 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4376} 4377 4378// Neither Rs nor Rt2 operands. 4379class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4380 dag oops, dag iops, string asm, string operands> 4381 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4382 bits<5> Rt; 4383 bits<5> Rn; 4384 let Inst{20-16} = 0b11111; 4385 let Unpredictable{20-16} = 0b11111; 4386 let Inst{14-10} = 0b11111; 4387 let Unpredictable{14-10} = 0b11111; 4388 let Inst{9-5} = Rn; 4389 let Inst{4-0} = Rt; 4390 4391 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4392} 4393 4394// Simple load acquires don't set the exclusive monitor 4395let mayLoad = 1, mayStore = 0 in 4396class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4397 RegisterClass regtype, string asm> 4398 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4399 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4400 Sched<[WriteLD]>; 4401 4402class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4403 RegisterClass regtype, string asm> 4404 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4405 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4406 Sched<[WriteLD]>; 4407 4408class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4409 RegisterClass regtype, string asm> 4410 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4411 (outs regtype:$Rt, regtype:$Rt2), 4412 (ins GPR64sp0:$Rn), asm, 4413 "\t$Rt, $Rt2, [$Rn]">, 4414 Sched<[WriteLD, WriteLDHi]> { 4415 bits<5> Rt; 4416 bits<5> Rt2; 4417 bits<5> Rn; 4418 let Inst{14-10} = Rt2; 4419 let Inst{9-5} = Rn; 4420 let Inst{4-0} = Rt; 4421 4422 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4423} 4424 4425// Simple store release operations do not check the exclusive monitor. 4426let mayLoad = 0, mayStore = 1 in 4427class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4428 RegisterClass regtype, string asm> 4429 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4430 (ins regtype:$Rt, GPR64sp0:$Rn), 4431 asm, "\t$Rt, [$Rn]">, 4432 Sched<[WriteST]>; 4433 4434let mayLoad = 1, mayStore = 1 in 4435class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4436 RegisterClass regtype, string asm> 4437 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4438 (ins regtype:$Rt, GPR64sp0:$Rn), 4439 asm, "\t$Ws, $Rt, [$Rn]">, 4440 Sched<[WriteSTX]> { 4441 bits<5> Ws; 4442 bits<5> Rt; 4443 bits<5> Rn; 4444 let Inst{20-16} = Ws; 4445 let Inst{9-5} = Rn; 4446 let Inst{4-0} = Rt; 4447 4448 let Constraints = "@earlyclobber $Ws"; 4449 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4450} 4451 4452class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4453 RegisterClass regtype, string asm> 4454 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4455 (outs GPR32:$Ws), 4456 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4457 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4458 Sched<[WriteSTX]> { 4459 bits<5> Ws; 4460 bits<5> Rt; 4461 bits<5> Rt2; 4462 bits<5> Rn; 4463 let Inst{20-16} = Ws; 4464 let Inst{14-10} = Rt2; 4465 let Inst{9-5} = Rn; 4466 let Inst{4-0} = Rt; 4467 4468 let Constraints = "@earlyclobber $Ws"; 4469} 4470 4471// Armv8.5-A Memory Tagging Extension 4472class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4473 string asm_opnds, string cstr, dag oops, dag iops> 4474 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4475 Sched<[]> { 4476 bits<5> Rn; 4477 4478 let Inst{31-24} = 0b11011001; 4479 let Inst{23-22} = opc1; 4480 let Inst{21} = 1; 4481 // Inst{20-12} defined by subclass 4482 let Inst{11-10} = opc2; 4483 let Inst{9-5} = Rn; 4484 // Inst{4-0} defined by subclass 4485} 4486 4487class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4488 dag oops, dag iops> 4489 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4490 "", oops, iops> { 4491 bits<5> Rt; 4492 4493 let Inst{20-12} = 0b000000000; 4494 let Inst{4-0} = Rt; 4495 4496 let mayLoad = Load; 4497} 4498 4499class MemTagLoad<string asm_insn, string asm_opnds> 4500 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4501 (outs GPR64:$wback), 4502 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4503 bits<5> Rt; 4504 bits<9> offset; 4505 4506 let Inst{20-12} = offset; 4507 let Inst{4-0} = Rt; 4508 4509 let mayLoad = 1; 4510} 4511 4512class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4513 string asm_opnds, string cstr, dag oops, dag iops> 4514 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4515 bits<5> Rt; 4516 bits<9> offset; 4517 4518 let Inst{20-12} = offset; 4519 let Inst{4-0} = Rt; 4520 4521 let mayStore = 1; 4522} 4523 4524multiclass MemTagStore<bits<2> opc1, string insn> { 4525 def Offset : 4526 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4527 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4528 def PreIndex : 4529 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4530 "$Rn = $wback", 4531 (outs GPR64sp:$wback), 4532 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4533 def PostIndex : 4534 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4535 "$Rn = $wback", 4536 (outs GPR64sp:$wback), 4537 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4538 4539 def : InstAlias<insn # "\t$Rt, [$Rn]", 4540 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4541} 4542 4543//--- 4544// Exception generation 4545//--- 4546 4547let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4548class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4549 list<dag> pattern = []> 4550 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4551 Sched<[WriteSys]> { 4552 bits<16> imm; 4553 let Inst{31-24} = 0b11010100; 4554 let Inst{23-21} = op1; 4555 let Inst{20-5} = imm; 4556 let Inst{4-2} = 0b000; 4557 let Inst{1-0} = ll; 4558} 4559 4560//--- 4561// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4562//-- 4563let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4564class UDFType<bits<16> opc, string asm> 4565 : I<(outs), (ins uimm16:$imm), 4566 asm, "\t$imm", "", []>, 4567 Sched<[]> { 4568 bits<16> imm; 4569 let Inst{31-16} = opc; 4570 let Inst{15-0} = imm; 4571} 4572} 4573let Predicates = [HasFPARMv8] in { 4574 4575//--- 4576// Floating point to integer conversion 4577//--- 4578 4579let mayRaiseFPException = 1 in 4580class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4581 RegisterClass srcType, RegisterClass dstType, 4582 string asm, list<dag> pattern> 4583 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4584 asm, "\t$Rd, $Rn", "", pattern>, 4585 Sched<[WriteFCvt]> { 4586 bits<5> Rd; 4587 bits<5> Rn; 4588 let Inst{30-29} = 0b00; 4589 let Inst{28-24} = 0b11110; 4590 let Inst{23-22} = type; 4591 let Inst{21} = 1; 4592 let Inst{20-19} = rmode; 4593 let Inst{18-16} = opcode; 4594 let Inst{15-10} = 0; 4595 let Inst{9-5} = Rn; 4596 let Inst{4-0} = Rd; 4597} 4598 4599let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 4600class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4601 RegisterClass srcType, RegisterClass dstType, 4602 Operand immType, string asm, list<dag> pattern> 4603 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4604 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4605 Sched<[WriteFCvt]> { 4606 bits<5> Rd; 4607 bits<5> Rn; 4608 bits<6> scale; 4609 let Inst{30-29} = 0b00; 4610 let Inst{28-24} = 0b11110; 4611 let Inst{23-22} = type; 4612 let Inst{21} = 0; 4613 let Inst{20-19} = rmode; 4614 let Inst{18-16} = opcode; 4615 let Inst{15-10} = scale; 4616 let Inst{9-5} = Rn; 4617 let Inst{4-0} = Rd; 4618} 4619 4620multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4621 SDPatternOperator OpN> { 4622 // Unscaled half-precision to 32-bit 4623 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4624 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4625 let Inst{31} = 0; // 32-bit GPR flag 4626 let Predicates = [HasFullFP16]; 4627 } 4628 4629 // Unscaled half-precision to 64-bit 4630 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4631 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4632 let Inst{31} = 1; // 64-bit GPR flag 4633 let Predicates = [HasFullFP16]; 4634 } 4635 4636 // Unscaled single-precision to 32-bit 4637 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4638 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4639 let Inst{31} = 0; // 32-bit GPR flag 4640 } 4641 4642 // Unscaled single-precision to 64-bit 4643 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4644 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4645 let Inst{31} = 1; // 64-bit GPR flag 4646 } 4647 4648 // Unscaled double-precision to 32-bit 4649 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4650 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4651 let Inst{31} = 0; // 32-bit GPR flag 4652 } 4653 4654 // Unscaled double-precision to 64-bit 4655 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4656 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4657 let Inst{31} = 1; // 64-bit GPR flag 4658 } 4659} 4660 4661multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4662 SDPatternOperator OpN> { 4663 // Scaled half-precision to 32-bit 4664 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4665 fixedpoint_f16_i32, asm, 4666 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4667 fixedpoint_f16_i32:$scale)))]> { 4668 let Inst{31} = 0; // 32-bit GPR flag 4669 let scale{5} = 1; 4670 let Predicates = [HasFullFP16]; 4671 } 4672 4673 // Scaled half-precision to 64-bit 4674 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4675 fixedpoint_f16_i64, asm, 4676 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4677 fixedpoint_f16_i64:$scale)))]> { 4678 let Inst{31} = 1; // 64-bit GPR flag 4679 let Predicates = [HasFullFP16]; 4680 } 4681 4682 // Scaled single-precision to 32-bit 4683 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4684 fixedpoint_f32_i32, asm, 4685 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4686 fixedpoint_f32_i32:$scale)))]> { 4687 let Inst{31} = 0; // 32-bit GPR flag 4688 let scale{5} = 1; 4689 } 4690 4691 // Scaled single-precision to 64-bit 4692 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4693 fixedpoint_f32_i64, asm, 4694 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4695 fixedpoint_f32_i64:$scale)))]> { 4696 let Inst{31} = 1; // 64-bit GPR flag 4697 } 4698 4699 // Scaled double-precision to 32-bit 4700 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4701 fixedpoint_f64_i32, asm, 4702 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4703 fixedpoint_f64_i32:$scale)))]> { 4704 let Inst{31} = 0; // 32-bit GPR flag 4705 let scale{5} = 1; 4706 } 4707 4708 // Scaled double-precision to 64-bit 4709 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4710 fixedpoint_f64_i64, asm, 4711 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4712 fixedpoint_f64_i64:$scale)))]> { 4713 let Inst{31} = 1; // 64-bit GPR flag 4714 } 4715} 4716 4717//--- 4718// Integer to floating point conversion 4719//--- 4720 4721let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 4722class BaseIntegerToFP<bit isUnsigned, 4723 RegisterClass srcType, RegisterClass dstType, 4724 Operand immType, string asm, list<dag> pattern> 4725 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4726 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4727 Sched<[WriteFCvt]> { 4728 bits<5> Rd; 4729 bits<5> Rn; 4730 bits<6> scale; 4731 let Inst{30-24} = 0b0011110; 4732 let Inst{21-17} = 0b00001; 4733 let Inst{16} = isUnsigned; 4734 let Inst{15-10} = scale; 4735 let Inst{9-5} = Rn; 4736 let Inst{4-0} = Rd; 4737} 4738 4739let mayRaiseFPException = 1 in 4740class BaseIntegerToFPUnscaled<bit isUnsigned, 4741 RegisterClass srcType, RegisterClass dstType, 4742 ValueType dvt, string asm, SDPatternOperator node> 4743 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4744 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4745 Sched<[WriteFCvt]> { 4746 bits<5> Rd; 4747 bits<5> Rn; 4748 bits<6> scale; 4749 let Inst{30-24} = 0b0011110; 4750 let Inst{21-17} = 0b10001; 4751 let Inst{16} = isUnsigned; 4752 let Inst{15-10} = 0b000000; 4753 let Inst{9-5} = Rn; 4754 let Inst{4-0} = Rd; 4755} 4756 4757multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4758 // Unscaled 4759 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4760 let Inst{31} = 0; // 32-bit GPR flag 4761 let Inst{23-22} = 0b11; // 16-bit FPR flag 4762 let Predicates = [HasFullFP16]; 4763 } 4764 4765 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4766 let Inst{31} = 0; // 32-bit GPR flag 4767 let Inst{23-22} = 0b00; // 32-bit FPR flag 4768 } 4769 4770 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4771 let Inst{31} = 0; // 32-bit GPR flag 4772 let Inst{23-22} = 0b01; // 64-bit FPR flag 4773 } 4774 4775 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4776 let Inst{31} = 1; // 64-bit GPR flag 4777 let Inst{23-22} = 0b11; // 16-bit FPR flag 4778 let Predicates = [HasFullFP16]; 4779 } 4780 4781 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4782 let Inst{31} = 1; // 64-bit GPR flag 4783 let Inst{23-22} = 0b00; // 32-bit FPR flag 4784 } 4785 4786 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4787 let Inst{31} = 1; // 64-bit GPR flag 4788 let Inst{23-22} = 0b01; // 64-bit FPR flag 4789 } 4790 4791 // Scaled 4792 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4793 [(set (f16 FPR16:$Rd), 4794 (fdiv (node GPR32:$Rn), 4795 fixedpoint_f16_i32:$scale))]> { 4796 let Inst{31} = 0; // 32-bit GPR flag 4797 let Inst{23-22} = 0b11; // 16-bit FPR flag 4798 let scale{5} = 1; 4799 let Predicates = [HasFullFP16]; 4800 } 4801 4802 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4803 [(set FPR32:$Rd, 4804 (fdiv (node GPR32:$Rn), 4805 fixedpoint_f32_i32:$scale))]> { 4806 let Inst{31} = 0; // 32-bit GPR flag 4807 let Inst{23-22} = 0b00; // 32-bit FPR flag 4808 let scale{5} = 1; 4809 } 4810 4811 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4812 [(set FPR64:$Rd, 4813 (fdiv (node GPR32:$Rn), 4814 fixedpoint_f64_i32:$scale))]> { 4815 let Inst{31} = 0; // 32-bit GPR flag 4816 let Inst{23-22} = 0b01; // 64-bit FPR flag 4817 let scale{5} = 1; 4818 } 4819 4820 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4821 [(set (f16 FPR16:$Rd), 4822 (fdiv (node GPR64:$Rn), 4823 fixedpoint_f16_i64:$scale))]> { 4824 let Inst{31} = 1; // 64-bit GPR flag 4825 let Inst{23-22} = 0b11; // 16-bit FPR flag 4826 let Predicates = [HasFullFP16]; 4827 } 4828 4829 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4830 [(set FPR32:$Rd, 4831 (fdiv (node GPR64:$Rn), 4832 fixedpoint_f32_i64:$scale))]> { 4833 let Inst{31} = 1; // 64-bit GPR flag 4834 let Inst{23-22} = 0b00; // 32-bit FPR flag 4835 } 4836 4837 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4838 [(set FPR64:$Rd, 4839 (fdiv (node GPR64:$Rn), 4840 fixedpoint_f64_i64:$scale))]> { 4841 let Inst{31} = 1; // 64-bit GPR flag 4842 let Inst{23-22} = 0b01; // 64-bit FPR flag 4843 } 4844} 4845 4846//--- 4847// Unscaled integer <-> floating point conversion (i.e. FMOV) 4848//--- 4849 4850let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4851class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4852 RegisterClass srcType, RegisterClass dstType, 4853 string asm> 4854 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4855 // We use COPY_TO_REGCLASS for these bitconvert operations. 4856 // copyPhysReg() expands the resultant COPY instructions after 4857 // regalloc is done. This gives greater freedom for the allocator 4858 // and related passes (coalescing, copy propagation, et. al.) to 4859 // be more effective. 4860 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4861 Sched<[WriteFCopy]> { 4862 bits<5> Rd; 4863 bits<5> Rn; 4864 let Inst{30-24} = 0b0011110; 4865 let Inst{21} = 1; 4866 let Inst{20-19} = rmode; 4867 let Inst{18-16} = opcode; 4868 let Inst{15-10} = 0b000000; 4869 let Inst{9-5} = Rn; 4870 let Inst{4-0} = Rd; 4871} 4872 4873let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4874class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4875 RegisterClass srcType, RegisterOperand dstType, string asm, 4876 string kind> 4877 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4878 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4879 Sched<[WriteFCopy]> { 4880 bits<5> Rd; 4881 bits<5> Rn; 4882 let Inst{30-23} = 0b00111101; 4883 let Inst{21} = 1; 4884 let Inst{20-19} = rmode; 4885 let Inst{18-16} = opcode; 4886 let Inst{15-10} = 0b000000; 4887 let Inst{9-5} = Rn; 4888 let Inst{4-0} = Rd; 4889 4890 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4891} 4892 4893let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4894class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4895 RegisterOperand srcType, RegisterClass dstType, string asm, 4896 string kind> 4897 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4898 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4899 Sched<[WriteFCopy]> { 4900 bits<5> Rd; 4901 bits<5> Rn; 4902 let Inst{30-23} = 0b00111101; 4903 let Inst{21} = 1; 4904 let Inst{20-19} = rmode; 4905 let Inst{18-16} = opcode; 4906 let Inst{15-10} = 0b000000; 4907 let Inst{9-5} = Rn; 4908 let Inst{4-0} = Rd; 4909 4910 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4911} 4912 4913 4914multiclass UnscaledConversion<string asm> { 4915 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4916 let Inst{31} = 0; // 32-bit GPR flag 4917 let Inst{23-22} = 0b11; // 16-bit FPR flag 4918 let Predicates = [HasFullFP16]; 4919 } 4920 4921 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4922 let Inst{31} = 1; // 64-bit GPR flag 4923 let Inst{23-22} = 0b11; // 16-bit FPR flag 4924 let Predicates = [HasFullFP16]; 4925 } 4926 4927 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4928 let Inst{31} = 0; // 32-bit GPR flag 4929 let Inst{23-22} = 0b00; // 32-bit FPR flag 4930 } 4931 4932 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4933 let Inst{31} = 1; // 64-bit GPR flag 4934 let Inst{23-22} = 0b01; // 64-bit FPR flag 4935 } 4936 4937 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4938 let Inst{31} = 0; // 32-bit GPR flag 4939 let Inst{23-22} = 0b11; // 16-bit FPR flag 4940 let Predicates = [HasFullFP16]; 4941 } 4942 4943 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4944 let Inst{31} = 1; // 64-bit GPR flag 4945 let Inst{23-22} = 0b11; // 16-bit FPR flag 4946 let Predicates = [HasFullFP16]; 4947 } 4948 4949 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4950 let Inst{31} = 0; // 32-bit GPR flag 4951 let Inst{23-22} = 0b00; // 32-bit FPR flag 4952 } 4953 4954 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4955 let Inst{31} = 1; // 64-bit GPR flag 4956 let Inst{23-22} = 0b01; // 64-bit FPR flag 4957 } 4958 4959 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4960 asm, ".d"> { 4961 let Inst{31} = 1; 4962 let Inst{22} = 0; 4963 } 4964 4965 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4966 asm, ".d"> { 4967 let Inst{31} = 1; 4968 let Inst{22} = 0; 4969 } 4970} 4971 4972//--- 4973// Floating point conversion 4974//--- 4975 4976let mayRaiseFPException = 1 in 4977class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4978 RegisterClass srcType, string asm, list<dag> pattern> 4979 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4980 Sched<[WriteFCvt]> { 4981 bits<5> Rd; 4982 bits<5> Rn; 4983 let Inst{31-24} = 0b00011110; 4984 let Inst{23-22} = type; 4985 let Inst{21-17} = 0b10001; 4986 let Inst{16-15} = opcode; 4987 let Inst{14-10} = 0b10000; 4988 let Inst{9-5} = Rn; 4989 let Inst{4-0} = Rd; 4990} 4991 4992multiclass FPConversion<string asm> { 4993 // Double-precision to Half-precision 4994 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4995 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4996 4997 // Double-precision to Single-precision 4998 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4999 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 5000 5001 // Half-precision to Double-precision 5002 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5003 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5004 5005 // Half-precision to Single-precision 5006 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5007 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5008 5009 // Single-precision to Double-precision 5010 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5011 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5012 5013 // Single-precision to Half-precision 5014 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5015 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5016} 5017 5018//--- 5019// Single operand floating point data processing 5020//--- 5021 5022let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5023class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5024 ValueType vt, string asm, SDPatternOperator node> 5025 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5026 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5027 Sched<[WriteF]> { 5028 bits<5> Rd; 5029 bits<5> Rn; 5030 let Inst{31-24} = 0b00011110; 5031 let Inst{21} = 0b1; 5032 let Inst{20-15} = opcode; 5033 let Inst{14-10} = 0b10000; 5034 let Inst{9-5} = Rn; 5035 let Inst{4-0} = Rd; 5036} 5037 5038multiclass SingleOperandFPData<bits<4> opcode, string asm, 5039 SDPatternOperator node = null_frag, 5040 int fpexceptions = 1> { 5041 let mayRaiseFPException = fpexceptions in { 5042 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5043 let Inst{23-22} = 0b11; // 16-bit size flag 5044 let Predicates = [HasFullFP16]; 5045 } 5046 5047 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5048 let Inst{23-22} = 0b00; // 32-bit size flag 5049 } 5050 5051 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5052 let Inst{23-22} = 0b01; // 64-bit size flag 5053 } 5054 } 5055} 5056 5057multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5058 SDPatternOperator node = null_frag> 5059 : SingleOperandFPData<opcode, asm, node, 0>; 5060 5061let mayRaiseFPException = 1 in 5062multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5063 SDPatternOperator node = null_frag>{ 5064 5065 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5066 let Inst{23-22} = 0b00; // 32-bit registers 5067 } 5068 5069 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5070 let Inst{23-22} = 0b01; // 64-bit registers 5071 } 5072} 5073 5074// FRInt[32|64][Z|N] instructions 5075multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5076 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5077 5078//--- 5079// Two operand floating point data processing 5080//--- 5081 5082let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5083class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5084 string asm, list<dag> pat> 5085 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5086 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5087 Sched<[WriteF]> { 5088 bits<5> Rd; 5089 bits<5> Rn; 5090 bits<5> Rm; 5091 let Inst{31-24} = 0b00011110; 5092 let Inst{21} = 1; 5093 let Inst{20-16} = Rm; 5094 let Inst{15-12} = opcode; 5095 let Inst{11-10} = 0b10; 5096 let Inst{9-5} = Rn; 5097 let Inst{4-0} = Rd; 5098} 5099 5100multiclass TwoOperandFPData<bits<4> opcode, string asm, 5101 SDPatternOperator node = null_frag> { 5102 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5103 [(set (f16 FPR16:$Rd), 5104 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5105 let Inst{23-22} = 0b11; // 16-bit size flag 5106 let Predicates = [HasFullFP16]; 5107 } 5108 5109 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5110 [(set (f32 FPR32:$Rd), 5111 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5112 let Inst{23-22} = 0b00; // 32-bit size flag 5113 } 5114 5115 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5116 [(set (f64 FPR64:$Rd), 5117 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5118 let Inst{23-22} = 0b01; // 64-bit size flag 5119 } 5120} 5121 5122multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5123 SDPatternOperator node> { 5124 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5125 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5126 let Inst{23-22} = 0b11; // 16-bit size flag 5127 let Predicates = [HasFullFP16]; 5128 } 5129 5130 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5131 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5132 let Inst{23-22} = 0b00; // 32-bit size flag 5133 } 5134 5135 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5136 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5137 let Inst{23-22} = 0b01; // 64-bit size flag 5138 } 5139} 5140 5141 5142//--- 5143// Three operand floating point data processing 5144//--- 5145 5146let mayRaiseFPException = 1 in 5147class BaseThreeOperandFPData<bit isNegated, bit isSub, 5148 RegisterClass regtype, string asm, list<dag> pat> 5149 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5150 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5151 Sched<[WriteFMul]> { 5152 bits<5> Rd; 5153 bits<5> Rn; 5154 bits<5> Rm; 5155 bits<5> Ra; 5156 let Inst{31-24} = 0b00011111; 5157 let Inst{21} = isNegated; 5158 let Inst{20-16} = Rm; 5159 let Inst{15} = isSub; 5160 let Inst{14-10} = Ra; 5161 let Inst{9-5} = Rn; 5162 let Inst{4-0} = Rd; 5163} 5164 5165multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5166 SDPatternOperator node> { 5167 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5168 [(set (f16 FPR16:$Rd), 5169 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5170 let Inst{23-22} = 0b11; // 16-bit size flag 5171 let Predicates = [HasFullFP16]; 5172 } 5173 5174 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5175 [(set FPR32:$Rd, 5176 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5177 let Inst{23-22} = 0b00; // 32-bit size flag 5178 } 5179 5180 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5181 [(set FPR64:$Rd, 5182 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5183 let Inst{23-22} = 0b01; // 64-bit size flag 5184 } 5185} 5186 5187//--- 5188// Floating point data comparisons 5189//--- 5190 5191let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5192class BaseOneOperandFPComparison<bit signalAllNans, 5193 RegisterClass regtype, string asm, 5194 list<dag> pat> 5195 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5196 Sched<[WriteFCmp]> { 5197 bits<5> Rn; 5198 let Inst{31-24} = 0b00011110; 5199 let Inst{21} = 1; 5200 5201 let Inst{15-10} = 0b001000; 5202 let Inst{9-5} = Rn; 5203 let Inst{4} = signalAllNans; 5204 let Inst{3-0} = 0b1000; 5205 5206 // Rm should be 0b00000 canonically, but we need to accept any value. 5207 let PostEncoderMethod = "fixOneOperandFPComparison"; 5208} 5209 5210let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5211class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5212 string asm, list<dag> pat> 5213 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5214 Sched<[WriteFCmp]> { 5215 bits<5> Rm; 5216 bits<5> Rn; 5217 let Inst{31-24} = 0b00011110; 5218 let Inst{21} = 1; 5219 let Inst{20-16} = Rm; 5220 let Inst{15-10} = 0b001000; 5221 let Inst{9-5} = Rn; 5222 let Inst{4} = signalAllNans; 5223 let Inst{3-0} = 0b0000; 5224} 5225 5226multiclass FPComparison<bit signalAllNans, string asm, 5227 SDPatternOperator OpNode = null_frag> { 5228 let Defs = [NZCV] in { 5229 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5230 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5231 let Inst{23-22} = 0b11; 5232 let Predicates = [HasFullFP16]; 5233 } 5234 5235 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5236 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5237 let Inst{23-22} = 0b11; 5238 let Predicates = [HasFullFP16]; 5239 } 5240 5241 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5242 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5243 let Inst{23-22} = 0b00; 5244 } 5245 5246 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5247 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5248 let Inst{23-22} = 0b00; 5249 } 5250 5251 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5252 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5253 let Inst{23-22} = 0b01; 5254 } 5255 5256 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5257 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5258 let Inst{23-22} = 0b01; 5259 } 5260 } // Defs = [NZCV] 5261} 5262 5263//--- 5264// Floating point conditional comparisons 5265//--- 5266 5267let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 5268class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5269 string mnemonic, list<dag> pat> 5270 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5271 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5272 Sched<[WriteFCmp]> { 5273 let Uses = [NZCV]; 5274 let Defs = [NZCV]; 5275 5276 bits<5> Rn; 5277 bits<5> Rm; 5278 bits<4> nzcv; 5279 bits<4> cond; 5280 5281 let Inst{31-24} = 0b00011110; 5282 let Inst{21} = 1; 5283 let Inst{20-16} = Rm; 5284 let Inst{15-12} = cond; 5285 let Inst{11-10} = 0b01; 5286 let Inst{9-5} = Rn; 5287 let Inst{4} = signalAllNans; 5288 let Inst{3-0} = nzcv; 5289} 5290 5291multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5292 SDPatternOperator OpNode = null_frag> { 5293 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5294 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5295 (i32 imm:$cond), NZCV))]> { 5296 let Inst{23-22} = 0b11; 5297 let Predicates = [HasFullFP16]; 5298 } 5299 5300 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5301 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5302 (i32 imm:$cond), NZCV))]> { 5303 let Inst{23-22} = 0b00; 5304 } 5305 5306 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5307 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5308 (i32 imm:$cond), NZCV))]> { 5309 let Inst{23-22} = 0b01; 5310 } 5311} 5312 5313//--- 5314// Floating point conditional select 5315//--- 5316 5317class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5318 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5319 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5320 [(set regtype:$Rd, 5321 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5322 (i32 imm:$cond), NZCV))]>, 5323 Sched<[WriteF]> { 5324 bits<5> Rd; 5325 bits<5> Rn; 5326 bits<5> Rm; 5327 bits<4> cond; 5328 5329 let Inst{31-24} = 0b00011110; 5330 let Inst{21} = 1; 5331 let Inst{20-16} = Rm; 5332 let Inst{15-12} = cond; 5333 let Inst{11-10} = 0b11; 5334 let Inst{9-5} = Rn; 5335 let Inst{4-0} = Rd; 5336} 5337 5338multiclass FPCondSelect<string asm> { 5339 let Uses = [NZCV] in { 5340 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5341 let Inst{23-22} = 0b11; 5342 let Predicates = [HasFullFP16]; 5343 } 5344 5345 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5346 let Inst{23-22} = 0b00; 5347 } 5348 5349 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5350 let Inst{23-22} = 0b01; 5351 } 5352 } // Uses = [NZCV] 5353} 5354 5355//--- 5356// Floating move immediate 5357//--- 5358 5359class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5360 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5361 [(set regtype:$Rd, fpimmtype:$imm)]>, 5362 Sched<[WriteFImm]> { 5363 bits<5> Rd; 5364 bits<8> imm; 5365 let Inst{31-24} = 0b00011110; 5366 let Inst{21} = 1; 5367 let Inst{20-13} = imm; 5368 let Inst{12-5} = 0b10000000; 5369 let Inst{4-0} = Rd; 5370} 5371 5372multiclass FPMoveImmediate<string asm> { 5373 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5374 let Inst{23-22} = 0b11; 5375 let Predicates = [HasFullFP16]; 5376 } 5377 5378 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5379 let Inst{23-22} = 0b00; 5380 } 5381 5382 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5383 let Inst{23-22} = 0b01; 5384 } 5385} 5386} // end of 'let Predicates = [HasFPARMv8]' 5387 5388//---------------------------------------------------------------------------- 5389// AdvSIMD 5390//---------------------------------------------------------------------------- 5391 5392let Predicates = [HasNEON] in { 5393 5394//---------------------------------------------------------------------------- 5395// AdvSIMD three register vector instructions 5396//---------------------------------------------------------------------------- 5397 5398let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5399class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5400 RegisterOperand regtype, string asm, string kind, 5401 list<dag> pattern> 5402 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5403 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5404 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5405 Sched<[!if(Q, WriteVq, WriteVd)]> { 5406 bits<5> Rd; 5407 bits<5> Rn; 5408 bits<5> Rm; 5409 let Inst{31} = 0; 5410 let Inst{30} = Q; 5411 let Inst{29} = U; 5412 let Inst{28-24} = 0b01110; 5413 let Inst{23-21} = size; 5414 let Inst{20-16} = Rm; 5415 let Inst{15-11} = opcode; 5416 let Inst{10} = 1; 5417 let Inst{9-5} = Rn; 5418 let Inst{4-0} = Rd; 5419} 5420 5421let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5422class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5423 RegisterOperand regtype, string asm, string kind, 5424 list<dag> pattern> 5425 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5426 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5427 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5428 Sched<[!if(Q, WriteVq, WriteVd)]> { 5429 bits<5> Rd; 5430 bits<5> Rn; 5431 bits<5> Rm; 5432 let Inst{31} = 0; 5433 let Inst{30} = Q; 5434 let Inst{29} = U; 5435 let Inst{28-24} = 0b01110; 5436 let Inst{23-21} = size; 5437 let Inst{20-16} = Rm; 5438 let Inst{15-11} = opcode; 5439 let Inst{10} = 1; 5440 let Inst{9-5} = Rn; 5441 let Inst{4-0} = Rd; 5442} 5443 5444let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5445class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5446 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5447 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5448 5449multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5450 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5451 [(set (v8i8 V64:$dst), 5452 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5453 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5454 [(set (v16i8 V128:$dst), 5455 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5456 (v16i8 V128:$Rm)))]>; 5457 5458 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5459 (v4i16 V64:$RHS))), 5460 (!cast<Instruction>(NAME#"v8i8") 5461 V64:$LHS, V64:$MHS, V64:$RHS)>; 5462 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5463 (v2i32 V64:$RHS))), 5464 (!cast<Instruction>(NAME#"v8i8") 5465 V64:$LHS, V64:$MHS, V64:$RHS)>; 5466 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5467 (v1i64 V64:$RHS))), 5468 (!cast<Instruction>(NAME#"v8i8") 5469 V64:$LHS, V64:$MHS, V64:$RHS)>; 5470 5471 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5472 (v8i16 V128:$RHS))), 5473 (!cast<Instruction>(NAME#"v16i8") 5474 V128:$LHS, V128:$MHS, V128:$RHS)>; 5475 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5476 (v4i32 V128:$RHS))), 5477 (!cast<Instruction>(NAME#"v16i8") 5478 V128:$LHS, V128:$MHS, V128:$RHS)>; 5479 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5480 (v2i64 V128:$RHS))), 5481 (!cast<Instruction>(NAME#"v16i8") 5482 V128:$LHS, V128:$MHS, V128:$RHS)>; 5483} 5484 5485// All operand sizes distinguished in the encoding. 5486multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5487 SDPatternOperator OpNode> { 5488 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5489 asm, ".8b", 5490 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5491 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5492 asm, ".16b", 5493 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5494 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5495 asm, ".4h", 5496 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5497 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5498 asm, ".8h", 5499 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5500 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5501 asm, ".2s", 5502 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5503 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5504 asm, ".4s", 5505 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5506 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5507 asm, ".2d", 5508 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5509} 5510 5511multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5512 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5513 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5514 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5515 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5516 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5517 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5518 5519 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5520 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5521 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5522 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5523 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5524 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5525 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5526 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5527} 5528 5529// As above, but D sized elements unsupported. 5530multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5531 SDPatternOperator OpNode> { 5532 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5533 asm, ".8b", 5534 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5535 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5536 asm, ".16b", 5537 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5538 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5539 asm, ".4h", 5540 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5541 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5542 asm, ".8h", 5543 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5544 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5545 asm, ".2s", 5546 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5547 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5548 asm, ".4s", 5549 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5550} 5551 5552multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5553 SDPatternOperator OpNode> { 5554 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5555 asm, ".8b", 5556 [(set (v8i8 V64:$dst), 5557 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5558 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5559 asm, ".16b", 5560 [(set (v16i8 V128:$dst), 5561 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5562 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5563 asm, ".4h", 5564 [(set (v4i16 V64:$dst), 5565 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5566 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5567 asm, ".8h", 5568 [(set (v8i16 V128:$dst), 5569 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5570 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5571 asm, ".2s", 5572 [(set (v2i32 V64:$dst), 5573 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5574 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5575 asm, ".4s", 5576 [(set (v4i32 V128:$dst), 5577 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5578} 5579 5580// As above, but only B sized elements supported. 5581multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5582 SDPatternOperator OpNode> { 5583 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5584 asm, ".8b", 5585 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5586 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5587 asm, ".16b", 5588 [(set (v16i8 V128:$Rd), 5589 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5590} 5591 5592// As above, but only floating point elements supported. 5593let mayRaiseFPException = 1 in 5594multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5595 string asm, SDPatternOperator OpNode> { 5596 let Predicates = [HasNEON, HasFullFP16] in { 5597 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5598 asm, ".4h", 5599 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5600 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5601 asm, ".8h", 5602 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5603 } // Predicates = [HasNEON, HasFullFP16] 5604 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5605 asm, ".2s", 5606 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5607 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5608 asm, ".4s", 5609 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5610 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5611 asm, ".2d", 5612 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5613} 5614 5615let mayRaiseFPException = 1 in 5616multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5617 string asm, 5618 SDPatternOperator OpNode> { 5619 let Predicates = [HasNEON, HasFullFP16] in { 5620 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5621 asm, ".4h", 5622 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5623 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5624 asm, ".8h", 5625 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5626 } // Predicates = [HasNEON, HasFullFP16] 5627 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5628 asm, ".2s", 5629 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5630 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5631 asm, ".4s", 5632 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5633 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5634 asm, ".2d", 5635 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5636} 5637 5638let mayRaiseFPException = 1 in 5639multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5640 string asm, SDPatternOperator OpNode> { 5641 let Predicates = [HasNEON, HasFullFP16] in { 5642 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5643 asm, ".4h", 5644 [(set (v4f16 V64:$dst), 5645 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5646 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5647 asm, ".8h", 5648 [(set (v8f16 V128:$dst), 5649 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5650 } // Predicates = [HasNEON, HasFullFP16] 5651 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5652 asm, ".2s", 5653 [(set (v2f32 V64:$dst), 5654 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5655 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5656 asm, ".4s", 5657 [(set (v4f32 V128:$dst), 5658 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5659 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5660 asm, ".2d", 5661 [(set (v2f64 V128:$dst), 5662 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5663} 5664 5665// As above, but D and B sized elements unsupported. 5666let mayRaiseFPException = 1 in 5667multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5668 SDPatternOperator OpNode> { 5669 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5670 asm, ".4h", 5671 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5672 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5673 asm, ".8h", 5674 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5675 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5676 asm, ".2s", 5677 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5678 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5679 asm, ".4s", 5680 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5681} 5682 5683// Logical three vector ops share opcode bits, and only use B sized elements. 5684multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5685 SDPatternOperator OpNode = null_frag> { 5686 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5687 asm, ".8b", 5688 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5689 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5690 asm, ".16b", 5691 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5692 5693 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5694 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5695 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5696 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5697 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5698 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5699 5700 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5701 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5702 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5703 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5704 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5705 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5706} 5707 5708multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5709 string asm, SDPatternOperator OpNode = null_frag> { 5710 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5711 asm, ".8b", 5712 [(set (v8i8 V64:$dst), 5713 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5714 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5715 asm, ".16b", 5716 [(set (v16i8 V128:$dst), 5717 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5718 (v16i8 V128:$Rm)))]>; 5719 5720 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5721 (v4i16 V64:$RHS))), 5722 (!cast<Instruction>(NAME#"v8i8") 5723 V64:$LHS, V64:$MHS, V64:$RHS)>; 5724 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5725 (v2i32 V64:$RHS))), 5726 (!cast<Instruction>(NAME#"v8i8") 5727 V64:$LHS, V64:$MHS, V64:$RHS)>; 5728 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5729 (v1i64 V64:$RHS))), 5730 (!cast<Instruction>(NAME#"v8i8") 5731 V64:$LHS, V64:$MHS, V64:$RHS)>; 5732 5733 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5734 (v8i16 V128:$RHS))), 5735 (!cast<Instruction>(NAME#"v16i8") 5736 V128:$LHS, V128:$MHS, V128:$RHS)>; 5737 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5738 (v4i32 V128:$RHS))), 5739 (!cast<Instruction>(NAME#"v16i8") 5740 V128:$LHS, V128:$MHS, V128:$RHS)>; 5741 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5742 (v2i64 V128:$RHS))), 5743 (!cast<Instruction>(NAME#"v16i8") 5744 V128:$LHS, V128:$MHS, V128:$RHS)>; 5745} 5746 5747// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5748// bytes from S-sized elements. 5749class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5750 string kind2, RegisterOperand RegType, 5751 ValueType AccumType, ValueType InputType, 5752 SDPatternOperator OpNode> : 5753 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5754 [(set (AccumType RegType:$dst), 5755 (OpNode (AccumType RegType:$Rd), 5756 (InputType RegType:$Rn), 5757 (InputType RegType:$Rm)))]> { 5758 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5759} 5760 5761multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5762 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5763 v2i32, v8i8, OpNode>; 5764 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5765 v4i32, v16i8, OpNode>; 5766} 5767 5768// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5769// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5770// 8H to 4S, when Q=1). 5771let mayRaiseFPException = 1 in 5772class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5773 string kind2, RegisterOperand RegType, 5774 ValueType AccumType, ValueType InputType, 5775 SDPatternOperator OpNode> : 5776 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5777 [(set (AccumType RegType:$dst), 5778 (OpNode (AccumType RegType:$Rd), 5779 (InputType RegType:$Rn), 5780 (InputType RegType:$Rm)))]> { 5781 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5782 let Inst{13} = b13; 5783} 5784 5785multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5786 SDPatternOperator OpNode> { 5787 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5788 v2f32, v4f16, OpNode>; 5789 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5790 v4f32, v8f16, OpNode>; 5791} 5792 5793 5794//---------------------------------------------------------------------------- 5795// AdvSIMD two register vector instructions. 5796//---------------------------------------------------------------------------- 5797 5798let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5799class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5800 bits<2> size2, RegisterOperand regtype, string asm, 5801 string dstkind, string srckind, list<dag> pattern> 5802 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5803 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5804 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5805 Sched<[!if(Q, WriteVq, WriteVd)]> { 5806 bits<5> Rd; 5807 bits<5> Rn; 5808 let Inst{31} = 0; 5809 let Inst{30} = Q; 5810 let Inst{29} = U; 5811 let Inst{28-24} = 0b01110; 5812 let Inst{23-22} = size; 5813 let Inst{21} = 0b1; 5814 let Inst{20-19} = size2; 5815 let Inst{18-17} = 0b00; 5816 let Inst{16-12} = opcode; 5817 let Inst{11-10} = 0b10; 5818 let Inst{9-5} = Rn; 5819 let Inst{4-0} = Rd; 5820} 5821 5822let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5823class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5824 bits<2> size2, RegisterOperand regtype, 5825 string asm, string dstkind, string srckind, 5826 list<dag> pattern> 5827 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5828 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5829 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5830 Sched<[!if(Q, WriteVq, WriteVd)]> { 5831 bits<5> Rd; 5832 bits<5> Rn; 5833 let Inst{31} = 0; 5834 let Inst{30} = Q; 5835 let Inst{29} = U; 5836 let Inst{28-24} = 0b01110; 5837 let Inst{23-22} = size; 5838 let Inst{21} = 0b1; 5839 let Inst{20-19} = size2; 5840 let Inst{18-17} = 0b00; 5841 let Inst{16-12} = opcode; 5842 let Inst{11-10} = 0b10; 5843 let Inst{9-5} = Rn; 5844 let Inst{4-0} = Rd; 5845} 5846 5847// Supports B, H, and S element sizes. 5848multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5849 SDPatternOperator OpNode> { 5850 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5851 asm, ".8b", ".8b", 5852 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5853 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5854 asm, ".16b", ".16b", 5855 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5856 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5857 asm, ".4h", ".4h", 5858 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5859 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5860 asm, ".8h", ".8h", 5861 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5862 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5863 asm, ".2s", ".2s", 5864 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5865 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5866 asm, ".4s", ".4s", 5867 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5868} 5869 5870class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5871 RegisterOperand regtype, string asm, string dstkind, 5872 string srckind, string amount> 5873 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5874 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5875 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5876 Sched<[WriteVq]> { 5877 bits<5> Rd; 5878 bits<5> Rn; 5879 let Inst{31} = 0; 5880 let Inst{30} = Q; 5881 let Inst{29-24} = 0b101110; 5882 let Inst{23-22} = size; 5883 let Inst{21-10} = 0b100001001110; 5884 let Inst{9-5} = Rn; 5885 let Inst{4-0} = Rd; 5886} 5887 5888multiclass SIMDVectorLShiftLongBySizeBHS { 5889 let hasSideEffects = 0 in { 5890 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5891 "shll", ".8h", ".8b", "8">; 5892 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5893 "shll2", ".8h", ".16b", "8">; 5894 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5895 "shll", ".4s", ".4h", "16">; 5896 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5897 "shll2", ".4s", ".8h", "16">; 5898 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5899 "shll", ".2d", ".2s", "32">; 5900 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5901 "shll2", ".2d", ".4s", "32">; 5902 } 5903} 5904 5905// Supports all element sizes. 5906multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5907 SDPatternOperator OpNode> { 5908 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5909 asm, ".4h", ".8b", 5910 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5911 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5912 asm, ".8h", ".16b", 5913 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5914 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5915 asm, ".2s", ".4h", 5916 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5917 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5918 asm, ".4s", ".8h", 5919 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5920 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5921 asm, ".1d", ".2s", 5922 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5923 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5924 asm, ".2d", ".4s", 5925 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5926} 5927 5928multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5929 SDPatternOperator OpNode> { 5930 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5931 asm, ".4h", ".8b", 5932 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5933 (v8i8 V64:$Rn)))]>; 5934 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5935 asm, ".8h", ".16b", 5936 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5937 (v16i8 V128:$Rn)))]>; 5938 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5939 asm, ".2s", ".4h", 5940 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5941 (v4i16 V64:$Rn)))]>; 5942 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5943 asm, ".4s", ".8h", 5944 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5945 (v8i16 V128:$Rn)))]>; 5946 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5947 asm, ".1d", ".2s", 5948 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5949 (v2i32 V64:$Rn)))]>; 5950 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5951 asm, ".2d", ".4s", 5952 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5953 (v4i32 V128:$Rn)))]>; 5954} 5955 5956// Supports all element sizes, except 1xD. 5957multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5958 SDPatternOperator OpNode> { 5959 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5960 asm, ".8b", ".8b", 5961 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5962 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5963 asm, ".16b", ".16b", 5964 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5965 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5966 asm, ".4h", ".4h", 5967 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5968 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5969 asm, ".8h", ".8h", 5970 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5971 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5972 asm, ".2s", ".2s", 5973 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5974 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5975 asm, ".4s", ".4s", 5976 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5977 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5978 asm, ".2d", ".2d", 5979 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5980} 5981 5982multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5983 SDPatternOperator OpNode = null_frag> { 5984 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5985 asm, ".8b", ".8b", 5986 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5987 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5988 asm, ".16b", ".16b", 5989 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5990 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5991 asm, ".4h", ".4h", 5992 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5993 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5994 asm, ".8h", ".8h", 5995 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5996 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5997 asm, ".2s", ".2s", 5998 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5999 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6000 asm, ".4s", ".4s", 6001 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6002 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6003 asm, ".2d", ".2d", 6004 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6005} 6006 6007 6008// Supports only B element sizes. 6009multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6010 SDPatternOperator OpNode> { 6011 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6012 asm, ".8b", ".8b", 6013 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6014 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6015 asm, ".16b", ".16b", 6016 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6017 6018} 6019 6020// Supports only B and H element sizes. 6021multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6022 SDPatternOperator OpNode> { 6023 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6024 asm, ".8b", ".8b", 6025 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6026 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6027 asm, ".16b", ".16b", 6028 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6029 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6030 asm, ".4h", ".4h", 6031 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6032 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6033 asm, ".8h", ".8h", 6034 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6035} 6036 6037// Supports H, S and D element sizes, uses high bit of the size field 6038// as an extra opcode bit. 6039multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6040 SDPatternOperator OpNode, 6041 int fpexceptions = 1> { 6042 let mayRaiseFPException = fpexceptions in { 6043 let Predicates = [HasNEON, HasFullFP16] in { 6044 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6045 asm, ".4h", ".4h", 6046 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6047 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6048 asm, ".8h", ".8h", 6049 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6050 } // Predicates = [HasNEON, HasFullFP16] 6051 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6052 asm, ".2s", ".2s", 6053 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6054 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6055 asm, ".4s", ".4s", 6056 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6057 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6058 asm, ".2d", ".2d", 6059 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6060 } 6061} 6062 6063multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6064 SDPatternOperator OpNode> 6065 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6066 6067// Supports only S and D element sizes 6068let mayRaiseFPException = 1 in 6069multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6070 SDPatternOperator OpNode = null_frag> { 6071 6072 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6073 asm, ".2s", ".2s", 6074 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6075 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6076 asm, ".4s", ".4s", 6077 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6078 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6079 asm, ".2d", ".2d", 6080 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6081} 6082 6083multiclass FRIntNNTVector<bit U, bit op, string asm, 6084 SDPatternOperator OpNode = null_frag> : 6085 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6086 6087// Supports only S element size. 6088multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6089 SDPatternOperator OpNode> { 6090 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6091 asm, ".2s", ".2s", 6092 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6093 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6094 asm, ".4s", ".4s", 6095 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6096} 6097 6098let mayRaiseFPException = 1 in 6099multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6100 SDPatternOperator OpNode> { 6101 let Predicates = [HasNEON, HasFullFP16] in { 6102 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6103 asm, ".4h", ".4h", 6104 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6105 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6106 asm, ".8h", ".8h", 6107 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6108 } // Predicates = [HasNEON, HasFullFP16] 6109 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6110 asm, ".2s", ".2s", 6111 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6112 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6113 asm, ".4s", ".4s", 6114 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6115 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6116 asm, ".2d", ".2d", 6117 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6118} 6119 6120let mayRaiseFPException = 1 in 6121multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6122 SDPatternOperator OpNode> { 6123 let Predicates = [HasNEON, HasFullFP16] in { 6124 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6125 asm, ".4h", ".4h", 6126 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6127 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6128 asm, ".8h", ".8h", 6129 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6130 } // Predicates = [HasNEON, HasFullFP16] 6131 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6132 asm, ".2s", ".2s", 6133 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6134 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6135 asm, ".4s", ".4s", 6136 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6137 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6138 asm, ".2d", ".2d", 6139 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6140} 6141 6142let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6143class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6144 RegisterOperand inreg, RegisterOperand outreg, 6145 string asm, string outkind, string inkind, 6146 list<dag> pattern> 6147 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6148 "{\t$Rd" # outkind # ", $Rn" # inkind # 6149 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6150 Sched<[WriteVq]> { 6151 bits<5> Rd; 6152 bits<5> Rn; 6153 let Inst{31} = 0; 6154 let Inst{30} = Q; 6155 let Inst{29} = U; 6156 let Inst{28-24} = 0b01110; 6157 let Inst{23-22} = size; 6158 let Inst{21-17} = 0b10000; 6159 let Inst{16-12} = opcode; 6160 let Inst{11-10} = 0b10; 6161 let Inst{9-5} = Rn; 6162 let Inst{4-0} = Rd; 6163} 6164 6165let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6166class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6167 RegisterOperand inreg, RegisterOperand outreg, 6168 string asm, string outkind, string inkind, 6169 list<dag> pattern> 6170 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6171 "{\t$Rd" # outkind # ", $Rn" # inkind # 6172 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6173 Sched<[WriteVq]> { 6174 bits<5> Rd; 6175 bits<5> Rn; 6176 let Inst{31} = 0; 6177 let Inst{30} = Q; 6178 let Inst{29} = U; 6179 let Inst{28-24} = 0b01110; 6180 let Inst{23-22} = size; 6181 let Inst{21-17} = 0b10000; 6182 let Inst{16-12} = opcode; 6183 let Inst{11-10} = 0b10; 6184 let Inst{9-5} = Rn; 6185 let Inst{4-0} = Rd; 6186} 6187 6188multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6189 SDPatternOperator OpNode> { 6190 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6191 asm, ".8b", ".8h", 6192 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6193 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6194 asm#"2", ".16b", ".8h", []>; 6195 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6196 asm, ".4h", ".4s", 6197 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6198 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6199 asm#"2", ".8h", ".4s", []>; 6200 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6201 asm, ".2s", ".2d", 6202 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6203 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6204 asm#"2", ".4s", ".2d", []>; 6205 6206 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6207 (!cast<Instruction>(NAME # "v16i8") 6208 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6209 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6210 (!cast<Instruction>(NAME # "v8i16") 6211 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6212 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6213 (!cast<Instruction>(NAME # "v4i32") 6214 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6215} 6216 6217class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6218 bits<5> opcode, RegisterOperand regtype, string asm, 6219 string kind, string zero, ValueType dty, 6220 ValueType sty, SDNode OpNode> 6221 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6222 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6223 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6224 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6225 Sched<[!if(Q, WriteVq, WriteVd)]> { 6226 bits<5> Rd; 6227 bits<5> Rn; 6228 let Inst{31} = 0; 6229 let Inst{30} = Q; 6230 let Inst{29} = U; 6231 let Inst{28-24} = 0b01110; 6232 let Inst{23-22} = size; 6233 let Inst{21} = 0b1; 6234 let Inst{20-19} = size2; 6235 let Inst{18-17} = 0b00; 6236 let Inst{16-12} = opcode; 6237 let Inst{11-10} = 0b10; 6238 let Inst{9-5} = Rn; 6239 let Inst{4-0} = Rd; 6240} 6241 6242// Comparisons support all element sizes, except 1xD. 6243multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6244 SDNode OpNode> { 6245 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6246 asm, ".8b", "0", 6247 v8i8, v8i8, OpNode>; 6248 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6249 asm, ".16b", "0", 6250 v16i8, v16i8, OpNode>; 6251 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6252 asm, ".4h", "0", 6253 v4i16, v4i16, OpNode>; 6254 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6255 asm, ".8h", "0", 6256 v8i16, v8i16, OpNode>; 6257 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6258 asm, ".2s", "0", 6259 v2i32, v2i32, OpNode>; 6260 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6261 asm, ".4s", "0", 6262 v4i32, v4i32, OpNode>; 6263 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6264 asm, ".2d", "0", 6265 v2i64, v2i64, OpNode>; 6266} 6267 6268// FP Comparisons support only S and D element sizes (and H for v8.2a). 6269multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6270 string asm, SDNode OpNode> { 6271 6272 let mayRaiseFPException = 1 in { 6273 let Predicates = [HasNEON, HasFullFP16] in { 6274 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6275 asm, ".4h", "0.0", 6276 v4i16, v4f16, OpNode>; 6277 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6278 asm, ".8h", "0.0", 6279 v8i16, v8f16, OpNode>; 6280 } // Predicates = [HasNEON, HasFullFP16] 6281 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6282 asm, ".2s", "0.0", 6283 v2i32, v2f32, OpNode>; 6284 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6285 asm, ".4s", "0.0", 6286 v4i32, v4f32, OpNode>; 6287 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6288 asm, ".2d", "0.0", 6289 v2i64, v2f64, OpNode>; 6290 } 6291 6292 let Predicates = [HasNEON, HasFullFP16] in { 6293 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6294 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6295 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6296 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6297 } 6298 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6299 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6300 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6301 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6302 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6303 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6304 let Predicates = [HasNEON, HasFullFP16] in { 6305 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6306 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6307 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6308 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6309 } 6310 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6311 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6312 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6313 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6314 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6315 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6316} 6317 6318let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 6319class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6320 RegisterOperand outtype, RegisterOperand intype, 6321 string asm, string VdTy, string VnTy, 6322 list<dag> pattern> 6323 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6324 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6325 Sched<[WriteVq]> { 6326 bits<5> Rd; 6327 bits<5> Rn; 6328 let Inst{31} = 0; 6329 let Inst{30} = Q; 6330 let Inst{29} = U; 6331 let Inst{28-24} = 0b01110; 6332 let Inst{23-22} = size; 6333 let Inst{21-17} = 0b10000; 6334 let Inst{16-12} = opcode; 6335 let Inst{11-10} = 0b10; 6336 let Inst{9-5} = Rn; 6337 let Inst{4-0} = Rd; 6338} 6339 6340let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 6341class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6342 RegisterOperand outtype, RegisterOperand intype, 6343 string asm, string VdTy, string VnTy, 6344 list<dag> pattern> 6345 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6346 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6347 Sched<[WriteVq]> { 6348 bits<5> Rd; 6349 bits<5> Rn; 6350 let Inst{31} = 0; 6351 let Inst{30} = Q; 6352 let Inst{29} = U; 6353 let Inst{28-24} = 0b01110; 6354 let Inst{23-22} = size; 6355 let Inst{21-17} = 0b10000; 6356 let Inst{16-12} = opcode; 6357 let Inst{11-10} = 0b10; 6358 let Inst{9-5} = Rn; 6359 let Inst{4-0} = Rd; 6360} 6361 6362multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6363 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6364 asm, ".4s", ".4h", []>; 6365 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6366 asm#"2", ".4s", ".8h", []>; 6367 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6368 asm, ".2d", ".2s", []>; 6369 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6370 asm#"2", ".2d", ".4s", []>; 6371} 6372 6373multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6374 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6375 asm, ".4h", ".4s", []>; 6376 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6377 asm#"2", ".8h", ".4s", []>; 6378 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6379 asm, ".2s", ".2d", []>; 6380 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6381 asm#"2", ".4s", ".2d", []>; 6382} 6383 6384multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6385 Intrinsic OpNode> { 6386 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6387 asm, ".2s", ".2d", 6388 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6389 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6390 asm#"2", ".4s", ".2d", []>; 6391 6392 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6393 (!cast<Instruction>(NAME # "v4f32") 6394 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6395} 6396 6397//---------------------------------------------------------------------------- 6398// AdvSIMD three register different-size vector instructions. 6399//---------------------------------------------------------------------------- 6400 6401let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6402class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6403 RegisterOperand outtype, RegisterOperand intype1, 6404 RegisterOperand intype2, string asm, 6405 string outkind, string inkind1, string inkind2, 6406 list<dag> pattern> 6407 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6408 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6409 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6410 Sched<[WriteVq]> { 6411 bits<5> Rd; 6412 bits<5> Rn; 6413 bits<5> Rm; 6414 let Inst{31} = 0; 6415 let Inst{30} = size{0}; 6416 let Inst{29} = U; 6417 let Inst{28-24} = 0b01110; 6418 let Inst{23-22} = size{2-1}; 6419 let Inst{21} = 1; 6420 let Inst{20-16} = Rm; 6421 let Inst{15-12} = opcode; 6422 let Inst{11-10} = 0b00; 6423 let Inst{9-5} = Rn; 6424 let Inst{4-0} = Rd; 6425} 6426 6427let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6428class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6429 RegisterOperand outtype, RegisterOperand intype1, 6430 RegisterOperand intype2, string asm, 6431 string outkind, string inkind1, string inkind2, 6432 list<dag> pattern> 6433 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6434 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6435 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6436 Sched<[WriteVq]> { 6437 bits<5> Rd; 6438 bits<5> Rn; 6439 bits<5> Rm; 6440 let Inst{31} = 0; 6441 let Inst{30} = size{0}; 6442 let Inst{29} = U; 6443 let Inst{28-24} = 0b01110; 6444 let Inst{23-22} = size{2-1}; 6445 let Inst{21} = 1; 6446 let Inst{20-16} = Rm; 6447 let Inst{15-12} = opcode; 6448 let Inst{11-10} = 0b00; 6449 let Inst{9-5} = Rn; 6450 let Inst{4-0} = Rd; 6451} 6452 6453// FIXME: TableGen doesn't know how to deal with expanded types that also 6454// change the element count (in this case, placing the results in 6455// the high elements of the result register rather than the low 6456// elements). Until that's fixed, we can't code-gen those. 6457multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6458 Intrinsic IntOp> { 6459 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6460 V64, V128, V128, 6461 asm, ".8b", ".8h", ".8h", 6462 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6463 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6464 V128, V128, V128, 6465 asm#"2", ".16b", ".8h", ".8h", 6466 []>; 6467 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6468 V64, V128, V128, 6469 asm, ".4h", ".4s", ".4s", 6470 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6471 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6472 V128, V128, V128, 6473 asm#"2", ".8h", ".4s", ".4s", 6474 []>; 6475 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6476 V64, V128, V128, 6477 asm, ".2s", ".2d", ".2d", 6478 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6479 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6480 V128, V128, V128, 6481 asm#"2", ".4s", ".2d", ".2d", 6482 []>; 6483 6484 6485 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6486 // a version attached to an instruction. 6487 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6488 (v8i16 V128:$Rm))), 6489 (!cast<Instruction>(NAME # "v8i16_v16i8") 6490 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6491 V128:$Rn, V128:$Rm)>; 6492 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6493 (v4i32 V128:$Rm))), 6494 (!cast<Instruction>(NAME # "v4i32_v8i16") 6495 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6496 V128:$Rn, V128:$Rm)>; 6497 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6498 (v2i64 V128:$Rm))), 6499 (!cast<Instruction>(NAME # "v2i64_v4i32") 6500 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6501 V128:$Rn, V128:$Rm)>; 6502} 6503 6504multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6505 Intrinsic IntOp> { 6506 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6507 V128, V64, V64, 6508 asm, ".8h", ".8b", ".8b", 6509 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6510 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6511 V128, V128, V128, 6512 asm#"2", ".8h", ".16b", ".16b", []>; 6513 let Predicates = [HasAES] in { 6514 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6515 V128, V64, V64, 6516 asm, ".1q", ".1d", ".1d", []>; 6517 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6518 V128, V128, V128, 6519 asm#"2", ".1q", ".2d", ".2d", []>; 6520 } 6521 6522 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6523 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6524 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6525} 6526 6527multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6528 SDPatternOperator OpNode> { 6529 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6530 V128, V64, V64, 6531 asm, ".4s", ".4h", ".4h", 6532 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6533 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6534 V128, V128, V128, 6535 asm#"2", ".4s", ".8h", ".8h", 6536 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6537 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6538 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6539 V128, V64, V64, 6540 asm, ".2d", ".2s", ".2s", 6541 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6542 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6543 V128, V128, V128, 6544 asm#"2", ".2d", ".4s", ".4s", 6545 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6546 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6547} 6548 6549multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6550 SDPatternOperator OpNode = null_frag> { 6551 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6552 V128, V64, V64, 6553 asm, ".8h", ".8b", ".8b", 6554 [(set (v8i16 V128:$Rd), 6555 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6556 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6557 V128, V128, V128, 6558 asm#"2", ".8h", ".16b", ".16b", 6559 [(set (v8i16 V128:$Rd), 6560 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6561 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 6562 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6563 V128, V64, V64, 6564 asm, ".4s", ".4h", ".4h", 6565 [(set (v4i32 V128:$Rd), 6566 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6567 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6568 V128, V128, V128, 6569 asm#"2", ".4s", ".8h", ".8h", 6570 [(set (v4i32 V128:$Rd), 6571 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6572 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6573 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6574 V128, V64, V64, 6575 asm, ".2d", ".2s", ".2s", 6576 [(set (v2i64 V128:$Rd), 6577 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6578 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6579 V128, V128, V128, 6580 asm#"2", ".2d", ".4s", ".4s", 6581 [(set (v2i64 V128:$Rd), 6582 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6583 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6584} 6585 6586multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6587 string asm, 6588 SDPatternOperator OpNode> { 6589 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6590 V128, V64, V64, 6591 asm, ".8h", ".8b", ".8b", 6592 [(set (v8i16 V128:$dst), 6593 (add (v8i16 V128:$Rd), 6594 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6595 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6596 V128, V128, V128, 6597 asm#"2", ".8h", ".16b", ".16b", 6598 [(set (v8i16 V128:$dst), 6599 (add (v8i16 V128:$Rd), 6600 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6601 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 6602 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6603 V128, V64, V64, 6604 asm, ".4s", ".4h", ".4h", 6605 [(set (v4i32 V128:$dst), 6606 (add (v4i32 V128:$Rd), 6607 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6608 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6609 V128, V128, V128, 6610 asm#"2", ".4s", ".8h", ".8h", 6611 [(set (v4i32 V128:$dst), 6612 (add (v4i32 V128:$Rd), 6613 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6614 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 6615 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6616 V128, V64, V64, 6617 asm, ".2d", ".2s", ".2s", 6618 [(set (v2i64 V128:$dst), 6619 (add (v2i64 V128:$Rd), 6620 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6621 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6622 V128, V128, V128, 6623 asm#"2", ".2d", ".4s", ".4s", 6624 [(set (v2i64 V128:$dst), 6625 (add (v2i64 V128:$Rd), 6626 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6627 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 6628} 6629 6630multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6631 SDPatternOperator OpNode = null_frag> { 6632 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6633 V128, V64, V64, 6634 asm, ".8h", ".8b", ".8b", 6635 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6636 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6637 V128, V128, V128, 6638 asm#"2", ".8h", ".16b", ".16b", 6639 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6640 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6641 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6642 V128, V64, V64, 6643 asm, ".4s", ".4h", ".4h", 6644 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6645 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6646 V128, V128, V128, 6647 asm#"2", ".4s", ".8h", ".8h", 6648 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6649 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6650 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6651 V128, V64, V64, 6652 asm, ".2d", ".2s", ".2s", 6653 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6654 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6655 V128, V128, V128, 6656 asm#"2", ".2d", ".4s", ".4s", 6657 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6658 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6659} 6660 6661multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6662 string asm, 6663 SDPatternOperator OpNode> { 6664 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6665 V128, V64, V64, 6666 asm, ".8h", ".8b", ".8b", 6667 [(set (v8i16 V128:$dst), 6668 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6669 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6670 V128, V128, V128, 6671 asm#"2", ".8h", ".16b", ".16b", 6672 [(set (v8i16 V128:$dst), 6673 (OpNode (v8i16 V128:$Rd), 6674 (extract_high_v16i8 (v16i8 V128:$Rn)), 6675 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6676 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6677 V128, V64, V64, 6678 asm, ".4s", ".4h", ".4h", 6679 [(set (v4i32 V128:$dst), 6680 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6681 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6682 V128, V128, V128, 6683 asm#"2", ".4s", ".8h", ".8h", 6684 [(set (v4i32 V128:$dst), 6685 (OpNode (v4i32 V128:$Rd), 6686 (extract_high_v8i16 (v8i16 V128:$Rn)), 6687 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6688 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6689 V128, V64, V64, 6690 asm, ".2d", ".2s", ".2s", 6691 [(set (v2i64 V128:$dst), 6692 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6693 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6694 V128, V128, V128, 6695 asm#"2", ".2d", ".4s", ".4s", 6696 [(set (v2i64 V128:$dst), 6697 (OpNode (v2i64 V128:$Rd), 6698 (extract_high_v4i32 (v4i32 V128:$Rn)), 6699 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6700} 6701 6702multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6703 SDPatternOperator Accum> { 6704 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6705 V128, V64, V64, 6706 asm, ".4s", ".4h", ".4h", 6707 [(set (v4i32 V128:$dst), 6708 (Accum (v4i32 V128:$Rd), 6709 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6710 (v4i16 V64:$Rm)))))]>; 6711 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6712 V128, V128, V128, 6713 asm#"2", ".4s", ".8h", ".8h", 6714 [(set (v4i32 V128:$dst), 6715 (Accum (v4i32 V128:$Rd), 6716 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 6717 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6718 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6719 V128, V64, V64, 6720 asm, ".2d", ".2s", ".2s", 6721 [(set (v2i64 V128:$dst), 6722 (Accum (v2i64 V128:$Rd), 6723 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6724 (v2i32 V64:$Rm)))))]>; 6725 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6726 V128, V128, V128, 6727 asm#"2", ".2d", ".4s", ".4s", 6728 [(set (v2i64 V128:$dst), 6729 (Accum (v2i64 V128:$Rd), 6730 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 6731 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6732} 6733 6734multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6735 SDPatternOperator OpNode> { 6736 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6737 V128, V128, V64, 6738 asm, ".8h", ".8h", ".8b", 6739 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6740 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6741 V128, V128, V128, 6742 asm#"2", ".8h", ".8h", ".16b", 6743 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6744 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6745 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6746 V128, V128, V64, 6747 asm, ".4s", ".4s", ".4h", 6748 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6749 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6750 V128, V128, V128, 6751 asm#"2", ".4s", ".4s", ".8h", 6752 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6753 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6754 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6755 V128, V128, V64, 6756 asm, ".2d", ".2d", ".2s", 6757 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6758 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6759 V128, V128, V128, 6760 asm#"2", ".2d", ".2d", ".4s", 6761 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6762 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6763} 6764 6765//---------------------------------------------------------------------------- 6766// AdvSIMD bitwise extract from vector 6767//---------------------------------------------------------------------------- 6768 6769class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6770 string asm, string kind> 6771 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6772 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6773 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6774 [(set (vty regtype:$Rd), 6775 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6776 Sched<[!if(size, WriteVq, WriteVd)]> { 6777 bits<5> Rd; 6778 bits<5> Rn; 6779 bits<5> Rm; 6780 bits<4> imm; 6781 let Inst{31} = 0; 6782 let Inst{30} = size; 6783 let Inst{29-21} = 0b101110000; 6784 let Inst{20-16} = Rm; 6785 let Inst{15} = 0; 6786 let Inst{14-11} = imm; 6787 let Inst{10} = 0; 6788 let Inst{9-5} = Rn; 6789 let Inst{4-0} = Rd; 6790} 6791 6792 6793multiclass SIMDBitwiseExtract<string asm> { 6794 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6795 let imm{3} = 0; 6796 } 6797 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6798} 6799 6800//---------------------------------------------------------------------------- 6801// AdvSIMD zip vector 6802//---------------------------------------------------------------------------- 6803 6804class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6805 string asm, string kind, SDNode OpNode, ValueType valty> 6806 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6807 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6808 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6809 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6810 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 6811 bits<5> Rd; 6812 bits<5> Rn; 6813 bits<5> Rm; 6814 let Inst{31} = 0; 6815 let Inst{30} = size{0}; 6816 let Inst{29-24} = 0b001110; 6817 let Inst{23-22} = size{2-1}; 6818 let Inst{21} = 0; 6819 let Inst{20-16} = Rm; 6820 let Inst{15} = 0; 6821 let Inst{14-12} = opc; 6822 let Inst{11-10} = 0b10; 6823 let Inst{9-5} = Rn; 6824 let Inst{4-0} = Rd; 6825} 6826 6827multiclass SIMDZipVector<bits<3>opc, string asm, 6828 SDNode OpNode> { 6829 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6830 asm, ".8b", OpNode, v8i8>; 6831 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6832 asm, ".16b", OpNode, v16i8>; 6833 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6834 asm, ".4h", OpNode, v4i16>; 6835 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6836 asm, ".8h", OpNode, v8i16>; 6837 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6838 asm, ".2s", OpNode, v2i32>; 6839 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6840 asm, ".4s", OpNode, v4i32>; 6841 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6842 asm, ".2d", OpNode, v2i64>; 6843 6844 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6845 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6846 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6847 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6848 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6849 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6850 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6851 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6852 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6853 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6854} 6855 6856//---------------------------------------------------------------------------- 6857// AdvSIMD three register scalar instructions 6858//---------------------------------------------------------------------------- 6859 6860let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6861class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6862 RegisterClass regtype, string asm, 6863 list<dag> pattern> 6864 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6865 "\t$Rd, $Rn, $Rm", "", pattern>, 6866 Sched<[WriteVd]> { 6867 bits<5> Rd; 6868 bits<5> Rn; 6869 bits<5> Rm; 6870 let Inst{31-30} = 0b01; 6871 let Inst{29} = U; 6872 let Inst{28-24} = 0b11110; 6873 let Inst{23-21} = size; 6874 let Inst{20-16} = Rm; 6875 let Inst{15-11} = opcode; 6876 let Inst{10} = 1; 6877 let Inst{9-5} = Rn; 6878 let Inst{4-0} = Rd; 6879} 6880 6881let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6882class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6883 dag oops, dag iops, string asm, 6884 list<dag> pattern> 6885 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6886 Sched<[WriteVd]> { 6887 bits<5> Rd; 6888 bits<5> Rn; 6889 bits<5> Rm; 6890 let Inst{31-30} = 0b01; 6891 let Inst{29} = U; 6892 let Inst{28-24} = 0b11110; 6893 let Inst{23-22} = size; 6894 let Inst{21} = R; 6895 let Inst{20-16} = Rm; 6896 let Inst{15-11} = opcode; 6897 let Inst{10} = 1; 6898 let Inst{9-5} = Rn; 6899 let Inst{4-0} = Rd; 6900} 6901 6902multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6903 SDPatternOperator OpNode> { 6904 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6905 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6906} 6907 6908multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6909 SDPatternOperator OpNode> { 6910 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6911 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6912 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6913 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6914 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6915 6916 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6917 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6918 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6919 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6920} 6921 6922multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6923 SDPatternOperator OpNode> { 6924 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6925 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6926 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6927} 6928 6929multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 6930 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6931 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6932 asm, []>; 6933 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6934 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6935 asm, []>; 6936} 6937 6938multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6939 SDPatternOperator OpNode = null_frag, 6940 Predicate pred = HasNEON> { 6941 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in { 6942 let Predicates = [pred] in { 6943 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6944 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6945 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6946 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6947 } 6948 let Predicates = [pred, HasFullFP16] in { 6949 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6950 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6951 } 6952 } 6953 6954 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6955 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6956} 6957 6958multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6959 SDPatternOperator OpNode = null_frag> { 6960 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in { 6961 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6962 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6963 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6964 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6965 let Predicates = [HasNEON, HasFullFP16] in { 6966 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6967 []>; 6968 } // Predicates = [HasNEON, HasFullFP16] 6969 } 6970 6971 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6972 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6973} 6974 6975class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6976 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6977 : I<oops, iops, asm, 6978 "\t$Rd, $Rn, $Rm", cstr, pat>, 6979 Sched<[WriteVd]> { 6980 bits<5> Rd; 6981 bits<5> Rn; 6982 bits<5> Rm; 6983 let Inst{31-30} = 0b01; 6984 let Inst{29} = U; 6985 let Inst{28-24} = 0b11110; 6986 let Inst{23-22} = size; 6987 let Inst{21} = 1; 6988 let Inst{20-16} = Rm; 6989 let Inst{15-11} = opcode; 6990 let Inst{10} = 0; 6991 let Inst{9-5} = Rn; 6992 let Inst{4-0} = Rd; 6993} 6994 6995let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6996multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6997 SDPatternOperator OpNode = null_frag> { 6998 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6999 (outs FPR32:$Rd), 7000 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 7001 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7002 (outs FPR64:$Rd), 7003 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7004 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7005} 7006 7007let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7008multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7009 SDPatternOperator OpNode = null_frag> { 7010 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7011 (outs FPR32:$dst), 7012 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7013 asm, "$Rd = $dst", []>; 7014 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7015 (outs FPR64:$dst), 7016 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7017 asm, "$Rd = $dst", 7018 [(set (i64 FPR64:$dst), 7019 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7020} 7021 7022//---------------------------------------------------------------------------- 7023// AdvSIMD two register scalar instructions 7024//---------------------------------------------------------------------------- 7025 7026let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7027class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7028 RegisterClass regtype, RegisterClass regtype2, 7029 string asm, list<dag> pat> 7030 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7031 "\t$Rd, $Rn", "", pat>, 7032 Sched<[WriteVd]> { 7033 bits<5> Rd; 7034 bits<5> Rn; 7035 let Inst{31-30} = 0b01; 7036 let Inst{29} = U; 7037 let Inst{28-24} = 0b11110; 7038 let Inst{23-22} = size; 7039 let Inst{21} = 0b1; 7040 let Inst{20-19} = size2; 7041 let Inst{18-17} = 0b00; 7042 let Inst{16-12} = opcode; 7043 let Inst{11-10} = 0b10; 7044 let Inst{9-5} = Rn; 7045 let Inst{4-0} = Rd; 7046} 7047 7048let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7049class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7050 RegisterClass regtype, RegisterClass regtype2, 7051 string asm, list<dag> pat> 7052 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7053 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7054 Sched<[WriteVd]> { 7055 bits<5> Rd; 7056 bits<5> Rn; 7057 let Inst{31-30} = 0b01; 7058 let Inst{29} = U; 7059 let Inst{28-24} = 0b11110; 7060 let Inst{23-22} = size; 7061 let Inst{21-17} = 0b10000; 7062 let Inst{16-12} = opcode; 7063 let Inst{11-10} = 0b10; 7064 let Inst{9-5} = Rn; 7065 let Inst{4-0} = Rd; 7066} 7067 7068 7069let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7070class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7071 RegisterClass regtype, string asm, string zero> 7072 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7073 "\t$Rd, $Rn, #" # zero, "", []>, 7074 Sched<[WriteVd]> { 7075 bits<5> Rd; 7076 bits<5> Rn; 7077 let Inst{31-30} = 0b01; 7078 let Inst{29} = U; 7079 let Inst{28-24} = 0b11110; 7080 let Inst{23-22} = size; 7081 let Inst{21} = 0b1; 7082 let Inst{20-19} = size2; 7083 let Inst{18-17} = 0b00; 7084 let Inst{16-12} = opcode; 7085 let Inst{11-10} = 0b10; 7086 let Inst{9-5} = Rn; 7087 let Inst{4-0} = Rd; 7088} 7089 7090let mayRaiseFPException = 1 in 7091class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7092 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7093 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7094 Sched<[WriteVd]> { 7095 bits<5> Rd; 7096 bits<5> Rn; 7097 let Inst{31-17} = 0b011111100110000; 7098 let Inst{16-12} = opcode; 7099 let Inst{11-10} = 0b10; 7100 let Inst{9-5} = Rn; 7101 let Inst{4-0} = Rd; 7102} 7103 7104multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7105 SDPatternOperator OpNode> { 7106 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7107 7108 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7109 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7110} 7111 7112multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7113 SDPatternOperator OpNode> { 7114 let mayRaiseFPException = 1 in { 7115 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7116 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7117 let Predicates = [HasNEON, HasFullFP16] in { 7118 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7119 } 7120 } 7121 7122 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7123 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7124 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7125 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7126 let Predicates = [HasNEON, HasFullFP16] in { 7127 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7128 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7129 } 7130 7131 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7132 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7133} 7134 7135multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7136 SDPatternOperator OpNode = null_frag> { 7137 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7138 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7139 7140 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7141 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7142} 7143 7144let mayRaiseFPException = 1 in 7145multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7146 Predicate pred = HasNEON> { 7147 let Predicates = [pred] in { 7148 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7149 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7150 } 7151 let Predicates = [pred, HasFullFP16] in { 7152 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7153 } 7154} 7155 7156let mayRaiseFPException = 1 in 7157multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7158 SDPatternOperator OpNode> { 7159 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7160 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7161 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7162 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7163 let Predicates = [HasNEON, HasFullFP16] in { 7164 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7165 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7166 } 7167} 7168 7169multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7170 SDPatternOperator OpNode = null_frag> { 7171 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7172 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7173 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7174 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7175 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7176 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7177 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7178 } 7179 7180 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7181 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7182} 7183 7184multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7185 Intrinsic OpNode> { 7186 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7187 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7188 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7189 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7190 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7191 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7192 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7193 } 7194 7195 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7196 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7197} 7198 7199 7200 7201let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7202multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7203 SDPatternOperator OpNode = null_frag> { 7204 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7205 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7206 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7207 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7208} 7209 7210//---------------------------------------------------------------------------- 7211// AdvSIMD scalar pairwise instructions 7212//---------------------------------------------------------------------------- 7213 7214let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7215class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7216 RegisterOperand regtype, RegisterOperand vectype, 7217 string asm, string kind> 7218 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7219 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7220 Sched<[WriteVd]> { 7221 bits<5> Rd; 7222 bits<5> Rn; 7223 let Inst{31-30} = 0b01; 7224 let Inst{29} = U; 7225 let Inst{28-24} = 0b11110; 7226 let Inst{23-22} = size; 7227 let Inst{21-17} = 0b11000; 7228 let Inst{16-12} = opcode; 7229 let Inst{11-10} = 0b10; 7230 let Inst{9-5} = Rn; 7231 let Inst{4-0} = Rd; 7232} 7233 7234multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7235 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7236 asm, ".2d">; 7237} 7238 7239let mayRaiseFPException = 1 in 7240multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7241 let Predicates = [HasNEON, HasFullFP16] in { 7242 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7243 asm, ".2h">; 7244 } 7245 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7246 asm, ".2s">; 7247 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7248 asm, ".2d">; 7249} 7250 7251//---------------------------------------------------------------------------- 7252// AdvSIMD across lanes instructions 7253//---------------------------------------------------------------------------- 7254 7255let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7256class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7257 RegisterClass regtype, RegisterOperand vectype, 7258 string asm, string kind, list<dag> pattern> 7259 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7260 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7261 Sched<[!if(Q, WriteVq, WriteVd)]> { 7262 bits<5> Rd; 7263 bits<5> Rn; 7264 let Inst{31} = 0; 7265 let Inst{30} = Q; 7266 let Inst{29} = U; 7267 let Inst{28-24} = 0b01110; 7268 let Inst{23-22} = size; 7269 let Inst{21-17} = 0b11000; 7270 let Inst{16-12} = opcode; 7271 let Inst{11-10} = 0b10; 7272 let Inst{9-5} = Rn; 7273 let Inst{4-0} = Rd; 7274} 7275 7276multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7277 string asm> { 7278 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7279 asm, ".8b", []>; 7280 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7281 asm, ".16b", []>; 7282 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7283 asm, ".4h", []>; 7284 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7285 asm, ".8h", []>; 7286 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7287 asm, ".4s", []>; 7288} 7289 7290multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7291 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7292 asm, ".8b", []>; 7293 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7294 asm, ".16b", []>; 7295 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7296 asm, ".4h", []>; 7297 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7298 asm, ".8h", []>; 7299 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7300 asm, ".4s", []>; 7301} 7302 7303let mayRaiseFPException = 1 in 7304multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7305 Intrinsic intOp> { 7306 let Predicates = [HasNEON, HasFullFP16] in { 7307 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7308 asm, ".4h", 7309 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7310 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7311 asm, ".8h", 7312 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7313 } // Predicates = [HasNEON, HasFullFP16] 7314 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7315 asm, ".4s", 7316 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7317} 7318 7319//---------------------------------------------------------------------------- 7320// AdvSIMD INS/DUP instructions 7321//---------------------------------------------------------------------------- 7322 7323// FIXME: There has got to be a better way to factor these. ugh. 7324 7325class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7326 string operands, string constraints, list<dag> pattern> 7327 : I<outs, ins, asm, operands, constraints, pattern>, 7328 Sched<[!if(Q, WriteVq, WriteVd)]> { 7329 bits<5> Rd; 7330 bits<5> Rn; 7331 let Inst{31} = 0; 7332 let Inst{30} = Q; 7333 let Inst{29} = op; 7334 let Inst{28-21} = 0b01110000; 7335 let Inst{15} = 0; 7336 let Inst{10} = 1; 7337 let Inst{9-5} = Rn; 7338 let Inst{4-0} = Rd; 7339} 7340 7341class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7342 RegisterOperand vecreg, RegisterClass regtype> 7343 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7344 "{\t$Rd" # size # ", $Rn" # 7345 "|" # size # "\t$Rd, $Rn}", "", 7346 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7347 let Inst{20-16} = imm5; 7348 let Inst{14-11} = 0b0001; 7349} 7350 7351class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7352 ValueType vectype, ValueType insreg, 7353 RegisterOperand vecreg, Operand idxtype, 7354 SDNode OpNode> 7355 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7356 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7357 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7358 [(set (vectype vecreg:$Rd), 7359 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7360 let Inst{14-11} = 0b0000; 7361} 7362 7363class SIMDDup64FromElement 7364 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7365 VectorIndexD, AArch64duplane64> { 7366 bits<1> idx; 7367 let Inst{20} = idx; 7368 let Inst{19-16} = 0b1000; 7369} 7370 7371class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7372 RegisterOperand vecreg> 7373 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7374 VectorIndexS, AArch64duplane32> { 7375 bits<2> idx; 7376 let Inst{20-19} = idx; 7377 let Inst{18-16} = 0b100; 7378} 7379 7380class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7381 RegisterOperand vecreg> 7382 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7383 VectorIndexH, AArch64duplane16> { 7384 bits<3> idx; 7385 let Inst{20-18} = idx; 7386 let Inst{17-16} = 0b10; 7387} 7388 7389class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7390 RegisterOperand vecreg> 7391 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7392 VectorIndexB, AArch64duplane8> { 7393 bits<4> idx; 7394 let Inst{20-17} = idx; 7395 let Inst{16} = 1; 7396} 7397 7398class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7399 Operand idxtype, string asm, list<dag> pattern> 7400 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7401 "{\t$Rd, $Rn" # size # "$idx" # 7402 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7403 let Inst{14-11} = imm4; 7404} 7405 7406class SIMDSMov<bit Q, string size, RegisterClass regtype, 7407 Operand idxtype> 7408 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7409class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7410 Operand idxtype> 7411 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7412 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7413 7414class SIMDMovAlias<string asm, string size, Instruction inst, 7415 RegisterClass regtype, Operand idxtype> 7416 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7417 "|" # size # "\t$dst, $src$idx}", 7418 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7419 7420multiclass SMov { 7421 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7422 // streaming mode. 7423 let Predicates = [HasNEONorSME] in { 7424 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7425 let Inst{20-16} = 0b00001; 7426 } 7427 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7428 let Inst{20-16} = 0b00001; 7429 } 7430 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7431 let Inst{20-16} = 0b00010; 7432 } 7433 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7434 let Inst{20-16} = 0b00010; 7435 } 7436 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7437 let Inst{20-16} = 0b00100; 7438 } 7439 } 7440 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7441 bits<4> idx; 7442 let Inst{20-17} = idx; 7443 let Inst{16} = 1; 7444 } 7445 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7446 bits<4> idx; 7447 let Inst{20-17} = idx; 7448 let Inst{16} = 1; 7449 } 7450 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7451 bits<3> idx; 7452 let Inst{20-18} = idx; 7453 let Inst{17-16} = 0b10; 7454 } 7455 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7456 bits<3> idx; 7457 let Inst{20-18} = idx; 7458 let Inst{17-16} = 0b10; 7459 } 7460 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7461 bits<2> idx; 7462 let Inst{20-19} = idx; 7463 let Inst{18-16} = 0b100; 7464 } 7465} 7466 7467multiclass UMov { 7468 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7469 // streaming mode. 7470 let Predicates = [HasNEONorSME] in { 7471 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7472 let Inst{20-16} = 0b00001; 7473 } 7474 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7475 let Inst{20-16} = 0b00010; 7476 } 7477 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7478 let Inst{20-16} = 0b00100; 7479 } 7480 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7481 let Inst{20-16} = 0b01000; 7482 } 7483 def : SIMDMovAlias<"mov", ".s", 7484 !cast<Instruction>(NAME # vi32_idx0), 7485 GPR32, VectorIndex0>; 7486 def : SIMDMovAlias<"mov", ".d", 7487 !cast<Instruction>(NAME # vi64_idx0), 7488 GPR64, VectorIndex0>; 7489 } 7490 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7491 bits<4> idx; 7492 let Inst{20-17} = idx; 7493 let Inst{16} = 1; 7494 } 7495 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7496 bits<3> idx; 7497 let Inst{20-18} = idx; 7498 let Inst{17-16} = 0b10; 7499 } 7500 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7501 bits<2> idx; 7502 let Inst{20-19} = idx; 7503 let Inst{18-16} = 0b100; 7504 } 7505 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7506 bits<1> idx; 7507 let Inst{20} = idx; 7508 let Inst{19-16} = 0b1000; 7509 } 7510 def : SIMDMovAlias<"mov", ".s", 7511 !cast<Instruction>(NAME#"vi32"), 7512 GPR32, VectorIndexS>; 7513 def : SIMDMovAlias<"mov", ".d", 7514 !cast<Instruction>(NAME#"vi64"), 7515 GPR64, VectorIndexD>; 7516} 7517 7518class SIMDInsFromMain<string size, ValueType vectype, 7519 RegisterClass regtype, Operand idxtype> 7520 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7521 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7522 "{\t$Rd" # size # "$idx, $Rn" # 7523 "|" # size # "\t$Rd$idx, $Rn}", 7524 "$Rd = $dst", 7525 [(set V128:$dst, 7526 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7527 let Inst{14-11} = 0b0011; 7528} 7529 7530class SIMDInsFromElement<string size, ValueType vectype, 7531 ValueType elttype, Operand idxtype> 7532 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7533 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7534 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7535 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7536 "$Rd = $dst", 7537 [(set V128:$dst, 7538 (vector_insert 7539 (vectype V128:$Rd), 7540 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7541 idxtype:$idx))]>; 7542 7543class SIMDInsMainMovAlias<string size, Instruction inst, 7544 RegisterClass regtype, Operand idxtype> 7545 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7546 "|" # size #"\t$dst$idx, $src}", 7547 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7548class SIMDInsElementMovAlias<string size, Instruction inst, 7549 Operand idxtype> 7550 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7551 # "|" # size #"\t$dst$idx, $src$idx2}", 7552 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7553 7554 7555multiclass SIMDIns { 7556 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7557 bits<4> idx; 7558 let Inst{20-17} = idx; 7559 let Inst{16} = 1; 7560 } 7561 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7562 bits<3> idx; 7563 let Inst{20-18} = idx; 7564 let Inst{17-16} = 0b10; 7565 } 7566 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7567 bits<2> idx; 7568 let Inst{20-19} = idx; 7569 let Inst{18-16} = 0b100; 7570 } 7571 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7572 bits<1> idx; 7573 let Inst{20} = idx; 7574 let Inst{19-16} = 0b1000; 7575 } 7576 7577 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7578 bits<4> idx; 7579 bits<4> idx2; 7580 let Inst{20-17} = idx; 7581 let Inst{16} = 1; 7582 let Inst{14-11} = idx2; 7583 } 7584 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7585 bits<3> idx; 7586 bits<3> idx2; 7587 let Inst{20-18} = idx; 7588 let Inst{17-16} = 0b10; 7589 let Inst{14-12} = idx2; 7590 let Inst{11} = {?}; 7591 } 7592 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7593 bits<2> idx; 7594 bits<2> idx2; 7595 let Inst{20-19} = idx; 7596 let Inst{18-16} = 0b100; 7597 let Inst{14-13} = idx2; 7598 let Inst{12-11} = {?,?}; 7599 } 7600 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7601 bits<1> idx; 7602 bits<1> idx2; 7603 let Inst{20} = idx; 7604 let Inst{19-16} = 0b1000; 7605 let Inst{14} = idx2; 7606 let Inst{13-11} = {?,?,?}; 7607 } 7608 7609 // For all forms of the INS instruction, the "mov" mnemonic is the 7610 // preferred alias. Why they didn't just call the instruction "mov" in 7611 // the first place is a very good question indeed... 7612 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7613 GPR32, VectorIndexB>; 7614 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7615 GPR32, VectorIndexH>; 7616 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7617 GPR32, VectorIndexS>; 7618 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7619 GPR64, VectorIndexD>; 7620 7621 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7622 VectorIndexB>; 7623 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7624 VectorIndexH>; 7625 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7626 VectorIndexS>; 7627 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7628 VectorIndexD>; 7629} 7630 7631//---------------------------------------------------------------------------- 7632// AdvSIMD TBL/TBX 7633//---------------------------------------------------------------------------- 7634 7635let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7636class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7637 RegisterOperand listtype, string asm, string kind> 7638 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7639 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7640 Sched<[!if(Q, WriteVq, WriteVd)]> { 7641 bits<5> Vd; 7642 bits<5> Vn; 7643 bits<5> Vm; 7644 let Inst{31} = 0; 7645 let Inst{30} = Q; 7646 let Inst{29-21} = 0b001110000; 7647 let Inst{20-16} = Vm; 7648 let Inst{15} = 0; 7649 let Inst{14-13} = len; 7650 let Inst{12} = op; 7651 let Inst{11-10} = 0b00; 7652 let Inst{9-5} = Vn; 7653 let Inst{4-0} = Vd; 7654} 7655 7656let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7657class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7658 RegisterOperand listtype, string asm, string kind> 7659 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7660 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7661 Sched<[!if(Q, WriteVq, WriteVd)]> { 7662 bits<5> Vd; 7663 bits<5> Vn; 7664 bits<5> Vm; 7665 let Inst{31} = 0; 7666 let Inst{30} = Q; 7667 let Inst{29-21} = 0b001110000; 7668 let Inst{20-16} = Vm; 7669 let Inst{15} = 0; 7670 let Inst{14-13} = len; 7671 let Inst{12} = op; 7672 let Inst{11-10} = 0b00; 7673 let Inst{9-5} = Vn; 7674 let Inst{4-0} = Vd; 7675} 7676 7677class SIMDTableLookupAlias<string asm, Instruction inst, 7678 RegisterOperand vectype, RegisterOperand listtype> 7679 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7680 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7681 7682multiclass SIMDTableLookup<bit op, string asm> { 7683 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7684 asm, ".8b">; 7685 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7686 asm, ".8b">; 7687 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7688 asm, ".8b">; 7689 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7690 asm, ".8b">; 7691 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7692 asm, ".16b">; 7693 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7694 asm, ".16b">; 7695 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7696 asm, ".16b">; 7697 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7698 asm, ".16b">; 7699 7700 def : SIMDTableLookupAlias<asm # ".8b", 7701 !cast<Instruction>(NAME#"v8i8One"), 7702 V64, VecListOne128>; 7703 def : SIMDTableLookupAlias<asm # ".8b", 7704 !cast<Instruction>(NAME#"v8i8Two"), 7705 V64, VecListTwo128>; 7706 def : SIMDTableLookupAlias<asm # ".8b", 7707 !cast<Instruction>(NAME#"v8i8Three"), 7708 V64, VecListThree128>; 7709 def : SIMDTableLookupAlias<asm # ".8b", 7710 !cast<Instruction>(NAME#"v8i8Four"), 7711 V64, VecListFour128>; 7712 def : SIMDTableLookupAlias<asm # ".16b", 7713 !cast<Instruction>(NAME#"v16i8One"), 7714 V128, VecListOne128>; 7715 def : SIMDTableLookupAlias<asm # ".16b", 7716 !cast<Instruction>(NAME#"v16i8Two"), 7717 V128, VecListTwo128>; 7718 def : SIMDTableLookupAlias<asm # ".16b", 7719 !cast<Instruction>(NAME#"v16i8Three"), 7720 V128, VecListThree128>; 7721 def : SIMDTableLookupAlias<asm # ".16b", 7722 !cast<Instruction>(NAME#"v16i8Four"), 7723 V128, VecListFour128>; 7724} 7725 7726multiclass SIMDTableLookupTied<bit op, string asm> { 7727 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7728 asm, ".8b">; 7729 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7730 asm, ".8b">; 7731 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7732 asm, ".8b">; 7733 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7734 asm, ".8b">; 7735 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7736 asm, ".16b">; 7737 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7738 asm, ".16b">; 7739 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7740 asm, ".16b">; 7741 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7742 asm, ".16b">; 7743 7744 def : SIMDTableLookupAlias<asm # ".8b", 7745 !cast<Instruction>(NAME#"v8i8One"), 7746 V64, VecListOne128>; 7747 def : SIMDTableLookupAlias<asm # ".8b", 7748 !cast<Instruction>(NAME#"v8i8Two"), 7749 V64, VecListTwo128>; 7750 def : SIMDTableLookupAlias<asm # ".8b", 7751 !cast<Instruction>(NAME#"v8i8Three"), 7752 V64, VecListThree128>; 7753 def : SIMDTableLookupAlias<asm # ".8b", 7754 !cast<Instruction>(NAME#"v8i8Four"), 7755 V64, VecListFour128>; 7756 def : SIMDTableLookupAlias<asm # ".16b", 7757 !cast<Instruction>(NAME#"v16i8One"), 7758 V128, VecListOne128>; 7759 def : SIMDTableLookupAlias<asm # ".16b", 7760 !cast<Instruction>(NAME#"v16i8Two"), 7761 V128, VecListTwo128>; 7762 def : SIMDTableLookupAlias<asm # ".16b", 7763 !cast<Instruction>(NAME#"v16i8Three"), 7764 V128, VecListThree128>; 7765 def : SIMDTableLookupAlias<asm # ".16b", 7766 !cast<Instruction>(NAME#"v16i8Four"), 7767 V128, VecListFour128>; 7768} 7769 7770 7771//---------------------------------------------------------------------------- 7772// AdvSIMD scalar DUP 7773//---------------------------------------------------------------------------- 7774let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7775class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 7776 string asm, string kind, Operand idxtype> 7777 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 7778 "{\t$dst, $src" # kind # "$idx" # 7779 "|\t$dst, $src$idx}", "", []>, 7780 Sched<[WriteVd]> { 7781 bits<5> dst; 7782 bits<5> src; 7783 let Inst{31-21} = 0b01011110000; 7784 let Inst{15-10} = 0b000001; 7785 let Inst{9-5} = src; 7786 let Inst{4-0} = dst; 7787} 7788 7789class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 7790 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7791 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7792 # "|\t$dst, $src$index}", 7793 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7794 7795 7796multiclass SIMDScalarDUP<string asm> { 7797 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 7798 bits<4> idx; 7799 let Inst{20-17} = idx; 7800 let Inst{16} = 1; 7801 } 7802 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 7803 bits<3> idx; 7804 let Inst{20-18} = idx; 7805 let Inst{17-16} = 0b10; 7806 } 7807 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 7808 bits<2> idx; 7809 let Inst{20-19} = idx; 7810 let Inst{18-16} = 0b100; 7811 } 7812 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 7813 bits<1> idx; 7814 let Inst{20} = idx; 7815 let Inst{19-16} = 0b1000; 7816 } 7817 7818 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7819 VectorIndexD:$idx)))), 7820 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7821 7822 // 'DUP' mnemonic aliases. 7823 def : SIMDScalarDUPAlias<"dup", ".b", 7824 !cast<Instruction>(NAME#"i8"), 7825 FPR8, V128, VectorIndexB>; 7826 def : SIMDScalarDUPAlias<"dup", ".h", 7827 !cast<Instruction>(NAME#"i16"), 7828 FPR16, V128, VectorIndexH>; 7829 def : SIMDScalarDUPAlias<"dup", ".s", 7830 !cast<Instruction>(NAME#"i32"), 7831 FPR32, V128, VectorIndexS>; 7832 def : SIMDScalarDUPAlias<"dup", ".d", 7833 !cast<Instruction>(NAME#"i64"), 7834 FPR64, V128, VectorIndexD>; 7835} 7836 7837//---------------------------------------------------------------------------- 7838// AdvSIMD modified immediate instructions 7839//---------------------------------------------------------------------------- 7840 7841class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7842 string asm, string op_string, 7843 string cstr, list<dag> pattern> 7844 : I<oops, iops, asm, op_string, cstr, pattern>, 7845 Sched<[!if(Q, WriteVq, WriteVd)]> { 7846 bits<5> Rd; 7847 bits<8> imm8; 7848 let Inst{31} = 0; 7849 let Inst{30} = Q; 7850 let Inst{29} = op; 7851 let Inst{28-19} = 0b0111100000; 7852 let Inst{18-16} = imm8{7-5}; 7853 let Inst{11} = op2; 7854 let Inst{10} = 1; 7855 let Inst{9-5} = imm8{4-0}; 7856 let Inst{4-0} = Rd; 7857} 7858 7859class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7860 Operand immtype, dag opt_shift_iop, 7861 string opt_shift, string asm, string kind, 7862 list<dag> pattern> 7863 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7864 !con((ins immtype:$imm8), opt_shift_iop), asm, 7865 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7866 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7867 "", pattern> { 7868 let DecoderMethod = "DecodeModImmInstruction"; 7869} 7870 7871class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7872 Operand immtype, dag opt_shift_iop, 7873 string opt_shift, string asm, string kind, 7874 list<dag> pattern> 7875 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7876 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7877 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7878 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7879 "$Rd = $dst", pattern> { 7880 let DecoderMethod = "DecodeModImmTiedInstruction"; 7881} 7882 7883class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7884 RegisterOperand vectype, string asm, 7885 string kind, list<dag> pattern> 7886 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7887 (ins logical_vec_shift:$shift), 7888 "$shift", asm, kind, pattern> { 7889 bits<2> shift; 7890 let Inst{15} = b15_b12{1}; 7891 let Inst{14-13} = shift; 7892 let Inst{12} = b15_b12{0}; 7893} 7894 7895class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7896 RegisterOperand vectype, string asm, 7897 string kind, list<dag> pattern> 7898 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7899 (ins logical_vec_shift:$shift), 7900 "$shift", asm, kind, pattern> { 7901 bits<2> shift; 7902 let Inst{15} = b15_b12{1}; 7903 let Inst{14-13} = shift; 7904 let Inst{12} = b15_b12{0}; 7905} 7906 7907 7908class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7909 RegisterOperand vectype, string asm, 7910 string kind, list<dag> pattern> 7911 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7912 (ins logical_vec_hw_shift:$shift), 7913 "$shift", asm, kind, pattern> { 7914 bits<2> shift; 7915 let Inst{15} = b15_b12{1}; 7916 let Inst{14} = 0; 7917 let Inst{13} = shift{0}; 7918 let Inst{12} = b15_b12{0}; 7919} 7920 7921class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7922 RegisterOperand vectype, string asm, 7923 string kind, list<dag> pattern> 7924 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7925 (ins logical_vec_hw_shift:$shift), 7926 "$shift", asm, kind, pattern> { 7927 bits<2> shift; 7928 let Inst{15} = b15_b12{1}; 7929 let Inst{14} = 0; 7930 let Inst{13} = shift{0}; 7931 let Inst{12} = b15_b12{0}; 7932} 7933 7934multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7935 string asm> { 7936 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7937 asm, ".4h", []>; 7938 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7939 asm, ".8h", []>; 7940 7941 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7942 asm, ".2s", []>; 7943 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7944 asm, ".4s", []>; 7945} 7946 7947multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7948 bits<2> w_cmode, string asm, 7949 SDNode OpNode> { 7950 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7951 asm, ".4h", 7952 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7953 imm0_255:$imm8, 7954 (i32 imm:$shift)))]>; 7955 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7956 asm, ".8h", 7957 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7958 imm0_255:$imm8, 7959 (i32 imm:$shift)))]>; 7960 7961 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7962 asm, ".2s", 7963 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7964 imm0_255:$imm8, 7965 (i32 imm:$shift)))]>; 7966 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7967 asm, ".4s", 7968 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7969 imm0_255:$imm8, 7970 (i32 imm:$shift)))]>; 7971} 7972 7973class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7974 RegisterOperand vectype, string asm, 7975 string kind, list<dag> pattern> 7976 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7977 (ins move_vec_shift:$shift), 7978 "$shift", asm, kind, pattern> { 7979 bits<1> shift; 7980 let Inst{15-13} = cmode{3-1}; 7981 let Inst{12} = shift; 7982} 7983 7984class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7985 RegisterOperand vectype, 7986 Operand imm_type, string asm, 7987 string kind, list<dag> pattern> 7988 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7989 asm, kind, pattern> { 7990 let Inst{15-12} = cmode; 7991} 7992 7993class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7994 list<dag> pattern> 7995 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7996 "\t$Rd, $imm8", "", pattern> { 7997 let Inst{15-12} = cmode; 7998 let DecoderMethod = "DecodeModImmInstruction"; 7999} 8000 8001//---------------------------------------------------------------------------- 8002// AdvSIMD indexed element 8003//---------------------------------------------------------------------------- 8004 8005let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8006class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8007 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8008 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8009 string apple_kind, string dst_kind, string lhs_kind, 8010 string rhs_kind, list<dag> pattern> 8011 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8012 asm, 8013 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8014 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8015 Sched<[WriteVd]> { 8016 bits<5> Rd; 8017 bits<5> Rn; 8018 bits<5> Rm; 8019 8020 let Inst{31} = 0; 8021 let Inst{30} = Q; 8022 let Inst{29} = U; 8023 let Inst{28} = Scalar; 8024 let Inst{27-24} = 0b1111; 8025 let Inst{23-22} = size; 8026 // Bit 21 must be set by the derived class. 8027 let Inst{20-16} = Rm; 8028 let Inst{15-12} = opc; 8029 // Bit 11 must be set by the derived class. 8030 let Inst{10} = 0; 8031 let Inst{9-5} = Rn; 8032 let Inst{4-0} = Rd; 8033} 8034 8035let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8036class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8037 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8038 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8039 string apple_kind, string dst_kind, string lhs_kind, 8040 string rhs_kind, list<dag> pattern> 8041 : I<(outs dst_reg:$dst), 8042 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8043 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8044 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8045 Sched<[WriteVd]> { 8046 bits<5> Rd; 8047 bits<5> Rn; 8048 bits<5> Rm; 8049 8050 let Inst{31} = 0; 8051 let Inst{30} = Q; 8052 let Inst{29} = U; 8053 let Inst{28} = Scalar; 8054 let Inst{27-24} = 0b1111; 8055 let Inst{23-22} = size; 8056 // Bit 21 must be set by the derived class. 8057 let Inst{20-16} = Rm; 8058 let Inst{15-12} = opc; 8059 // Bit 11 must be set by the derived class. 8060 let Inst{10} = 0; 8061 let Inst{9-5} = Rn; 8062 let Inst{4-0} = Rd; 8063} 8064 8065 8066//---------------------------------------------------------------------------- 8067// Armv8.6 BFloat16 Extension 8068//---------------------------------------------------------------------------- 8069let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8070 8071class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8072 string kind2, RegisterOperand RegType, 8073 ValueType AccumType, ValueType InputType> 8074 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8075 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8076 (InputType RegType:$Rn), 8077 (InputType RegType:$Rm)))]> { 8078 let AsmString = !strconcat(asm, 8079 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8080 ", $Rm" # kind2 # "}"); 8081} 8082 8083multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8084 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8085 v2f32, v4bf16>; 8086 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8087 v4f32, v8bf16>; 8088} 8089 8090class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8091 string dst_kind, string lhs_kind, 8092 string rhs_kind, 8093 RegisterOperand RegType, 8094 ValueType AccumType, 8095 ValueType InputType> 8096 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8097 RegType, RegType, V128, VectorIndexS, 8098 asm, "", dst_kind, lhs_kind, rhs_kind, 8099 [(set (AccumType RegType:$dst), 8100 (AccumType (int_aarch64_neon_bfdot 8101 (AccumType RegType:$Rd), 8102 (InputType RegType:$Rn), 8103 (InputType (bitconvert (AccumType 8104 (AArch64duplane32 (v4f32 V128:$Rm), 8105 VectorIndexS:$idx)))))))]> { 8106 8107 bits<2> idx; 8108 let Inst{21} = idx{0}; // L 8109 let Inst{11} = idx{1}; // H 8110} 8111 8112multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8113 8114 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8115 ".2h", V64, v2f32, v4bf16>; 8116 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8117 ".2h", V128, v4f32, v8bf16>; 8118} 8119 8120let mayRaiseFPException = 1 in 8121class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8122 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8123 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8124 (v8bf16 V128:$Rn), 8125 (v8bf16 V128:$Rm)))]> { 8126 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8127} 8128 8129let mayRaiseFPException = 1 in 8130class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8131 : I<(outs V128:$dst), 8132 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8133 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8134 [(set (v4f32 V128:$dst), 8135 (v4f32 (OpNode (v4f32 V128:$Rd), 8136 (v8bf16 V128:$Rn), 8137 (v8bf16 8138 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8139 VectorIndexH:$idx)))))]>, 8140 Sched<[WriteVq]> { 8141 bits<5> Rd; 8142 bits<5> Rn; 8143 bits<4> Rm; 8144 bits<3> idx; 8145 8146 let Inst{31} = 0; 8147 let Inst{30} = Q; 8148 let Inst{29-22} = 0b00111111; 8149 let Inst{21-20} = idx{1-0}; 8150 let Inst{19-16} = Rm; 8151 let Inst{15-12} = 0b1111; 8152 let Inst{11} = idx{2}; // H 8153 let Inst{10} = 0; 8154 let Inst{9-5} = Rn; 8155 let Inst{4-0} = Rd; 8156} 8157 8158class SIMDThreeSameVectorBF16MatrixMul<string asm> 8159 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8160 V128, asm, ".4s", 8161 [(set (v4f32 V128:$dst), 8162 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8163 (v8bf16 V128:$Rn), 8164 (v8bf16 V128:$Rm)))]> { 8165 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8166 ", $Rm", ".8h", "}"); 8167} 8168 8169let mayRaiseFPException = 1 in 8170class SIMD_BFCVTN 8171 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8172 "bfcvtn", ".4h", ".4s", 8173 [(set (v8bf16 V128:$Rd), 8174 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8175 8176let mayRaiseFPException = 1 in 8177class SIMD_BFCVTN2 8178 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8179 "bfcvtn2", ".8h", ".4s", 8180 [(set (v8bf16 V128:$dst), 8181 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8182 8183let mayRaiseFPException = 1 in 8184class BF16ToSinglePrecision<string asm> 8185 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8186 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8187 Sched<[WriteFCvt]> { 8188 bits<5> Rd; 8189 bits<5> Rn; 8190 let Inst{31-10} = 0b0001111001100011010000; 8191 let Inst{9-5} = Rn; 8192 let Inst{4-0} = Rd; 8193} 8194} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8195 8196//---------------------------------------------------------------------------- 8197// Armv8.6 Matrix Multiply Extension 8198//---------------------------------------------------------------------------- 8199 8200class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8201 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8202 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8203 (v16i8 V128:$Rn), 8204 (v16i8 V128:$Rm)))]> { 8205 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8206} 8207 8208//---------------------------------------------------------------------------- 8209// ARMv8.2-A Dot Product Instructions (Indexed) 8210class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8211 string dst_kind, string lhs_kind, string rhs_kind, 8212 RegisterOperand RegType, 8213 ValueType AccumType, ValueType InputType, 8214 SDPatternOperator OpNode> : 8215 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8216 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8217 [(set (AccumType RegType:$dst), 8218 (AccumType (OpNode (AccumType RegType:$Rd), 8219 (InputType RegType:$Rn), 8220 (InputType (bitconvert (AccumType 8221 (AArch64duplane32 (v4i32 V128:$Rm), 8222 VectorIndexS:$idx)))))))]> { 8223 bits<2> idx; 8224 let Inst{21} = idx{0}; // L 8225 let Inst{11} = idx{1}; // H 8226} 8227 8228multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8229 SDPatternOperator OpNode> { 8230 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8231 V64, v2i32, v8i8, OpNode>; 8232 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8233 V128, v4i32, v16i8, OpNode>; 8234} 8235 8236// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8237let mayRaiseFPException = 1 in 8238class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8239 string dst_kind, string lhs_kind, 8240 string rhs_kind, RegisterOperand RegType, 8241 ValueType AccumType, ValueType InputType, 8242 SDPatternOperator OpNode> : 8243 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8244 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8245 [(set (AccumType RegType:$dst), 8246 (AccumType (OpNode (AccumType RegType:$Rd), 8247 (InputType RegType:$Rn), 8248 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8249 VectorIndexH:$idx)))))]> { 8250 // idx = H:L:M 8251 bits<3> idx; 8252 let Inst{11} = idx{2}; // H 8253 let Inst{21} = idx{1}; // L 8254 let Inst{20} = idx{0}; // M 8255} 8256 8257multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8258 SDPatternOperator OpNode> { 8259 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8260 V64, v2f32, v4f16, OpNode>; 8261 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8262 V128, v4f32, v8f16, OpNode>; 8263} 8264 8265let mayRaiseFPException = 1 in 8266multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8267 SDPatternOperator OpNode> { 8268 let Predicates = [HasNEON, HasFullFP16] in { 8269 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8270 V64, V64, 8271 V128_lo, VectorIndexH, 8272 asm, ".4h", ".4h", ".4h", ".h", 8273 [(set (v4f16 V64:$Rd), 8274 (OpNode (v4f16 V64:$Rn), 8275 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8276 bits<3> idx; 8277 let Inst{11} = idx{2}; 8278 let Inst{21} = idx{1}; 8279 let Inst{20} = idx{0}; 8280 } 8281 8282 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8283 V128, V128, 8284 V128_lo, VectorIndexH, 8285 asm, ".8h", ".8h", ".8h", ".h", 8286 [(set (v8f16 V128:$Rd), 8287 (OpNode (v8f16 V128:$Rn), 8288 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8289 bits<3> idx; 8290 let Inst{11} = idx{2}; 8291 let Inst{21} = idx{1}; 8292 let Inst{20} = idx{0}; 8293 } 8294 } // Predicates = [HasNEON, HasFullFP16] 8295 8296 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8297 V64, V64, 8298 V128, VectorIndexS, 8299 asm, ".2s", ".2s", ".2s", ".s", 8300 [(set (v2f32 V64:$Rd), 8301 (OpNode (v2f32 V64:$Rn), 8302 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8303 bits<2> idx; 8304 let Inst{11} = idx{1}; 8305 let Inst{21} = idx{0}; 8306 } 8307 8308 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8309 V128, V128, 8310 V128, VectorIndexS, 8311 asm, ".4s", ".4s", ".4s", ".s", 8312 [(set (v4f32 V128:$Rd), 8313 (OpNode (v4f32 V128:$Rn), 8314 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8315 bits<2> idx; 8316 let Inst{11} = idx{1}; 8317 let Inst{21} = idx{0}; 8318 } 8319 8320 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8321 V128, V128, 8322 V128, VectorIndexD, 8323 asm, ".2d", ".2d", ".2d", ".d", 8324 [(set (v2f64 V128:$Rd), 8325 (OpNode (v2f64 V128:$Rn), 8326 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8327 bits<1> idx; 8328 let Inst{11} = idx{0}; 8329 let Inst{21} = 0; 8330 } 8331 8332 let Predicates = [HasNEON, HasFullFP16] in { 8333 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8334 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8335 asm, ".h", "", "", ".h", 8336 [(set (f16 FPR16Op:$Rd), 8337 (OpNode (f16 FPR16Op:$Rn), 8338 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8339 VectorIndexH:$idx))))]> { 8340 bits<3> idx; 8341 let Inst{11} = idx{2}; 8342 let Inst{21} = idx{1}; 8343 let Inst{20} = idx{0}; 8344 } 8345 } // Predicates = [HasNEON, HasFullFP16] 8346 8347 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8348 FPR32Op, FPR32Op, V128, VectorIndexS, 8349 asm, ".s", "", "", ".s", 8350 [(set (f32 FPR32Op:$Rd), 8351 (OpNode (f32 FPR32Op:$Rn), 8352 (f32 (vector_extract (v4f32 V128:$Rm), 8353 VectorIndexS:$idx))))]> { 8354 bits<2> idx; 8355 let Inst{11} = idx{1}; 8356 let Inst{21} = idx{0}; 8357 } 8358 8359 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8360 FPR64Op, FPR64Op, V128, VectorIndexD, 8361 asm, ".d", "", "", ".d", 8362 [(set (f64 FPR64Op:$Rd), 8363 (OpNode (f64 FPR64Op:$Rn), 8364 (f64 (vector_extract (v2f64 V128:$Rm), 8365 VectorIndexD:$idx))))]> { 8366 bits<1> idx; 8367 let Inst{11} = idx{0}; 8368 let Inst{21} = 0; 8369 } 8370} 8371 8372multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8373 let Predicates = [HasNEON, HasFullFP16] in { 8374 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8375 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8376 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8377 VectorIndexH:$idx))), 8378 (!cast<Instruction>(INST # "v8i16_indexed") 8379 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8380 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8381 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8382 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8383 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8384 8385 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8386 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8387 VectorIndexH:$idx))), 8388 (!cast<Instruction>(INST # "v4i16_indexed") 8389 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8390 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8391 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8392 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8393 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8394 8395 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8396 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8397 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8398 V128_lo:$Rm, VectorIndexH:$idx)>; 8399 } // Predicates = [HasNEON, HasFullFP16] 8400 8401 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8402 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8403 (AArch64duplane32 (v4f32 V128:$Rm), 8404 VectorIndexS:$idx))), 8405 (!cast<Instruction>(INST # v2i32_indexed) 8406 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8407 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8408 (AArch64dup (f32 FPR32Op:$Rm)))), 8409 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8410 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8411 8412 8413 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8414 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8415 (AArch64duplane32 (v4f32 V128:$Rm), 8416 VectorIndexS:$idx))), 8417 (!cast<Instruction>(INST # "v4i32_indexed") 8418 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8419 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8420 (AArch64dup (f32 FPR32Op:$Rm)))), 8421 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8422 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8423 8424 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8425 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8426 (AArch64duplane64 (v2f64 V128:$Rm), 8427 VectorIndexD:$idx))), 8428 (!cast<Instruction>(INST # "v2i64_indexed") 8429 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8430 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8431 (AArch64dup (f64 FPR64Op:$Rm)))), 8432 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8433 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8434 8435 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8436 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8437 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8438 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8439 V128:$Rm, VectorIndexS:$idx)>; 8440 8441 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8442 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8443 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8444 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8445 V128:$Rm, VectorIndexD:$idx)>; 8446} 8447 8448let mayRaiseFPException = 1 in 8449multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8450 let Predicates = [HasNEON, HasFullFP16] in { 8451 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8452 V128_lo, VectorIndexH, 8453 asm, ".4h", ".4h", ".4h", ".h", []> { 8454 bits<3> idx; 8455 let Inst{11} = idx{2}; 8456 let Inst{21} = idx{1}; 8457 let Inst{20} = idx{0}; 8458 } 8459 8460 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8461 V128, V128, 8462 V128_lo, VectorIndexH, 8463 asm, ".8h", ".8h", ".8h", ".h", []> { 8464 bits<3> idx; 8465 let Inst{11} = idx{2}; 8466 let Inst{21} = idx{1}; 8467 let Inst{20} = idx{0}; 8468 } 8469 } // Predicates = [HasNEON, HasFullFP16] 8470 8471 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8472 V128, VectorIndexS, 8473 asm, ".2s", ".2s", ".2s", ".s", []> { 8474 bits<2> idx; 8475 let Inst{11} = idx{1}; 8476 let Inst{21} = idx{0}; 8477 } 8478 8479 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8480 V128, V128, 8481 V128, VectorIndexS, 8482 asm, ".4s", ".4s", ".4s", ".s", []> { 8483 bits<2> idx; 8484 let Inst{11} = idx{1}; 8485 let Inst{21} = idx{0}; 8486 } 8487 8488 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8489 V128, V128, 8490 V128, VectorIndexD, 8491 asm, ".2d", ".2d", ".2d", ".d", []> { 8492 bits<1> idx; 8493 let Inst{11} = idx{0}; 8494 let Inst{21} = 0; 8495 } 8496 8497 let Predicates = [HasNEON, HasFullFP16] in { 8498 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8499 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8500 asm, ".h", "", "", ".h", []> { 8501 bits<3> idx; 8502 let Inst{11} = idx{2}; 8503 let Inst{21} = idx{1}; 8504 let Inst{20} = idx{0}; 8505 } 8506 } // Predicates = [HasNEON, HasFullFP16] 8507 8508 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8509 FPR32Op, FPR32Op, V128, VectorIndexS, 8510 asm, ".s", "", "", ".s", []> { 8511 bits<2> idx; 8512 let Inst{11} = idx{1}; 8513 let Inst{21} = idx{0}; 8514 } 8515 8516 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8517 FPR64Op, FPR64Op, V128, VectorIndexD, 8518 asm, ".d", "", "", ".d", []> { 8519 bits<1> idx; 8520 let Inst{11} = idx{0}; 8521 let Inst{21} = 0; 8522 } 8523} 8524 8525multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8526 SDPatternOperator OpNodeLaneQ> { 8527 8528 def : Pat<(v4i16 (OpNodeLane 8529 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8530 VectorIndexS32b:$idx)), 8531 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8532 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8533 (UImmS1XForm $idx))>; 8534 8535 def : Pat<(v4i16 (OpNodeLaneQ 8536 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8537 VectorIndexH32b:$idx)), 8538 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8539 (UImmS1XForm $idx))>; 8540 8541 def : Pat<(v8i16 (OpNodeLane 8542 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8543 VectorIndexS32b:$idx)), 8544 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8545 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8546 (UImmS1XForm $idx))>; 8547 8548 def : Pat<(v8i16 (OpNodeLaneQ 8549 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8550 VectorIndexH32b:$idx)), 8551 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8552 (UImmS1XForm $idx))>; 8553 8554 def : Pat<(v2i32 (OpNodeLane 8555 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8556 VectorIndexD32b:$idx)), 8557 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8558 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8559 (UImmS1XForm $idx))>; 8560 8561 def : Pat<(v2i32 (OpNodeLaneQ 8562 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8563 VectorIndexS32b:$idx)), 8564 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8565 (UImmS1XForm $idx))>; 8566 8567 def : Pat<(v4i32 (OpNodeLane 8568 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8569 VectorIndexD32b:$idx)), 8570 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8571 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8572 (UImmS1XForm $idx))>; 8573 8574 def : Pat<(v4i32 (OpNodeLaneQ 8575 (v4i32 V128:$Rn), 8576 (v4i32 V128:$Rm), 8577 VectorIndexS32b:$idx)), 8578 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8579 (UImmS1XForm $idx))>; 8580 8581} 8582 8583multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8584 SDPatternOperator OpNode> { 8585 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8586 V128_lo, VectorIndexH, 8587 asm, ".4h", ".4h", ".4h", ".h", 8588 [(set (v4i16 V64:$Rd), 8589 (OpNode (v4i16 V64:$Rn), 8590 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8591 bits<3> idx; 8592 let Inst{11} = idx{2}; 8593 let Inst{21} = idx{1}; 8594 let Inst{20} = idx{0}; 8595 } 8596 8597 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8598 V128, V128, 8599 V128_lo, VectorIndexH, 8600 asm, ".8h", ".8h", ".8h", ".h", 8601 [(set (v8i16 V128:$Rd), 8602 (OpNode (v8i16 V128:$Rn), 8603 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8604 bits<3> idx; 8605 let Inst{11} = idx{2}; 8606 let Inst{21} = idx{1}; 8607 let Inst{20} = idx{0}; 8608 } 8609 8610 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8611 V64, V64, 8612 V128, VectorIndexS, 8613 asm, ".2s", ".2s", ".2s", ".s", 8614 [(set (v2i32 V64:$Rd), 8615 (OpNode (v2i32 V64:$Rn), 8616 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8617 bits<2> idx; 8618 let Inst{11} = idx{1}; 8619 let Inst{21} = idx{0}; 8620 } 8621 8622 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8623 V128, V128, 8624 V128, VectorIndexS, 8625 asm, ".4s", ".4s", ".4s", ".s", 8626 [(set (v4i32 V128:$Rd), 8627 (OpNode (v4i32 V128:$Rn), 8628 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8629 bits<2> idx; 8630 let Inst{11} = idx{1}; 8631 let Inst{21} = idx{0}; 8632 } 8633 8634 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8635 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8636 asm, ".h", "", "", ".h", []> { 8637 bits<3> idx; 8638 let Inst{11} = idx{2}; 8639 let Inst{21} = idx{1}; 8640 let Inst{20} = idx{0}; 8641 } 8642 8643 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8644 FPR32Op, FPR32Op, V128, VectorIndexS, 8645 asm, ".s", "", "", ".s", 8646 [(set (i32 FPR32Op:$Rd), 8647 (OpNode FPR32Op:$Rn, 8648 (i32 (vector_extract (v4i32 V128:$Rm), 8649 VectorIndexS:$idx))))]> { 8650 bits<2> idx; 8651 let Inst{11} = idx{1}; 8652 let Inst{21} = idx{0}; 8653 } 8654} 8655 8656multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8657 SDPatternOperator OpNode> { 8658 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8659 V64, V64, 8660 V128_lo, VectorIndexH, 8661 asm, ".4h", ".4h", ".4h", ".h", 8662 [(set (v4i16 V64:$Rd), 8663 (OpNode (v4i16 V64:$Rn), 8664 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8665 bits<3> idx; 8666 let Inst{11} = idx{2}; 8667 let Inst{21} = idx{1}; 8668 let Inst{20} = idx{0}; 8669 } 8670 8671 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8672 V128, V128, 8673 V128_lo, VectorIndexH, 8674 asm, ".8h", ".8h", ".8h", ".h", 8675 [(set (v8i16 V128:$Rd), 8676 (OpNode (v8i16 V128:$Rn), 8677 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8678 bits<3> idx; 8679 let Inst{11} = idx{2}; 8680 let Inst{21} = idx{1}; 8681 let Inst{20} = idx{0}; 8682 } 8683 8684 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8685 V64, V64, 8686 V128, VectorIndexS, 8687 asm, ".2s", ".2s", ".2s", ".s", 8688 [(set (v2i32 V64:$Rd), 8689 (OpNode (v2i32 V64:$Rn), 8690 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8691 bits<2> idx; 8692 let Inst{11} = idx{1}; 8693 let Inst{21} = idx{0}; 8694 } 8695 8696 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8697 V128, V128, 8698 V128, VectorIndexS, 8699 asm, ".4s", ".4s", ".4s", ".s", 8700 [(set (v4i32 V128:$Rd), 8701 (OpNode (v4i32 V128:$Rn), 8702 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8703 bits<2> idx; 8704 let Inst{11} = idx{1}; 8705 let Inst{21} = idx{0}; 8706 } 8707} 8708 8709multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8710 SDPatternOperator OpNode> { 8711 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8712 V128_lo, VectorIndexH, 8713 asm, ".4h", ".4h", ".4h", ".h", 8714 [(set (v4i16 V64:$dst), 8715 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8716 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8717 bits<3> idx; 8718 let Inst{11} = idx{2}; 8719 let Inst{21} = idx{1}; 8720 let Inst{20} = idx{0}; 8721 } 8722 8723 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8724 V128, V128, 8725 V128_lo, VectorIndexH, 8726 asm, ".8h", ".8h", ".8h", ".h", 8727 [(set (v8i16 V128:$dst), 8728 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8729 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8730 bits<3> idx; 8731 let Inst{11} = idx{2}; 8732 let Inst{21} = idx{1}; 8733 let Inst{20} = idx{0}; 8734 } 8735 8736 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8737 V64, V64, 8738 V128, VectorIndexS, 8739 asm, ".2s", ".2s", ".2s", ".s", 8740 [(set (v2i32 V64:$dst), 8741 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8742 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8743 bits<2> idx; 8744 let Inst{11} = idx{1}; 8745 let Inst{21} = idx{0}; 8746 } 8747 8748 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8749 V128, V128, 8750 V128, VectorIndexS, 8751 asm, ".4s", ".4s", ".4s", ".s", 8752 [(set (v4i32 V128:$dst), 8753 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8754 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8755 bits<2> idx; 8756 let Inst{11} = idx{1}; 8757 let Inst{21} = idx{0}; 8758 } 8759} 8760 8761multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8762 SDPatternOperator OpNode> { 8763 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8764 V128, V64, 8765 V128_lo, VectorIndexH, 8766 asm, ".4s", ".4s", ".4h", ".h", 8767 [(set (v4i32 V128:$Rd), 8768 (OpNode (v4i16 V64:$Rn), 8769 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8770 bits<3> idx; 8771 let Inst{11} = idx{2}; 8772 let Inst{21} = idx{1}; 8773 let Inst{20} = idx{0}; 8774 } 8775 8776 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8777 V128, V128, 8778 V128_lo, VectorIndexH, 8779 asm#"2", ".4s", ".4s", ".8h", ".h", 8780 [(set (v4i32 V128:$Rd), 8781 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 8782 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8783 8784 bits<3> idx; 8785 let Inst{11} = idx{2}; 8786 let Inst{21} = idx{1}; 8787 let Inst{20} = idx{0}; 8788 } 8789 8790 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8791 V128, V64, 8792 V128, VectorIndexS, 8793 asm, ".2d", ".2d", ".2s", ".s", 8794 [(set (v2i64 V128:$Rd), 8795 (OpNode (v2i32 V64:$Rn), 8796 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8797 bits<2> idx; 8798 let Inst{11} = idx{1}; 8799 let Inst{21} = idx{0}; 8800 } 8801 8802 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8803 V128, V128, 8804 V128, VectorIndexS, 8805 asm#"2", ".2d", ".2d", ".4s", ".s", 8806 [(set (v2i64 V128:$Rd), 8807 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 8808 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8809 bits<2> idx; 8810 let Inst{11} = idx{1}; 8811 let Inst{21} = idx{0}; 8812 } 8813 8814 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8815 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8816 asm, ".h", "", "", ".h", []> { 8817 bits<3> idx; 8818 let Inst{11} = idx{2}; 8819 let Inst{21} = idx{1}; 8820 let Inst{20} = idx{0}; 8821 } 8822 8823 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8824 FPR64Op, FPR32Op, V128, VectorIndexS, 8825 asm, ".s", "", "", ".s", []> { 8826 bits<2> idx; 8827 let Inst{11} = idx{1}; 8828 let Inst{21} = idx{0}; 8829 } 8830} 8831 8832multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8833 SDPatternOperator Accum> { 8834 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8835 V128, V64, 8836 V128_lo, VectorIndexH, 8837 asm, ".4s", ".4s", ".4h", ".h", 8838 [(set (v4i32 V128:$dst), 8839 (Accum (v4i32 V128:$Rd), 8840 (v4i32 (int_aarch64_neon_sqdmull 8841 (v4i16 V64:$Rn), 8842 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8843 VectorIndexH:$idx))))))]> { 8844 bits<3> idx; 8845 let Inst{11} = idx{2}; 8846 let Inst{21} = idx{1}; 8847 let Inst{20} = idx{0}; 8848 } 8849 8850 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8851 // intermediate EXTRACT_SUBREG would be untyped. 8852 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8853 (i32 (vector_extract (v4i32 8854 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8855 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8856 VectorIndexH:$idx)))), 8857 (i64 0))))), 8858 (EXTRACT_SUBREG 8859 (!cast<Instruction>(NAME # v4i16_indexed) 8860 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8861 V128_lo:$Rm, VectorIndexH:$idx), 8862 ssub)>; 8863 8864 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8865 V128, V128, 8866 V128_lo, VectorIndexH, 8867 asm#"2", ".4s", ".4s", ".8h", ".h", 8868 [(set (v4i32 V128:$dst), 8869 (Accum (v4i32 V128:$Rd), 8870 (v4i32 (int_aarch64_neon_sqdmull 8871 (extract_high_v8i16 (v8i16 V128:$Rn)), 8872 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 8873 bits<3> idx; 8874 let Inst{11} = idx{2}; 8875 let Inst{21} = idx{1}; 8876 let Inst{20} = idx{0}; 8877 } 8878 8879 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8880 V128, V64, 8881 V128, VectorIndexS, 8882 asm, ".2d", ".2d", ".2s", ".s", 8883 [(set (v2i64 V128:$dst), 8884 (Accum (v2i64 V128:$Rd), 8885 (v2i64 (int_aarch64_neon_sqdmull 8886 (v2i32 V64:$Rn), 8887 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8888 VectorIndexS:$idx))))))]> { 8889 bits<2> idx; 8890 let Inst{11} = idx{1}; 8891 let Inst{21} = idx{0}; 8892 } 8893 8894 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8895 V128, V128, 8896 V128, VectorIndexS, 8897 asm#"2", ".2d", ".2d", ".4s", ".s", 8898 [(set (v2i64 V128:$dst), 8899 (Accum (v2i64 V128:$Rd), 8900 (v2i64 (int_aarch64_neon_sqdmull 8901 (extract_high_v4i32 (v4i32 V128:$Rn)), 8902 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 8903 bits<2> idx; 8904 let Inst{11} = idx{1}; 8905 let Inst{21} = idx{0}; 8906 } 8907 8908 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8909 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8910 asm, ".h", "", "", ".h", []> { 8911 bits<3> idx; 8912 let Inst{11} = idx{2}; 8913 let Inst{21} = idx{1}; 8914 let Inst{20} = idx{0}; 8915 } 8916 8917 8918 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8919 FPR64Op, FPR32Op, V128, VectorIndexS, 8920 asm, ".s", "", "", ".s", 8921 [(set (i64 FPR64Op:$dst), 8922 (Accum (i64 FPR64Op:$Rd), 8923 (i64 (int_aarch64_neon_sqdmulls_scalar 8924 (i32 FPR32Op:$Rn), 8925 (i32 (vector_extract (v4i32 V128:$Rm), 8926 VectorIndexS:$idx))))))]> { 8927 8928 bits<2> idx; 8929 let Inst{11} = idx{1}; 8930 let Inst{21} = idx{0}; 8931 } 8932} 8933 8934multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8935 SDPatternOperator OpNode> { 8936 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8937 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8938 V128, V64, 8939 V128_lo, VectorIndexH, 8940 asm, ".4s", ".4s", ".4h", ".h", 8941 [(set (v4i32 V128:$Rd), 8942 (OpNode (v4i16 V64:$Rn), 8943 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8944 bits<3> idx; 8945 let Inst{11} = idx{2}; 8946 let Inst{21} = idx{1}; 8947 let Inst{20} = idx{0}; 8948 } 8949 8950 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8951 V128, V128, 8952 V128_lo, VectorIndexH, 8953 asm#"2", ".4s", ".4s", ".8h", ".h", 8954 [(set (v4i32 V128:$Rd), 8955 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 8956 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8957 8958 bits<3> idx; 8959 let Inst{11} = idx{2}; 8960 let Inst{21} = idx{1}; 8961 let Inst{20} = idx{0}; 8962 } 8963 8964 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8965 V128, V64, 8966 V128, VectorIndexS, 8967 asm, ".2d", ".2d", ".2s", ".s", 8968 [(set (v2i64 V128:$Rd), 8969 (OpNode (v2i32 V64:$Rn), 8970 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8971 bits<2> idx; 8972 let Inst{11} = idx{1}; 8973 let Inst{21} = idx{0}; 8974 } 8975 8976 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8977 V128, V128, 8978 V128, VectorIndexS, 8979 asm#"2", ".2d", ".2d", ".4s", ".s", 8980 [(set (v2i64 V128:$Rd), 8981 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 8982 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8983 bits<2> idx; 8984 let Inst{11} = idx{1}; 8985 let Inst{21} = idx{0}; 8986 } 8987 } 8988} 8989 8990multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8991 SDPatternOperator OpNode> { 8992 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8993 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8994 V128, V64, 8995 V128_lo, VectorIndexH, 8996 asm, ".4s", ".4s", ".4h", ".h", 8997 [(set (v4i32 V128:$dst), 8998 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8999 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9000 bits<3> idx; 9001 let Inst{11} = idx{2}; 9002 let Inst{21} = idx{1}; 9003 let Inst{20} = idx{0}; 9004 } 9005 9006 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9007 V128, V128, 9008 V128_lo, VectorIndexH, 9009 asm#"2", ".4s", ".4s", ".8h", ".h", 9010 [(set (v4i32 V128:$dst), 9011 (OpNode (v4i32 V128:$Rd), 9012 (extract_high_v8i16 (v8i16 V128:$Rn)), 9013 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9014 bits<3> idx; 9015 let Inst{11} = idx{2}; 9016 let Inst{21} = idx{1}; 9017 let Inst{20} = idx{0}; 9018 } 9019 9020 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9021 V128, V64, 9022 V128, VectorIndexS, 9023 asm, ".2d", ".2d", ".2s", ".s", 9024 [(set (v2i64 V128:$dst), 9025 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9026 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9027 bits<2> idx; 9028 let Inst{11} = idx{1}; 9029 let Inst{21} = idx{0}; 9030 } 9031 9032 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9033 V128, V128, 9034 V128, VectorIndexS, 9035 asm#"2", ".2d", ".2d", ".4s", ".s", 9036 [(set (v2i64 V128:$dst), 9037 (OpNode (v2i64 V128:$Rd), 9038 (extract_high_v4i32 (v4i32 V128:$Rn)), 9039 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9040 bits<2> idx; 9041 let Inst{11} = idx{1}; 9042 let Inst{21} = idx{0}; 9043 } 9044 } 9045} 9046 9047//---------------------------------------------------------------------------- 9048// AdvSIMD scalar shift by immediate 9049//---------------------------------------------------------------------------- 9050 9051let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9052class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9053 RegisterClass regtype1, RegisterClass regtype2, 9054 Operand immtype, string asm, list<dag> pattern> 9055 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9056 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9057 Sched<[WriteVd]> { 9058 bits<5> Rd; 9059 bits<5> Rn; 9060 bits<7> imm; 9061 let Inst{31-30} = 0b01; 9062 let Inst{29} = U; 9063 let Inst{28-23} = 0b111110; 9064 let Inst{22-16} = fixed_imm; 9065 let Inst{15-11} = opc; 9066 let Inst{10} = 1; 9067 let Inst{9-5} = Rn; 9068 let Inst{4-0} = Rd; 9069} 9070 9071let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9072class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9073 RegisterClass regtype1, RegisterClass regtype2, 9074 Operand immtype, string asm, list<dag> pattern> 9075 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9076 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9077 Sched<[WriteVd]> { 9078 bits<5> Rd; 9079 bits<5> Rn; 9080 bits<7> imm; 9081 let Inst{31-30} = 0b01; 9082 let Inst{29} = U; 9083 let Inst{28-23} = 0b111110; 9084 let Inst{22-16} = fixed_imm; 9085 let Inst{15-11} = opc; 9086 let Inst{10} = 1; 9087 let Inst{9-5} = Rn; 9088 let Inst{4-0} = Rd; 9089} 9090 9091 9092multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9093 let Predicates = [HasNEON, HasFullFP16] in { 9094 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9095 FPR16, FPR16, vecshiftR16, asm, []> { 9096 let Inst{19-16} = imm{3-0}; 9097 } 9098 } // Predicates = [HasNEON, HasFullFP16] 9099 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9100 FPR32, FPR32, vecshiftR32, asm, []> { 9101 let Inst{20-16} = imm{4-0}; 9102 } 9103 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9104 FPR64, FPR64, vecshiftR64, asm, []> { 9105 let Inst{21-16} = imm{5-0}; 9106 } 9107} 9108 9109multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9110 SDPatternOperator OpNode> { 9111 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9112 FPR64, FPR64, vecshiftR64, asm, 9113 [(set (i64 FPR64:$Rd), 9114 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9115 let Inst{21-16} = imm{5-0}; 9116 } 9117 9118 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9119 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9120} 9121 9122multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9123 SDPatternOperator OpNode = null_frag> { 9124 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9125 FPR64, FPR64, vecshiftR64, asm, 9126 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9127 (i32 vecshiftR64:$imm)))]> { 9128 let Inst{21-16} = imm{5-0}; 9129 } 9130 9131 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9132 (i32 vecshiftR64:$imm))), 9133 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9134 vecshiftR64:$imm)>; 9135} 9136 9137multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9138 SDPatternOperator OpNode> { 9139 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9140 FPR64, FPR64, vecshiftL64, asm, 9141 [(set (i64 FPR64:$Rd), 9142 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9143 let Inst{21-16} = imm{5-0}; 9144 } 9145 9146 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9147 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9148} 9149 9150let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9151multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9152 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9153 FPR64, FPR64, vecshiftL64, asm, []> { 9154 let Inst{21-16} = imm{5-0}; 9155 } 9156} 9157 9158let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9159multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9160 SDPatternOperator OpNode = null_frag> { 9161 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9162 FPR8, FPR16, vecshiftR8, asm, []> { 9163 let Inst{18-16} = imm{2-0}; 9164 } 9165 9166 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9167 FPR16, FPR32, vecshiftR16, asm, []> { 9168 let Inst{19-16} = imm{3-0}; 9169 } 9170 9171 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9172 FPR32, FPR64, vecshiftR32, asm, 9173 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9174 let Inst{20-16} = imm{4-0}; 9175 } 9176} 9177 9178multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9179 SDPatternOperator OpNode> { 9180 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9181 FPR8, FPR8, vecshiftL8, asm, []> { 9182 let Inst{18-16} = imm{2-0}; 9183 } 9184 9185 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9186 FPR16, FPR16, vecshiftL16, asm, []> { 9187 let Inst{19-16} = imm{3-0}; 9188 } 9189 9190 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9191 FPR32, FPR32, vecshiftL32, asm, 9192 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9193 let Inst{20-16} = imm{4-0}; 9194 } 9195 9196 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9197 FPR64, FPR64, vecshiftL64, asm, 9198 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9199 let Inst{21-16} = imm{5-0}; 9200 } 9201 9202 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9203 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9204} 9205 9206multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9207 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9208 FPR8, FPR8, vecshiftR8, asm, []> { 9209 let Inst{18-16} = imm{2-0}; 9210 } 9211 9212 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9213 FPR16, FPR16, vecshiftR16, asm, []> { 9214 let Inst{19-16} = imm{3-0}; 9215 } 9216 9217 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9218 FPR32, FPR32, vecshiftR32, asm, []> { 9219 let Inst{20-16} = imm{4-0}; 9220 } 9221 9222 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9223 FPR64, FPR64, vecshiftR64, asm, []> { 9224 let Inst{21-16} = imm{5-0}; 9225 } 9226} 9227 9228//---------------------------------------------------------------------------- 9229// AdvSIMD vector x indexed element 9230//---------------------------------------------------------------------------- 9231 9232let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9233class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9234 RegisterOperand dst_reg, RegisterOperand src_reg, 9235 Operand immtype, 9236 string asm, string dst_kind, string src_kind, 9237 list<dag> pattern> 9238 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9239 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9240 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9241 Sched<[!if(Q, WriteVq, WriteVd)]> { 9242 bits<5> Rd; 9243 bits<5> Rn; 9244 let Inst{31} = 0; 9245 let Inst{30} = Q; 9246 let Inst{29} = U; 9247 let Inst{28-23} = 0b011110; 9248 let Inst{22-16} = fixed_imm; 9249 let Inst{15-11} = opc; 9250 let Inst{10} = 1; 9251 let Inst{9-5} = Rn; 9252 let Inst{4-0} = Rd; 9253} 9254 9255let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9256class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9257 RegisterOperand vectype1, RegisterOperand vectype2, 9258 Operand immtype, 9259 string asm, string dst_kind, string src_kind, 9260 list<dag> pattern> 9261 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9262 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9263 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9264 Sched<[!if(Q, WriteVq, WriteVd)]> { 9265 bits<5> Rd; 9266 bits<5> Rn; 9267 let Inst{31} = 0; 9268 let Inst{30} = Q; 9269 let Inst{29} = U; 9270 let Inst{28-23} = 0b011110; 9271 let Inst{22-16} = fixed_imm; 9272 let Inst{15-11} = opc; 9273 let Inst{10} = 1; 9274 let Inst{9-5} = Rn; 9275 let Inst{4-0} = Rd; 9276} 9277 9278multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9279 Intrinsic OpNode> { 9280 let Predicates = [HasNEON, HasFullFP16] in { 9281 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9282 V64, V64, vecshiftR16, 9283 asm, ".4h", ".4h", 9284 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9285 bits<4> imm; 9286 let Inst{19-16} = imm; 9287 } 9288 9289 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9290 V128, V128, vecshiftR16, 9291 asm, ".8h", ".8h", 9292 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9293 bits<4> imm; 9294 let Inst{19-16} = imm; 9295 } 9296 } // Predicates = [HasNEON, HasFullFP16] 9297 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9298 V64, V64, vecshiftR32, 9299 asm, ".2s", ".2s", 9300 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9301 bits<5> imm; 9302 let Inst{20-16} = imm; 9303 } 9304 9305 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9306 V128, V128, vecshiftR32, 9307 asm, ".4s", ".4s", 9308 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9309 bits<5> imm; 9310 let Inst{20-16} = imm; 9311 } 9312 9313 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9314 V128, V128, vecshiftR64, 9315 asm, ".2d", ".2d", 9316 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9317 bits<6> imm; 9318 let Inst{21-16} = imm; 9319 } 9320} 9321 9322multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9323 Intrinsic OpNode> { 9324 let Predicates = [HasNEON, HasFullFP16] in { 9325 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9326 V64, V64, vecshiftR16, 9327 asm, ".4h", ".4h", 9328 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9329 bits<4> imm; 9330 let Inst{19-16} = imm; 9331 } 9332 9333 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9334 V128, V128, vecshiftR16, 9335 asm, ".8h", ".8h", 9336 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9337 bits<4> imm; 9338 let Inst{19-16} = imm; 9339 } 9340 } // Predicates = [HasNEON, HasFullFP16] 9341 9342 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9343 V64, V64, vecshiftR32, 9344 asm, ".2s", ".2s", 9345 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9346 bits<5> imm; 9347 let Inst{20-16} = imm; 9348 } 9349 9350 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9351 V128, V128, vecshiftR32, 9352 asm, ".4s", ".4s", 9353 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9354 bits<5> imm; 9355 let Inst{20-16} = imm; 9356 } 9357 9358 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9359 V128, V128, vecshiftR64, 9360 asm, ".2d", ".2d", 9361 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9362 bits<6> imm; 9363 let Inst{21-16} = imm; 9364 } 9365} 9366 9367multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9368 SDPatternOperator OpNode> { 9369 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9370 V64, V128, vecshiftR16Narrow, 9371 asm, ".8b", ".8h", 9372 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9373 bits<3> imm; 9374 let Inst{18-16} = imm; 9375 } 9376 9377 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9378 V128, V128, vecshiftR16Narrow, 9379 asm#"2", ".16b", ".8h", []> { 9380 bits<3> imm; 9381 let Inst{18-16} = imm; 9382 let hasSideEffects = 0; 9383 } 9384 9385 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9386 V64, V128, vecshiftR32Narrow, 9387 asm, ".4h", ".4s", 9388 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9389 bits<4> imm; 9390 let Inst{19-16} = imm; 9391 } 9392 9393 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9394 V128, V128, vecshiftR32Narrow, 9395 asm#"2", ".8h", ".4s", []> { 9396 bits<4> imm; 9397 let Inst{19-16} = imm; 9398 let hasSideEffects = 0; 9399 } 9400 9401 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9402 V64, V128, vecshiftR64Narrow, 9403 asm, ".2s", ".2d", 9404 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9405 bits<5> imm; 9406 let Inst{20-16} = imm; 9407 } 9408 9409 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9410 V128, V128, vecshiftR64Narrow, 9411 asm#"2", ".4s", ".2d", []> { 9412 bits<5> imm; 9413 let Inst{20-16} = imm; 9414 let hasSideEffects = 0; 9415 } 9416 9417 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9418 // themselves, so put them here instead. 9419 9420 // Patterns involving what's effectively an insert high and a normal 9421 // intrinsic, represented by CONCAT_VECTORS. 9422 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9423 vecshiftR16Narrow:$imm)), 9424 (!cast<Instruction>(NAME # "v16i8_shift") 9425 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9426 V128:$Rn, vecshiftR16Narrow:$imm)>; 9427 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9428 vecshiftR32Narrow:$imm)), 9429 (!cast<Instruction>(NAME # "v8i16_shift") 9430 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9431 V128:$Rn, vecshiftR32Narrow:$imm)>; 9432 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9433 vecshiftR64Narrow:$imm)), 9434 (!cast<Instruction>(NAME # "v4i32_shift") 9435 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9436 V128:$Rn, vecshiftR64Narrow:$imm)>; 9437} 9438 9439multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9440 SDPatternOperator OpNode> { 9441 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9442 V64, V64, vecshiftL8, 9443 asm, ".8b", ".8b", 9444 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9445 (i32 vecshiftL8:$imm)))]> { 9446 bits<3> imm; 9447 let Inst{18-16} = imm; 9448 } 9449 9450 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9451 V128, V128, vecshiftL8, 9452 asm, ".16b", ".16b", 9453 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9454 (i32 vecshiftL8:$imm)))]> { 9455 bits<3> imm; 9456 let Inst{18-16} = imm; 9457 } 9458 9459 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9460 V64, V64, vecshiftL16, 9461 asm, ".4h", ".4h", 9462 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9463 (i32 vecshiftL16:$imm)))]> { 9464 bits<4> imm; 9465 let Inst{19-16} = imm; 9466 } 9467 9468 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9469 V128, V128, vecshiftL16, 9470 asm, ".8h", ".8h", 9471 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9472 (i32 vecshiftL16:$imm)))]> { 9473 bits<4> imm; 9474 let Inst{19-16} = imm; 9475 } 9476 9477 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9478 V64, V64, vecshiftL32, 9479 asm, ".2s", ".2s", 9480 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9481 (i32 vecshiftL32:$imm)))]> { 9482 bits<5> imm; 9483 let Inst{20-16} = imm; 9484 } 9485 9486 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9487 V128, V128, vecshiftL32, 9488 asm, ".4s", ".4s", 9489 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9490 (i32 vecshiftL32:$imm)))]> { 9491 bits<5> imm; 9492 let Inst{20-16} = imm; 9493 } 9494 9495 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9496 V128, V128, vecshiftL64, 9497 asm, ".2d", ".2d", 9498 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9499 (i32 vecshiftL64:$imm)))]> { 9500 bits<6> imm; 9501 let Inst{21-16} = imm; 9502 } 9503} 9504 9505multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9506 SDPatternOperator OpNode> { 9507 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9508 V64, V64, vecshiftR8, 9509 asm, ".8b", ".8b", 9510 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9511 (i32 vecshiftR8:$imm)))]> { 9512 bits<3> imm; 9513 let Inst{18-16} = imm; 9514 } 9515 9516 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9517 V128, V128, vecshiftR8, 9518 asm, ".16b", ".16b", 9519 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9520 (i32 vecshiftR8:$imm)))]> { 9521 bits<3> imm; 9522 let Inst{18-16} = imm; 9523 } 9524 9525 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9526 V64, V64, vecshiftR16, 9527 asm, ".4h", ".4h", 9528 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9529 (i32 vecshiftR16:$imm)))]> { 9530 bits<4> imm; 9531 let Inst{19-16} = imm; 9532 } 9533 9534 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9535 V128, V128, vecshiftR16, 9536 asm, ".8h", ".8h", 9537 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9538 (i32 vecshiftR16:$imm)))]> { 9539 bits<4> imm; 9540 let Inst{19-16} = imm; 9541 } 9542 9543 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9544 V64, V64, vecshiftR32, 9545 asm, ".2s", ".2s", 9546 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9547 (i32 vecshiftR32:$imm)))]> { 9548 bits<5> imm; 9549 let Inst{20-16} = imm; 9550 } 9551 9552 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9553 V128, V128, vecshiftR32, 9554 asm, ".4s", ".4s", 9555 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9556 (i32 vecshiftR32:$imm)))]> { 9557 bits<5> imm; 9558 let Inst{20-16} = imm; 9559 } 9560 9561 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9562 V128, V128, vecshiftR64, 9563 asm, ".2d", ".2d", 9564 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9565 (i32 vecshiftR64:$imm)))]> { 9566 bits<6> imm; 9567 let Inst{21-16} = imm; 9568 } 9569} 9570 9571let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9572multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9573 SDPatternOperator OpNode = null_frag> { 9574 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9575 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9576 [(set (v8i8 V64:$dst), 9577 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9578 (i32 vecshiftR8:$imm)))]> { 9579 bits<3> imm; 9580 let Inst{18-16} = imm; 9581 } 9582 9583 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9584 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9585 [(set (v16i8 V128:$dst), 9586 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9587 (i32 vecshiftR8:$imm)))]> { 9588 bits<3> imm; 9589 let Inst{18-16} = imm; 9590 } 9591 9592 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9593 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9594 [(set (v4i16 V64:$dst), 9595 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9596 (i32 vecshiftR16:$imm)))]> { 9597 bits<4> imm; 9598 let Inst{19-16} = imm; 9599 } 9600 9601 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9602 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9603 [(set (v8i16 V128:$dst), 9604 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9605 (i32 vecshiftR16:$imm)))]> { 9606 bits<4> imm; 9607 let Inst{19-16} = imm; 9608 } 9609 9610 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9611 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9612 [(set (v2i32 V64:$dst), 9613 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9614 (i32 vecshiftR32:$imm)))]> { 9615 bits<5> imm; 9616 let Inst{20-16} = imm; 9617 } 9618 9619 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9620 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9621 [(set (v4i32 V128:$dst), 9622 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9623 (i32 vecshiftR32:$imm)))]> { 9624 bits<5> imm; 9625 let Inst{20-16} = imm; 9626 } 9627 9628 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9629 V128, V128, vecshiftR64, 9630 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9631 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9632 (i32 vecshiftR64:$imm)))]> { 9633 bits<6> imm; 9634 let Inst{21-16} = imm; 9635 } 9636} 9637 9638multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9639 SDPatternOperator OpNode = null_frag> { 9640 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9641 V64, V64, vecshiftL8, 9642 asm, ".8b", ".8b", 9643 [(set (v8i8 V64:$dst), 9644 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9645 (i32 vecshiftL8:$imm)))]> { 9646 bits<3> imm; 9647 let Inst{18-16} = imm; 9648 } 9649 9650 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9651 V128, V128, vecshiftL8, 9652 asm, ".16b", ".16b", 9653 [(set (v16i8 V128:$dst), 9654 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9655 (i32 vecshiftL8:$imm)))]> { 9656 bits<3> imm; 9657 let Inst{18-16} = imm; 9658 } 9659 9660 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9661 V64, V64, vecshiftL16, 9662 asm, ".4h", ".4h", 9663 [(set (v4i16 V64:$dst), 9664 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9665 (i32 vecshiftL16:$imm)))]> { 9666 bits<4> imm; 9667 let Inst{19-16} = imm; 9668 } 9669 9670 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9671 V128, V128, vecshiftL16, 9672 asm, ".8h", ".8h", 9673 [(set (v8i16 V128:$dst), 9674 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9675 (i32 vecshiftL16:$imm)))]> { 9676 bits<4> imm; 9677 let Inst{19-16} = imm; 9678 } 9679 9680 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9681 V64, V64, vecshiftL32, 9682 asm, ".2s", ".2s", 9683 [(set (v2i32 V64:$dst), 9684 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9685 (i32 vecshiftL32:$imm)))]> { 9686 bits<5> imm; 9687 let Inst{20-16} = imm; 9688 } 9689 9690 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9691 V128, V128, vecshiftL32, 9692 asm, ".4s", ".4s", 9693 [(set (v4i32 V128:$dst), 9694 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9695 (i32 vecshiftL32:$imm)))]> { 9696 bits<5> imm; 9697 let Inst{20-16} = imm; 9698 } 9699 9700 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9701 V128, V128, vecshiftL64, 9702 asm, ".2d", ".2d", 9703 [(set (v2i64 V128:$dst), 9704 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9705 (i32 vecshiftL64:$imm)))]> { 9706 bits<6> imm; 9707 let Inst{21-16} = imm; 9708 } 9709} 9710 9711multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9712 SDPatternOperator OpNode> { 9713 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9714 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9715 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9716 bits<3> imm; 9717 let Inst{18-16} = imm; 9718 } 9719 9720 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9721 V128, V128, vecshiftL8, 9722 asm#"2", ".8h", ".16b", 9723 [(set (v8i16 V128:$Rd), 9724 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 9725 bits<3> imm; 9726 let Inst{18-16} = imm; 9727 } 9728 9729 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9730 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9731 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9732 bits<4> imm; 9733 let Inst{19-16} = imm; 9734 } 9735 9736 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9737 V128, V128, vecshiftL16, 9738 asm#"2", ".4s", ".8h", 9739 [(set (v4i32 V128:$Rd), 9740 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 9741 9742 bits<4> imm; 9743 let Inst{19-16} = imm; 9744 } 9745 9746 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9747 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9748 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9749 bits<5> imm; 9750 let Inst{20-16} = imm; 9751 } 9752 9753 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9754 V128, V128, vecshiftL32, 9755 asm#"2", ".2d", ".4s", 9756 [(set (v2i64 V128:$Rd), 9757 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 9758 bits<5> imm; 9759 let Inst{20-16} = imm; 9760 } 9761} 9762 9763 9764//--- 9765// Vector load/store 9766//--- 9767// SIMD ldX/stX no-index memory references don't allow the optional 9768// ", #0" constant and handle post-indexing explicitly, so we use 9769// a more specialized parse method for them. Otherwise, it's the same as 9770// the general GPR64sp handling. 9771 9772class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9773 string asm, dag oops, dag iops, list<dag> pattern> 9774 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9775 bits<5> Vt; 9776 bits<5> Rn; 9777 let Inst{31} = 0; 9778 let Inst{30} = Q; 9779 let Inst{29-23} = 0b0011000; 9780 let Inst{22} = L; 9781 let Inst{21-16} = 0b000000; 9782 let Inst{15-12} = opcode; 9783 let Inst{11-10} = size; 9784 let Inst{9-5} = Rn; 9785 let Inst{4-0} = Vt; 9786} 9787 9788class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9789 string asm, dag oops, dag iops> 9790 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9791 bits<5> Vt; 9792 bits<5> Rn; 9793 bits<5> Xm; 9794 let Inst{31} = 0; 9795 let Inst{30} = Q; 9796 let Inst{29-23} = 0b0011001; 9797 let Inst{22} = L; 9798 let Inst{21} = 0; 9799 let Inst{20-16} = Xm; 9800 let Inst{15-12} = opcode; 9801 let Inst{11-10} = size; 9802 let Inst{9-5} = Rn; 9803 let Inst{4-0} = Vt; 9804} 9805 9806// The immediate form of AdvSIMD post-indexed addressing is encoded with 9807// register post-index addressing from the zero register. 9808multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9809 int Offset, int Size> { 9810 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9811 // "ld1\t$Vt, [$Rn], #16" 9812 // may get mapped to 9813 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9814 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9815 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9816 GPR64sp:$Rn, 9817 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9818 XZR), 1>; 9819 9820 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9821 // "ld1.8b\t$Vt, [$Rn], #16" 9822 // may get mapped to 9823 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9824 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9825 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9826 GPR64sp:$Rn, 9827 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9828 XZR), 0>; 9829 9830 // E.g. "ld1.8b { v0, v1 }, [x1]" 9831 // "ld1\t$Vt, [$Rn]" 9832 // may get mapped to 9833 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9834 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9835 (!cast<Instruction>(BaseName # Count # "v" # layout) 9836 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9837 GPR64sp:$Rn), 0>; 9838 9839 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9840 // "ld1\t$Vt, [$Rn], $Xm" 9841 // may get mapped to 9842 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9843 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9844 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9845 GPR64sp:$Rn, 9846 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9847 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9848} 9849 9850multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9851 int Offset128, int Offset64, bits<4> opcode> { 9852 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9853 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9854 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9855 (ins GPR64sp:$Rn), []>; 9856 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9857 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9858 (ins GPR64sp:$Rn), []>; 9859 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9860 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9861 (ins GPR64sp:$Rn), []>; 9862 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9863 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9864 (ins GPR64sp:$Rn), []>; 9865 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9866 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9867 (ins GPR64sp:$Rn), []>; 9868 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9869 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9870 (ins GPR64sp:$Rn), []>; 9871 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9872 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9873 (ins GPR64sp:$Rn), []>; 9874 9875 9876 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9877 (outs GPR64sp:$wback, 9878 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9879 (ins GPR64sp:$Rn, 9880 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9881 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9882 (outs GPR64sp:$wback, 9883 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9884 (ins GPR64sp:$Rn, 9885 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9886 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9887 (outs GPR64sp:$wback, 9888 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9889 (ins GPR64sp:$Rn, 9890 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9891 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9892 (outs GPR64sp:$wback, 9893 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9894 (ins GPR64sp:$Rn, 9895 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9896 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9897 (outs GPR64sp:$wback, 9898 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9899 (ins GPR64sp:$Rn, 9900 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9901 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9902 (outs GPR64sp:$wback, 9903 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9904 (ins GPR64sp:$Rn, 9905 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9906 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9907 (outs GPR64sp:$wback, 9908 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9909 (ins GPR64sp:$Rn, 9910 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9911 } 9912 9913 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9914 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9915 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9916 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9917 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9918 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9919 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9920} 9921 9922// Only ld1/st1 has a v1d version. 9923multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9924 int Offset128, int Offset64, bits<4> opcode> { 9925 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9926 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9927 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9928 GPR64sp:$Rn), []>; 9929 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9930 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9931 GPR64sp:$Rn), []>; 9932 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9933 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9934 GPR64sp:$Rn), []>; 9935 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9936 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9937 GPR64sp:$Rn), []>; 9938 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9939 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9940 GPR64sp:$Rn), []>; 9941 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9942 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9943 GPR64sp:$Rn), []>; 9944 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9945 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9946 GPR64sp:$Rn), []>; 9947 9948 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9949 (outs GPR64sp:$wback), 9950 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9951 GPR64sp:$Rn, 9952 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9953 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9954 (outs GPR64sp:$wback), 9955 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9956 GPR64sp:$Rn, 9957 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9958 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9959 (outs GPR64sp:$wback), 9960 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9961 GPR64sp:$Rn, 9962 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9963 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9964 (outs GPR64sp:$wback), 9965 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9966 GPR64sp:$Rn, 9967 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9968 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9969 (outs GPR64sp:$wback), 9970 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9971 GPR64sp:$Rn, 9972 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9973 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9974 (outs GPR64sp:$wback), 9975 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9976 GPR64sp:$Rn, 9977 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9978 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9979 (outs GPR64sp:$wback), 9980 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9981 GPR64sp:$Rn, 9982 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9983 } 9984 9985 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9986 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9987 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9988 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9989 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9990 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9991 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9992} 9993 9994multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9995 int Offset128, int Offset64, bits<4> opcode> 9996 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9997 9998 // LD1 instructions have extra "1d" variants. 9999 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10000 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 10001 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 10002 (ins GPR64sp:$Rn), []>; 10003 10004 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 10005 (outs GPR64sp:$wback, 10006 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10007 (ins GPR64sp:$Rn, 10008 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10009 } 10010 10011 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10012} 10013 10014multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10015 int Offset128, int Offset64, bits<4> opcode> 10016 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10017 10018 // ST1 instructions have extra "1d" variants. 10019 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10020 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10021 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10022 GPR64sp:$Rn), []>; 10023 10024 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10025 (outs GPR64sp:$wback), 10026 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10027 GPR64sp:$Rn, 10028 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10029 } 10030 10031 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10032} 10033 10034multiclass SIMDLd1Multiple<string asm> { 10035 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10036 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10037 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10038 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10039} 10040 10041multiclass SIMDSt1Multiple<string asm> { 10042 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10043 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10044 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10045 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10046} 10047 10048multiclass SIMDLd2Multiple<string asm> { 10049 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10050} 10051 10052multiclass SIMDSt2Multiple<string asm> { 10053 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10054} 10055 10056multiclass SIMDLd3Multiple<string asm> { 10057 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10058} 10059 10060multiclass SIMDSt3Multiple<string asm> { 10061 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10062} 10063 10064multiclass SIMDLd4Multiple<string asm> { 10065 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10066} 10067 10068multiclass SIMDSt4Multiple<string asm> { 10069 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10070} 10071 10072//--- 10073// AdvSIMD Load/store single-element 10074//--- 10075 10076class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10077 string asm, string operands, string cst, 10078 dag oops, dag iops, list<dag> pattern> 10079 : I<oops, iops, asm, operands, cst, pattern> { 10080 bits<5> Vt; 10081 bits<5> Rn; 10082 let Inst{31} = 0; 10083 let Inst{29-24} = 0b001101; 10084 let Inst{22} = L; 10085 let Inst{21} = R; 10086 let Inst{15-13} = opcode; 10087 let Inst{9-5} = Rn; 10088 let Inst{4-0} = Vt; 10089} 10090 10091class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10092 string asm, string operands, string cst, 10093 dag oops, dag iops, list<dag> pattern> 10094 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10095 bits<5> Vt; 10096 bits<5> Rn; 10097 let Inst{31} = 0; 10098 let Inst{29-24} = 0b001101; 10099 let Inst{22} = L; 10100 let Inst{21} = R; 10101 let Inst{15-13} = opcode; 10102 let Inst{9-5} = Rn; 10103 let Inst{4-0} = Vt; 10104} 10105 10106 10107let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10108class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10109 DAGOperand listtype> 10110 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10111 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10112 []> { 10113 let Inst{30} = Q; 10114 let Inst{23} = 0; 10115 let Inst{20-16} = 0b00000; 10116 let Inst{12} = S; 10117 let Inst{11-10} = size; 10118} 10119let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10120class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10121 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10122 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10123 "$Rn = $wback", 10124 (outs GPR64sp:$wback, listtype:$Vt), 10125 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10126 bits<5> Xm; 10127 let Inst{30} = Q; 10128 let Inst{23} = 1; 10129 let Inst{20-16} = Xm; 10130 let Inst{12} = S; 10131 let Inst{11-10} = size; 10132} 10133 10134multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10135 int Offset, int Size> { 10136 // E.g. "ld1r { v0.8b }, [x1], #1" 10137 // "ld1r.8b\t$Vt, [$Rn], #1" 10138 // may get mapped to 10139 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10140 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10141 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10142 GPR64sp:$Rn, 10143 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10144 XZR), 1>; 10145 10146 // E.g. "ld1r.8b { v0 }, [x1], #1" 10147 // "ld1r.8b\t$Vt, [$Rn], #1" 10148 // may get mapped to 10149 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10150 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10151 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10152 GPR64sp:$Rn, 10153 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10154 XZR), 0>; 10155 10156 // E.g. "ld1r.8b { v0 }, [x1]" 10157 // "ld1r.8b\t$Vt, [$Rn]" 10158 // may get mapped to 10159 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10160 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10161 (!cast<Instruction>(BaseName # "v" # layout) 10162 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10163 GPR64sp:$Rn), 0>; 10164 10165 // E.g. "ld1r.8b { v0 }, [x1], x2" 10166 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10167 // may get mapped to 10168 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10169 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10170 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10171 GPR64sp:$Rn, 10172 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10173 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10174} 10175 10176multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10177 int Offset1, int Offset2, int Offset4, int Offset8> { 10178 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10179 !cast<DAGOperand>("VecList" # Count # "8b")>; 10180 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10181 !cast<DAGOperand>("VecList" # Count #"16b")>; 10182 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10183 !cast<DAGOperand>("VecList" # Count #"4h")>; 10184 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10185 !cast<DAGOperand>("VecList" # Count #"8h")>; 10186 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10187 !cast<DAGOperand>("VecList" # Count #"2s")>; 10188 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10189 !cast<DAGOperand>("VecList" # Count #"4s")>; 10190 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10191 !cast<DAGOperand>("VecList" # Count #"1d")>; 10192 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10193 !cast<DAGOperand>("VecList" # Count #"2d")>; 10194 10195 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10196 !cast<DAGOperand>("VecList" # Count # "8b"), 10197 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10198 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10199 !cast<DAGOperand>("VecList" # Count # "16b"), 10200 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10201 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10202 !cast<DAGOperand>("VecList" # Count # "4h"), 10203 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10204 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10205 !cast<DAGOperand>("VecList" # Count # "8h"), 10206 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10207 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10208 !cast<DAGOperand>("VecList" # Count # "2s"), 10209 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10210 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10211 !cast<DAGOperand>("VecList" # Count # "4s"), 10212 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10213 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10214 !cast<DAGOperand>("VecList" # Count # "1d"), 10215 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10216 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10217 !cast<DAGOperand>("VecList" # Count # "2d"), 10218 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10219 10220 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10221 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10222 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10223 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10224 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10225 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10226 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10227 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10228} 10229 10230class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10231 dag oops, dag iops, list<dag> pattern> 10232 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10233 pattern> { 10234 // idx encoded in Q:S:size fields. 10235 bits<4> idx; 10236 let Inst{30} = idx{3}; 10237 let Inst{23} = 0; 10238 let Inst{20-16} = 0b00000; 10239 let Inst{12} = idx{2}; 10240 let Inst{11-10} = idx{1-0}; 10241} 10242class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10243 dag oops, dag iops, list<dag> pattern> 10244 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10245 oops, iops, pattern> { 10246 // idx encoded in Q:S:size fields. 10247 bits<4> idx; 10248 let Inst{30} = idx{3}; 10249 let Inst{23} = 0; 10250 let Inst{20-16} = 0b00000; 10251 let Inst{12} = idx{2}; 10252 let Inst{11-10} = idx{1-0}; 10253} 10254class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10255 dag oops, dag iops> 10256 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10257 "$Rn = $wback", oops, iops, []> { 10258 // idx encoded in Q:S:size fields. 10259 bits<4> idx; 10260 bits<5> Xm; 10261 let Inst{30} = idx{3}; 10262 let Inst{23} = 1; 10263 let Inst{20-16} = Xm; 10264 let Inst{12} = idx{2}; 10265 let Inst{11-10} = idx{1-0}; 10266} 10267class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10268 dag oops, dag iops> 10269 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10270 "$Rn = $wback", oops, iops, []> { 10271 // idx encoded in Q:S:size fields. 10272 bits<4> idx; 10273 bits<5> Xm; 10274 let Inst{30} = idx{3}; 10275 let Inst{23} = 1; 10276 let Inst{20-16} = Xm; 10277 let Inst{12} = idx{2}; 10278 let Inst{11-10} = idx{1-0}; 10279} 10280 10281class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10282 dag oops, dag iops, list<dag> pattern> 10283 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10284 pattern> { 10285 // idx encoded in Q:S:size<1> fields. 10286 bits<3> idx; 10287 let Inst{30} = idx{2}; 10288 let Inst{23} = 0; 10289 let Inst{20-16} = 0b00000; 10290 let Inst{12} = idx{1}; 10291 let Inst{11} = idx{0}; 10292 let Inst{10} = size; 10293} 10294class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10295 dag oops, dag iops, list<dag> pattern> 10296 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10297 oops, iops, pattern> { 10298 // idx encoded in Q:S:size<1> fields. 10299 bits<3> idx; 10300 let Inst{30} = idx{2}; 10301 let Inst{23} = 0; 10302 let Inst{20-16} = 0b00000; 10303 let Inst{12} = idx{1}; 10304 let Inst{11} = idx{0}; 10305 let Inst{10} = size; 10306} 10307 10308class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10309 dag oops, dag iops> 10310 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10311 "$Rn = $wback", oops, iops, []> { 10312 // idx encoded in Q:S:size<1> fields. 10313 bits<3> idx; 10314 bits<5> Xm; 10315 let Inst{30} = idx{2}; 10316 let Inst{23} = 1; 10317 let Inst{20-16} = Xm; 10318 let Inst{12} = idx{1}; 10319 let Inst{11} = idx{0}; 10320 let Inst{10} = size; 10321} 10322class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10323 dag oops, dag iops> 10324 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10325 "$Rn = $wback", oops, iops, []> { 10326 // idx encoded in Q:S:size<1> fields. 10327 bits<3> idx; 10328 bits<5> Xm; 10329 let Inst{30} = idx{2}; 10330 let Inst{23} = 1; 10331 let Inst{20-16} = Xm; 10332 let Inst{12} = idx{1}; 10333 let Inst{11} = idx{0}; 10334 let Inst{10} = size; 10335} 10336class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10337 dag oops, dag iops, list<dag> pattern> 10338 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10339 pattern> { 10340 // idx encoded in Q:S fields. 10341 bits<2> idx; 10342 let Inst{30} = idx{1}; 10343 let Inst{23} = 0; 10344 let Inst{20-16} = 0b00000; 10345 let Inst{12} = idx{0}; 10346 let Inst{11-10} = size; 10347} 10348class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10349 dag oops, dag iops, list<dag> pattern> 10350 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10351 oops, iops, pattern> { 10352 // idx encoded in Q:S fields. 10353 bits<2> idx; 10354 let Inst{30} = idx{1}; 10355 let Inst{23} = 0; 10356 let Inst{20-16} = 0b00000; 10357 let Inst{12} = idx{0}; 10358 let Inst{11-10} = size; 10359} 10360class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10361 string asm, dag oops, dag iops> 10362 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10363 "$Rn = $wback", oops, iops, []> { 10364 // idx encoded in Q:S fields. 10365 bits<2> idx; 10366 bits<5> Xm; 10367 let Inst{30} = idx{1}; 10368 let Inst{23} = 1; 10369 let Inst{20-16} = Xm; 10370 let Inst{12} = idx{0}; 10371 let Inst{11-10} = size; 10372} 10373class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10374 string asm, dag oops, dag iops> 10375 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10376 "$Rn = $wback", oops, iops, []> { 10377 // idx encoded in Q:S fields. 10378 bits<2> idx; 10379 bits<5> Xm; 10380 let Inst{30} = idx{1}; 10381 let Inst{23} = 1; 10382 let Inst{20-16} = Xm; 10383 let Inst{12} = idx{0}; 10384 let Inst{11-10} = size; 10385} 10386class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10387 dag oops, dag iops, list<dag> pattern> 10388 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10389 pattern> { 10390 // idx encoded in Q field. 10391 bits<1> idx; 10392 let Inst{30} = idx; 10393 let Inst{23} = 0; 10394 let Inst{20-16} = 0b00000; 10395 let Inst{12} = 0; 10396 let Inst{11-10} = size; 10397} 10398class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10399 dag oops, dag iops, list<dag> pattern> 10400 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10401 oops, iops, pattern> { 10402 // idx encoded in Q field. 10403 bits<1> idx; 10404 let Inst{30} = idx; 10405 let Inst{23} = 0; 10406 let Inst{20-16} = 0b00000; 10407 let Inst{12} = 0; 10408 let Inst{11-10} = size; 10409} 10410class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10411 string asm, dag oops, dag iops> 10412 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10413 "$Rn = $wback", oops, iops, []> { 10414 // idx encoded in Q field. 10415 bits<1> idx; 10416 bits<5> Xm; 10417 let Inst{30} = idx; 10418 let Inst{23} = 1; 10419 let Inst{20-16} = Xm; 10420 let Inst{12} = 0; 10421 let Inst{11-10} = size; 10422} 10423class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10424 string asm, dag oops, dag iops> 10425 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10426 "$Rn = $wback", oops, iops, []> { 10427 // idx encoded in Q field. 10428 bits<1> idx; 10429 bits<5> Xm; 10430 let Inst{30} = idx; 10431 let Inst{23} = 1; 10432 let Inst{20-16} = Xm; 10433 let Inst{12} = 0; 10434 let Inst{11-10} = size; 10435} 10436 10437let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10438multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10439 RegisterOperand listtype, 10440 RegisterOperand GPR64pi> { 10441 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10442 (outs listtype:$dst), 10443 (ins listtype:$Vt, VectorIndexB:$idx, 10444 GPR64sp:$Rn), []>; 10445 10446 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10447 (outs GPR64sp:$wback, listtype:$dst), 10448 (ins listtype:$Vt, VectorIndexB:$idx, 10449 GPR64sp:$Rn, GPR64pi:$Xm)>; 10450} 10451let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10452multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10453 RegisterOperand listtype, 10454 RegisterOperand GPR64pi> { 10455 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10456 (outs listtype:$dst), 10457 (ins listtype:$Vt, VectorIndexH:$idx, 10458 GPR64sp:$Rn), []>; 10459 10460 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10461 (outs GPR64sp:$wback, listtype:$dst), 10462 (ins listtype:$Vt, VectorIndexH:$idx, 10463 GPR64sp:$Rn, GPR64pi:$Xm)>; 10464} 10465let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10466multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10467 RegisterOperand listtype, 10468 RegisterOperand GPR64pi> { 10469 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10470 (outs listtype:$dst), 10471 (ins listtype:$Vt, VectorIndexS:$idx, 10472 GPR64sp:$Rn), []>; 10473 10474 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10475 (outs GPR64sp:$wback, listtype:$dst), 10476 (ins listtype:$Vt, VectorIndexS:$idx, 10477 GPR64sp:$Rn, GPR64pi:$Xm)>; 10478} 10479let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10480multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10481 RegisterOperand listtype, RegisterOperand GPR64pi> { 10482 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10483 (outs listtype:$dst), 10484 (ins listtype:$Vt, VectorIndexD:$idx, 10485 GPR64sp:$Rn), []>; 10486 10487 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10488 (outs GPR64sp:$wback, listtype:$dst), 10489 (ins listtype:$Vt, VectorIndexD:$idx, 10490 GPR64sp:$Rn, GPR64pi:$Xm)>; 10491} 10492let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10493multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10494 RegisterOperand listtype, RegisterOperand GPR64pi> { 10495 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10496 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10497 GPR64sp:$Rn), []>; 10498 10499 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10500 (outs GPR64sp:$wback), 10501 (ins listtype:$Vt, VectorIndexB:$idx, 10502 GPR64sp:$Rn, GPR64pi:$Xm)>; 10503} 10504let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10505multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10506 RegisterOperand listtype, RegisterOperand GPR64pi> { 10507 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10508 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10509 GPR64sp:$Rn), []>; 10510 10511 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10512 (outs GPR64sp:$wback), 10513 (ins listtype:$Vt, VectorIndexH:$idx, 10514 GPR64sp:$Rn, GPR64pi:$Xm)>; 10515} 10516let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10517multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10518 RegisterOperand listtype, RegisterOperand GPR64pi> { 10519 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10520 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10521 GPR64sp:$Rn), []>; 10522 10523 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10524 (outs GPR64sp:$wback), 10525 (ins listtype:$Vt, VectorIndexS:$idx, 10526 GPR64sp:$Rn, GPR64pi:$Xm)>; 10527} 10528let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10529multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10530 RegisterOperand listtype, RegisterOperand GPR64pi> { 10531 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10532 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10533 GPR64sp:$Rn), []>; 10534 10535 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10536 (outs GPR64sp:$wback), 10537 (ins listtype:$Vt, VectorIndexD:$idx, 10538 GPR64sp:$Rn, GPR64pi:$Xm)>; 10539} 10540 10541multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10542 string Count, int Offset, Operand idxtype> { 10543 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10544 // "ld1\t$Vt, [$Rn], #1" 10545 // may get mapped to 10546 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10547 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10548 (!cast<Instruction>(NAME # Type # "_POST") 10549 GPR64sp:$Rn, 10550 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10551 idxtype:$idx, XZR), 1>; 10552 10553 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10554 // "ld1.8b\t$Vt, [$Rn], #1" 10555 // may get mapped to 10556 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10557 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10558 (!cast<Instruction>(NAME # Type # "_POST") 10559 GPR64sp:$Rn, 10560 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10561 idxtype:$idx, XZR), 0>; 10562 10563 // E.g. "ld1.8b { v0 }[0], [x1]" 10564 // "ld1.8b\t$Vt, [$Rn]" 10565 // may get mapped to 10566 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10567 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10568 (!cast<Instruction>(NAME # Type) 10569 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10570 idxtype:$idx, GPR64sp:$Rn), 0>; 10571 10572 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10573 // "ld1.8b\t$Vt, [$Rn], $Xm" 10574 // may get mapped to 10575 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10576 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10577 (!cast<Instruction>(NAME # Type # "_POST") 10578 GPR64sp:$Rn, 10579 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10580 idxtype:$idx, 10581 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10582} 10583 10584multiclass SIMDLdSt1SingleAliases<string asm> { 10585 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10586 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10587 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10588 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10589} 10590 10591multiclass SIMDLdSt2SingleAliases<string asm> { 10592 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10593 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10594 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10595 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10596} 10597 10598multiclass SIMDLdSt3SingleAliases<string asm> { 10599 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10600 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10601 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10602 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10603} 10604 10605multiclass SIMDLdSt4SingleAliases<string asm> { 10606 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10607 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10608 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10609 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10610} 10611} // end of 'let Predicates = [HasNEON]' 10612 10613//---------------------------------------------------------------------------- 10614// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10615//---------------------------------------------------------------------------- 10616 10617let Predicates = [HasNEON, HasRDM] in { 10618 10619class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10620 RegisterOperand regtype, string asm, 10621 string kind, list<dag> pattern> 10622 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10623 pattern> { 10624} 10625multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10626 SDPatternOperator op> { 10627 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10628 [(set (v4i16 V64:$dst), 10629 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 10630 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10631 [(set (v8i16 V128:$dst), 10632 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 10633 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10634 [(set (v2i32 V64:$dst), 10635 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 10636 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10637 [(set (v4i32 V128:$dst), 10638 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 10639} 10640 10641multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10642 SDPatternOperator op> { 10643 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10644 V64, V64, V128_lo, VectorIndexH, 10645 asm, ".4h", ".4h", ".4h", ".h", 10646 [(set (v4i16 V64:$dst), 10647 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10648 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10649 VectorIndexH:$idx)))))]> { 10650 bits<3> idx; 10651 let Inst{11} = idx{2}; 10652 let Inst{21} = idx{1}; 10653 let Inst{20} = idx{0}; 10654 } 10655 10656 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10657 V128, V128, V128_lo, VectorIndexH, 10658 asm, ".8h", ".8h", ".8h", ".h", 10659 [(set (v8i16 V128:$dst), 10660 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10661 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10662 VectorIndexH:$idx)))))]> { 10663 bits<3> idx; 10664 let Inst{11} = idx{2}; 10665 let Inst{21} = idx{1}; 10666 let Inst{20} = idx{0}; 10667 } 10668 10669 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10670 V64, V64, V128, VectorIndexS, 10671 asm, ".2s", ".2s", ".2s", ".s", 10672 [(set (v2i32 V64:$dst), 10673 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10674 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10675 VectorIndexS:$idx)))))]> { 10676 bits<2> idx; 10677 let Inst{11} = idx{1}; 10678 let Inst{21} = idx{0}; 10679 } 10680 10681 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10682 V128, V128, V128, VectorIndexS, 10683 asm, ".4s", ".4s", ".4s", ".s", 10684 [(set (v4i32 V128:$dst), 10685 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10686 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10687 VectorIndexS:$idx)))))]> { 10688 bits<2> idx; 10689 let Inst{11} = idx{1}; 10690 let Inst{21} = idx{0}; 10691 } 10692 10693 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10694 FPR16Op, FPR16Op, V128_lo, 10695 VectorIndexH, asm, ".h", "", "", ".h", 10696 []> { 10697 bits<3> idx; 10698 let Inst{11} = idx{2}; 10699 let Inst{21} = idx{1}; 10700 let Inst{20} = idx{0}; 10701 } 10702 10703 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10704 FPR32Op, FPR32Op, V128, VectorIndexS, 10705 asm, ".s", "", "", ".s", 10706 [(set (i32 FPR32Op:$dst), 10707 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 10708 (i32 (vector_extract (v4i32 V128:$Rm), 10709 VectorIndexS:$idx)))))]> { 10710 bits<2> idx; 10711 let Inst{11} = idx{1}; 10712 let Inst{21} = idx{0}; 10713 } 10714} 10715} // let Predicates = [HasNeon, HasRDM] 10716 10717//---------------------------------------------------------------------------- 10718// ARMv8.3 Complex ADD/MLA instructions 10719//---------------------------------------------------------------------------- 10720 10721class ComplexRotationOperand<int Angle, int Remainder, string Type> 10722 : AsmOperandClass { 10723 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10724 let DiagnosticType = "InvalidComplexRotation" # Type; 10725 let Name = "ComplexRotation" # Type; 10726} 10727def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10728 SDNodeXForm<imm, [{ 10729 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10730}]>> { 10731 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10732 let PrintMethod = "printComplexRotationOp<90, 0>"; 10733} 10734def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10735 SDNodeXForm<imm, [{ 10736 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10737}]>> { 10738 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10739 let PrintMethod = "printComplexRotationOp<180, 90>"; 10740} 10741let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10742class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10743 RegisterOperand regtype, Operand rottype, 10744 string asm, string kind, list<dag> pattern> 10745 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10746 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10747 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10748 Sched<[!if(Q, WriteVq, WriteVd)]> { 10749 bits<5> Rd; 10750 bits<5> Rn; 10751 bits<5> Rm; 10752 bits<1> rot; 10753 let Inst{31} = 0; 10754 let Inst{30} = Q; 10755 let Inst{29} = U; 10756 let Inst{28-24} = 0b01110; 10757 let Inst{23-22} = size; 10758 let Inst{21} = 0; 10759 let Inst{20-16} = Rm; 10760 let Inst{15-13} = opcode; 10761 // Non-tied version (FCADD) only has one rotation bit 10762 let Inst{12} = rot; 10763 let Inst{11} = 0; 10764 let Inst{10} = 1; 10765 let Inst{9-5} = Rn; 10766 let Inst{4-0} = Rd; 10767} 10768 10769//8.3 CompNum - Floating-point complex number support 10770multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10771 string asm, SDPatternOperator OpNode>{ 10772 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10773 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10774 asm, ".4h", 10775 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10776 (v4f16 V64:$Rn), 10777 (v4f16 V64:$Rm), 10778 (i32 rottype:$rot)))]>; 10779 10780 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10781 asm, ".8h", 10782 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10783 (v8f16 V128:$Rn), 10784 (v8f16 V128:$Rm), 10785 (i32 rottype:$rot)))]>; 10786 } 10787 10788 let Predicates = [HasComplxNum, HasNEON] in { 10789 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10790 asm, ".2s", 10791 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10792 (v2f32 V64:$Rn), 10793 (v2f32 V64:$Rm), 10794 (i32 rottype:$rot)))]>; 10795 10796 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10797 asm, ".4s", 10798 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10799 (v4f32 V128:$Rn), 10800 (v4f32 V128:$Rm), 10801 (i32 rottype:$rot)))]>; 10802 10803 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10804 asm, ".2d", 10805 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10806 (v2f64 V128:$Rn), 10807 (v2f64 V128:$Rm), 10808 (i32 rottype:$rot)))]>; 10809 } 10810} 10811 10812let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10813class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10814 bits<3> opcode, 10815 RegisterOperand regtype, 10816 Operand rottype, string asm, 10817 string kind, list<dag> pattern> 10818 : I<(outs regtype:$dst), 10819 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10820 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10821 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10822 Sched<[!if(Q, WriteVq, WriteVd)]> { 10823 bits<5> Rd; 10824 bits<5> Rn; 10825 bits<5> Rm; 10826 bits<2> rot; 10827 let Inst{31} = 0; 10828 let Inst{30} = Q; 10829 let Inst{29} = U; 10830 let Inst{28-24} = 0b01110; 10831 let Inst{23-22} = size; 10832 let Inst{21} = 0; 10833 let Inst{20-16} = Rm; 10834 let Inst{15-13} = opcode; 10835 let Inst{12-11} = rot; 10836 let Inst{10} = 1; 10837 let Inst{9-5} = Rn; 10838 let Inst{4-0} = Rd; 10839} 10840 10841multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10842 Operand rottype, string asm, 10843 SDPatternOperator OpNode> { 10844 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10845 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10846 rottype, asm, ".4h", 10847 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10848 (v4f16 V64:$Rn), 10849 (v4f16 V64:$Rm), 10850 (i32 rottype:$rot)))]>; 10851 10852 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10853 rottype, asm, ".8h", 10854 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10855 (v8f16 V128:$Rn), 10856 (v8f16 V128:$Rm), 10857 (i32 rottype:$rot)))]>; 10858 } 10859 10860 let Predicates = [HasComplxNum, HasNEON] in { 10861 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10862 rottype, asm, ".2s", 10863 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10864 (v2f32 V64:$Rn), 10865 (v2f32 V64:$Rm), 10866 (i32 rottype:$rot)))]>; 10867 10868 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10869 rottype, asm, ".4s", 10870 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10871 (v4f32 V128:$Rn), 10872 (v4f32 V128:$Rm), 10873 (i32 rottype:$rot)))]>; 10874 10875 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10876 rottype, asm, ".2d", 10877 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10878 (v2f64 V128:$Rn), 10879 (v2f64 V128:$Rm), 10880 (i32 rottype:$rot)))]>; 10881 } 10882} 10883 10884let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1 in 10885class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10886 bit opc1, bit opc2, RegisterOperand dst_reg, 10887 RegisterOperand lhs_reg, 10888 RegisterOperand rhs_reg, Operand vec_idx, 10889 Operand rottype, string asm, string apple_kind, 10890 string dst_kind, string lhs_kind, 10891 string rhs_kind, list<dag> pattern> 10892 : I<(outs dst_reg:$dst), 10893 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10894 asm, 10895 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10896 "$idx, $rot" # "|" # apple_kind # 10897 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10898 Sched<[!if(Q, WriteVq, WriteVd)]> { 10899 bits<5> Rd; 10900 bits<5> Rn; 10901 bits<5> Rm; 10902 bits<2> rot; 10903 10904 let Inst{31} = 0; 10905 let Inst{30} = Q; 10906 let Inst{29} = U; 10907 let Inst{28} = Scalar; 10908 let Inst{27-24} = 0b1111; 10909 let Inst{23-22} = size; 10910 // Bit 21 must be set by the derived class. 10911 let Inst{20-16} = Rm; 10912 let Inst{15} = opc1; 10913 let Inst{14-13} = rot; 10914 let Inst{12} = opc2; 10915 // Bit 11 must be set by the derived class. 10916 let Inst{10} = 0; 10917 let Inst{9-5} = Rn; 10918 let Inst{4-0} = Rd; 10919} 10920 10921// The complex instructions index by pairs of elements, so the VectorIndexes 10922// don't match the lane types, and the index bits are different to the other 10923// classes. 10924multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 10925 string asm> { 10926 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10927 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10928 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10929 ".4h", ".h", []> { 10930 bits<1> idx; 10931 let Inst{11} = 0; 10932 let Inst{21} = idx{0}; 10933 } 10934 10935 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10936 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10937 ".8h", ".8h", ".h", []> { 10938 bits<2> idx; 10939 let Inst{11} = idx{1}; 10940 let Inst{21} = idx{0}; 10941 } 10942 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10943 10944 let Predicates = [HasComplxNum, HasNEON] in { 10945 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10946 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10947 ".4s", ".4s", ".s", []> { 10948 bits<1> idx; 10949 let Inst{11} = idx{0}; 10950 let Inst{21} = 0; 10951 } 10952 } // Predicates = [HasComplxNum, HasNEON] 10953} 10954 10955//---------------------------------------------------------------------------- 10956// Crypto extensions 10957//---------------------------------------------------------------------------- 10958 10959let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10960class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10961 list<dag> pat> 10962 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10963 Sched<[WriteVq]>{ 10964 bits<5> Rd; 10965 bits<5> Rn; 10966 let Inst{31-16} = 0b0100111000101000; 10967 let Inst{15-12} = opc; 10968 let Inst{11-10} = 0b10; 10969 let Inst{9-5} = Rn; 10970 let Inst{4-0} = Rd; 10971} 10972 10973class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10974 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10975 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10976 10977class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10978 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10979 "$Rd = $dst", 10980 [(set (v16i8 V128:$dst), 10981 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10982 10983let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10984class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10985 dag oops, dag iops, list<dag> pat> 10986 : I<oops, iops, asm, 10987 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10988 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10989 Sched<[WriteVq]>{ 10990 bits<5> Rd; 10991 bits<5> Rn; 10992 bits<5> Rm; 10993 let Inst{31-21} = 0b01011110000; 10994 let Inst{20-16} = Rm; 10995 let Inst{15} = 0; 10996 let Inst{14-12} = opc; 10997 let Inst{11-10} = 0b00; 10998 let Inst{9-5} = Rn; 10999 let Inst{4-0} = Rd; 11000} 11001 11002class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 11003 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11004 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 11005 [(set (v4i32 FPR128:$dst), 11006 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11007 (v4i32 V128:$Rm)))]>; 11008 11009class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11010 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11011 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11012 [(set (v4i32 V128:$dst), 11013 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11014 (v4i32 V128:$Rm)))]>; 11015 11016class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11017 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11018 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11019 [(set (v4i32 FPR128:$dst), 11020 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11021 (v4i32 V128:$Rm)))]>; 11022 11023let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11024class SHA2OpInst<bits<4> opc, string asm, string kind, 11025 string cstr, dag oops, dag iops, 11026 list<dag> pat> 11027 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11028 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11029 Sched<[WriteVq]>{ 11030 bits<5> Rd; 11031 bits<5> Rn; 11032 let Inst{31-16} = 0b0101111000101000; 11033 let Inst{15-12} = opc; 11034 let Inst{11-10} = 0b10; 11035 let Inst{9-5} = Rn; 11036 let Inst{4-0} = Rd; 11037} 11038 11039class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11040 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11041 (ins V128:$Rd, V128:$Rn), 11042 [(set (v4i32 V128:$dst), 11043 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11044 11045class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11046 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11047 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11048 11049// Armv8.2-A Crypto extensions 11050class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11051 list<dag> pattern> 11052 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11053 bits<5> Vd; 11054 bits<5> Vn; 11055 let Inst{31-25} = 0b1100111; 11056 let Inst{9-5} = Vn; 11057 let Inst{4-0} = Vd; 11058} 11059 11060class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11061 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11062 "$Vd = $Vdst", []> { 11063 let Inst{31-25} = 0b1100111; 11064 let Inst{24-21} = 0b0110; 11065 let Inst{20-15} = 0b000001; 11066 let Inst{14} = op0; 11067 let Inst{13-12} = 0b00; 11068 let Inst{11-10} = op1; 11069} 11070class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11071 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11072class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11073 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11074 11075class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11076 string asmops, string cst> 11077 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11078 bits<5> Vm; 11079 let Inst{24-21} = 0b0011; 11080 let Inst{20-16} = Vm; 11081 let Inst{15} = 0b1; 11082 let Inst{14} = op0; 11083 let Inst{13-12} = 0b00; 11084 let Inst{11-10} = op1; 11085} 11086class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11087 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11088 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11089class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11090 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11091 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11092class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11093 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11094 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11095class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11096 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11097 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11098class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11099 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11100 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11101 11102class CryptoRRRR<bits<2>op0, string asm, string asmops> 11103 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11104 asmops, "", []> { 11105 bits<5> Vm; 11106 bits<5> Va; 11107 let Inst{24-23} = 0b00; 11108 let Inst{22-21} = op0; 11109 let Inst{20-16} = Vm; 11110 let Inst{15} = 0b0; 11111 let Inst{14-10} = Va; 11112} 11113class CryptoRRRR_16B<bits<2>op0, string asm> 11114 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11115 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11116} 11117class CryptoRRRR_4S<bits<2>op0, string asm> 11118 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11119 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11120} 11121 11122class CryptoRRRi6<string asm> 11123 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11124 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11125 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11126 bits<6> imm; 11127 bits<5> Vm; 11128 let Inst{24-21} = 0b0100; 11129 let Inst{20-16} = Vm; 11130 let Inst{15-10} = imm; 11131 let Inst{9-5} = Vn; 11132 let Inst{4-0} = Vd; 11133} 11134 11135class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11136 : BaseCryptoV82<(outs V128:$Vdst), 11137 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11138 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11139 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11140 bits<2> imm; 11141 bits<5> Vm; 11142 let Inst{24-21} = 0b0010; 11143 let Inst{20-16} = Vm; 11144 let Inst{15} = 0b1; 11145 let Inst{14} = op0; 11146 let Inst{13-12} = imm; 11147 let Inst{11-10} = op1; 11148} 11149 11150//---------------------------------------------------------------------------- 11151// v8.1 atomic instructions extension: 11152// * CAS 11153// * CASP 11154// * SWP 11155// * LDOPregister<OP>, and aliases STOPregister<OP> 11156 11157// Instruction encodings: 11158// 11159// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11160// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11161// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11162// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11163// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11164// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11165 11166// Instruction syntax: 11167// 11168// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11169// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11170// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11171// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11172// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11173// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11174// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11175// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11176// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11177// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11178 11179let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11180class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11181 string cstr, list<dag> pattern> 11182 : I<oops, iops, asm, operands, cstr, pattern> { 11183 bits<2> Sz; 11184 bit NP; 11185 bit Acq; 11186 bit Rel; 11187 bits<5> Rs; 11188 bits<5> Rn; 11189 bits<5> Rt; 11190 let Inst{31-30} = Sz; 11191 let Inst{29-24} = 0b001000; 11192 let Inst{23} = NP; 11193 let Inst{22} = Acq; 11194 let Inst{21} = 0b1; 11195 let Inst{20-16} = Rs; 11196 let Inst{15} = Rel; 11197 let Inst{14-10} = 0b11111; 11198 let Inst{9-5} = Rn; 11199 let Inst{4-0} = Rt; 11200 let Predicates = [HasLSE]; 11201} 11202 11203class BaseCAS<string order, string size, RegisterClass RC> 11204 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11205 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11206 "$out = $Rs",[]>, 11207 Sched<[WriteAtomic]> { 11208 let NP = 1; 11209} 11210 11211multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11212 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11213 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11214 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11215 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11216} 11217 11218class BaseCASP<string order, string size, RegisterOperand RC> 11219 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11220 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11221 "$out = $Rs",[]>, 11222 Sched<[WriteAtomic]> { 11223 let NP = 0; 11224} 11225 11226multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11227 let Sz = 0b00, Acq = Acq, Rel = Rel in 11228 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11229 let Sz = 0b01, Acq = Acq, Rel = Rel in 11230 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11231} 11232 11233let Predicates = [HasLSE] in 11234class BaseSWP<string order, string size, RegisterClass RC> 11235 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11236 "\t$Rs, $Rt, [$Rn]","",[]>, 11237 Sched<[WriteAtomic]> { 11238 bits<2> Sz; 11239 bit Acq; 11240 bit Rel; 11241 bits<5> Rs; 11242 bits<3> opc = 0b000; 11243 bits<5> Rn; 11244 bits<5> Rt; 11245 let Inst{31-30} = Sz; 11246 let Inst{29-24} = 0b111000; 11247 let Inst{23} = Acq; 11248 let Inst{22} = Rel; 11249 let Inst{21} = 0b1; 11250 let Inst{20-16} = Rs; 11251 let Inst{15} = 0b1; 11252 let Inst{14-12} = opc; 11253 let Inst{11-10} = 0b00; 11254 let Inst{9-5} = Rn; 11255 let Inst{4-0} = Rt; 11256 let Predicates = [HasLSE]; 11257} 11258 11259multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11260 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11261 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11262 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11263 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11264} 11265 11266let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11267class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11268 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11269 "\t$Rs, $Rt, [$Rn]","",[]>, 11270 Sched<[WriteAtomic]> { 11271 bits<2> Sz; 11272 bit Acq; 11273 bit Rel; 11274 bits<5> Rs; 11275 bits<3> opc; 11276 bits<5> Rn; 11277 bits<5> Rt; 11278 let Inst{31-30} = Sz; 11279 let Inst{29-24} = 0b111000; 11280 let Inst{23} = Acq; 11281 let Inst{22} = Rel; 11282 let Inst{21} = 0b1; 11283 let Inst{20-16} = Rs; 11284 let Inst{15} = 0b0; 11285 let Inst{14-12} = opc; 11286 let Inst{11-10} = 0b00; 11287 let Inst{9-5} = Rn; 11288 let Inst{4-0} = Rt; 11289 let Predicates = [HasLSE]; 11290} 11291 11292multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11293 string order> { 11294 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11295 def B : BaseLDOPregister<op, order, "b", GPR32>; 11296 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11297 def H : BaseLDOPregister<op, order, "h", GPR32>; 11298 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11299 def W : BaseLDOPregister<op, order, "", GPR32>; 11300 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11301 def X : BaseLDOPregister<op, order, "", GPR64>; 11302} 11303 11304// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11305// complex DAG for DstRHS. 11306let Predicates = [HasLSE] in 11307multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11308 string size, dag SrcRHS, dag DstRHS> { 11309 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11310 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11311 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11312 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11313 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11314 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11315 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11316 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11317 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11318 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11319} 11320 11321multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11322 string size, dag RHS> { 11323 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11324} 11325 11326multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11327 string size, dag LHS, dag RHS> { 11328 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11329} 11330 11331multiclass LDOPregister_patterns<string inst, string op> { 11332 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11333 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11334 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11335 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11336} 11337 11338multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11339 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11340 (i64 GPR64:$Rm), 11341 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11342 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11343 (i32 GPR32:$Rm), 11344 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11345 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11346 (i32 GPR32:$Rm), 11347 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11348 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11349 (i32 GPR32:$Rm), 11350 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11351} 11352 11353let Predicates = [HasLSE] in 11354multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11355 string size, dag OLD, dag NEW> { 11356 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11357 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11358 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11359 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11360 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11361 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11362 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11363 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11364 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11365 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11366} 11367 11368multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11369 string size, dag OLD, dag NEW> { 11370 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11371} 11372 11373multiclass CASregister_patterns<string inst, string op> { 11374 defm : CASregister_patterns_ord<inst, "X", op, "64", 11375 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11376 defm : CASregister_patterns_ord<inst, "W", op, "32", 11377 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11378 defm : CASregister_patterns_ord<inst, "H", op, "16", 11379 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11380 defm : CASregister_patterns_ord<inst, "B", op, "8", 11381 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11382} 11383 11384let Predicates = [HasLSE] in 11385class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11386 Instruction inst> : 11387 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11388 11389multiclass STOPregister<string asm, string instr> { 11390 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11391 !cast<Instruction>(instr # "LB")>; 11392 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11393 !cast<Instruction>(instr # "LH")>; 11394 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11395 !cast<Instruction>(instr # "LW")>; 11396 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11397 !cast<Instruction>(instr # "LX")>; 11398 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11399 !cast<Instruction>(instr # "B")>; 11400 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11401 !cast<Instruction>(instr # "H")>; 11402 def : BaseSTOPregister<asm, GPR32, WZR, 11403 !cast<Instruction>(instr # "W")>; 11404 def : BaseSTOPregister<asm, GPR64, XZR, 11405 !cast<Instruction>(instr # "X")>; 11406} 11407 11408class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11409 dag iops, dag oops, list<dag> pat> 11410 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11411 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11412 bits<5> Rt; 11413 bits<5> Rn; 11414 let Inst{31-21} = 0b11111000001; 11415 let Inst{15} = 1; 11416 let Inst{14-12} = opc; 11417 let Inst{11-10} = 0b00; 11418 let Inst{9-5} = Rn; 11419 let Inst{4-0} = Rt; 11420 11421 let Predicates = [HasV8_7a]; 11422} 11423 11424class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11425 list<dag> pat = []> 11426 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11427 let Inst{20-16} = 0b11111; 11428} 11429 11430class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11431 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11432 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11433 bits<5> Rs; 11434 let Inst{20-16} = Rs; 11435} 11436 11437class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 11438 bits<2> op2, string asm> 11439 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 11440 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 11441 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 11442 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 11443 Sched<[]> { 11444 bits<5> Rd; 11445 bits<5> Rs; 11446 bits<5> Rn; 11447 let Inst{31-27} = 0b00011; 11448 let Inst{26} = isMove; 11449 let Inst{25-24} = 0b01; 11450 let Inst{23-22} = opcode; 11451 let Inst{21} = 0b0; 11452 let Inst{20-16} = Rs; 11453 let Inst{15-14} = op2; 11454 let Inst{13-12} = op1; 11455 let Inst{11-10} = 0b01; 11456 let Inst{9-5} = Rn; 11457 let Inst{4-0} = Rd; 11458 11459 let DecoderMethod = "DecodeCPYMemOpInstruction"; 11460 let mayLoad = 1; 11461 let mayStore = 1; 11462} 11463 11464class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11465 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 11466 11467class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11468 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 11469 11470class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 11471 string asm> 11472 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 11473 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 11474 asm, "\t[$Rd]!, $Rn!, $Rm", 11475 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 11476 Sched<[]> { 11477 bits<5> Rd; 11478 bits<5> Rn; 11479 bits<5> Rm; 11480 let Inst{31-27} = 0b00011; 11481 let Inst{26} = isTagging; 11482 let Inst{25-21} = 0b01110; 11483 let Inst{20-16} = Rm; 11484 let Inst{15-14} = opcode; 11485 let Inst{13} = op2; 11486 let Inst{12} = op1; 11487 let Inst{11-10} = 0b01; 11488 let Inst{9-5} = Rn; 11489 let Inst{4-0} = Rd; 11490 11491 let DecoderMethod = "DecodeSETMemOpInstruction"; 11492 let mayLoad = 0; 11493 let mayStore = 1; 11494} 11495 11496class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 11497 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 11498 11499class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 11500 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 11501 11502multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 11503 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 11504 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 11505 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 11506 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 11507 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 11508 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 11509 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 11510 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 11511 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 11512 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 11513 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 11514 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 11515 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 11516 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 11517 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 11518 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 11519} 11520 11521multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 11522 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 11523 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 11524 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 11525 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 11526 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 11527 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 11528 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 11529 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 11530 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 11531 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 11532 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 11533 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 11534 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 11535 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 11536 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 11537 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 11538} 11539 11540multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 11541 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 11542 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 11543 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 11544 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 11545} 11546 11547multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 11548 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 11549 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 11550 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 11551 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 11552} 11553 11554//---------------------------------------------------------------------------- 11555// Allow the size specifier tokens to be upper case, not just lower. 11556def : TokenAlias<".4B", ".4b">; // Add dot product 11557def : TokenAlias<".8B", ".8b">; 11558def : TokenAlias<".4H", ".4h">; 11559def : TokenAlias<".2S", ".2s">; 11560def : TokenAlias<".1D", ".1d">; 11561def : TokenAlias<".16B", ".16b">; 11562def : TokenAlias<".8H", ".8h">; 11563def : TokenAlias<".4S", ".4s">; 11564def : TokenAlias<".2D", ".2d">; 11565def : TokenAlias<".1Q", ".1q">; 11566def : TokenAlias<".2H", ".2h">; 11567def : TokenAlias<".B", ".b">; 11568def : TokenAlias<".H", ".h">; 11569def : TokenAlias<".S", ".s">; 11570def : TokenAlias<".D", ".d">; 11571def : TokenAlias<".Q", ".q">; 11572