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. 113def extract_high_v16i8 : 114 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>; 115def extract_high_v8i16 : 116 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>; 117def extract_high_v4i32 : 118 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>; 119def extract_high_v2i64 : 120 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>; 121 122//===----------------------------------------------------------------------===// 123// Asm Operand Classes. 124// 125 126// Shifter operand for arithmetic shifted encodings. 127def ShifterOperand : AsmOperandClass { 128 let Name = "Shifter"; 129} 130 131// Shifter operand for mov immediate encodings. 132def MovImm32ShifterOperand : AsmOperandClass { 133 let SuperClasses = [ShifterOperand]; 134 let Name = "MovImm32Shifter"; 135 let RenderMethod = "addShifterOperands"; 136 let DiagnosticType = "InvalidMovImm32Shift"; 137} 138def MovImm64ShifterOperand : AsmOperandClass { 139 let SuperClasses = [ShifterOperand]; 140 let Name = "MovImm64Shifter"; 141 let RenderMethod = "addShifterOperands"; 142 let DiagnosticType = "InvalidMovImm64Shift"; 143} 144 145// Shifter operand for arithmetic register shifted encodings. 146class ArithmeticShifterOperand<int width> : AsmOperandClass { 147 let SuperClasses = [ShifterOperand]; 148 let Name = "ArithmeticShifter" # width; 149 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 150 let RenderMethod = "addShifterOperands"; 151 let DiagnosticType = "AddSubRegShift" # width; 152} 153 154def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 155def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 156 157// Shifter operand for logical register shifted encodings. 158class LogicalShifterOperand<int width> : AsmOperandClass { 159 let SuperClasses = [ShifterOperand]; 160 let Name = "LogicalShifter" # width; 161 let PredicateMethod = "isLogicalShifter<" # width # ">"; 162 let RenderMethod = "addShifterOperands"; 163 let DiagnosticType = "AddSubRegShift" # width; 164} 165 166def LogicalShifterOperand32 : LogicalShifterOperand<32>; 167def LogicalShifterOperand64 : LogicalShifterOperand<64>; 168 169// Shifter operand for logical vector 128/64-bit shifted encodings. 170def LogicalVecShifterOperand : AsmOperandClass { 171 let SuperClasses = [ShifterOperand]; 172 let Name = "LogicalVecShifter"; 173 let RenderMethod = "addShifterOperands"; 174} 175def LogicalVecHalfWordShifterOperand : AsmOperandClass { 176 let SuperClasses = [LogicalVecShifterOperand]; 177 let Name = "LogicalVecHalfWordShifter"; 178 let RenderMethod = "addShifterOperands"; 179} 180 181// The "MSL" shifter on the vector MOVI instruction. 182def MoveVecShifterOperand : AsmOperandClass { 183 let SuperClasses = [ShifterOperand]; 184 let Name = "MoveVecShifter"; 185 let RenderMethod = "addShifterOperands"; 186} 187 188// Extend operand for arithmetic encodings. 189def ExtendOperand : AsmOperandClass { 190 let Name = "Extend"; 191 let DiagnosticType = "AddSubRegExtendLarge"; 192} 193def ExtendOperand64 : AsmOperandClass { 194 let SuperClasses = [ExtendOperand]; 195 let Name = "Extend64"; 196 let DiagnosticType = "AddSubRegExtendSmall"; 197} 198// 'extend' that's a lsl of a 64-bit register. 199def ExtendOperandLSL64 : AsmOperandClass { 200 let SuperClasses = [ExtendOperand]; 201 let Name = "ExtendLSL64"; 202 let RenderMethod = "addExtend64Operands"; 203 let DiagnosticType = "AddSubRegExtendLarge"; 204} 205 206// 8-bit floating-point immediate encodings. 207def FPImmOperand : AsmOperandClass { 208 let Name = "FPImm"; 209 let ParserMethod = "tryParseFPImm<true>"; 210 let DiagnosticType = "InvalidFPImm"; 211} 212 213def CondCode : AsmOperandClass { 214 let Name = "CondCode"; 215 let DiagnosticType = "InvalidCondCode"; 216} 217 218// A 32-bit register pasrsed as 64-bit 219def GPR32as64Operand : AsmOperandClass { 220 let Name = "GPR32as64"; 221 let ParserMethod = 222 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 223} 224def GPR32as64 : RegisterOperand<GPR32> { 225 let ParserMatchClass = GPR32as64Operand; 226} 227 228// A 64-bit register pasrsed as 32-bit 229def GPR64as32Operand : AsmOperandClass { 230 let Name = "GPR64as32"; 231 let ParserMethod = 232 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 233} 234def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 235 let ParserMatchClass = GPR64as32Operand; 236} 237 238// 8-bit immediate for AdvSIMD where 64-bit values of the form: 239// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 240// are encoded as the eight bit value 'abcdefgh'. 241def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 242 243class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 244 let Name = "UImm" # Width # "s" # Scale; 245 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 246 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 247 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 248} 249 250class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 251 let Name = "SImm" # Width # "s" # Scale; 252 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 253 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 254 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 255} 256 257//===----------------------------------------------------------------------===// 258// Operand Definitions. 259// 260 261// ADR[P] instruction labels. 262def AdrpOperand : AsmOperandClass { 263 let Name = "AdrpLabel"; 264 let ParserMethod = "tryParseAdrpLabel"; 265 let DiagnosticType = "InvalidLabel"; 266} 267def adrplabel : Operand<i64> { 268 let EncoderMethod = "getAdrLabelOpValue"; 269 let PrintMethod = "printAdrpLabel"; 270 let ParserMatchClass = AdrpOperand; 271 let OperandType = "OPERAND_PCREL"; 272} 273 274def AdrOperand : AsmOperandClass { 275 let Name = "AdrLabel"; 276 let ParserMethod = "tryParseAdrLabel"; 277 let DiagnosticType = "InvalidLabel"; 278} 279def adrlabel : Operand<i64> { 280 let EncoderMethod = "getAdrLabelOpValue"; 281 let ParserMatchClass = AdrOperand; 282} 283 284class SImmOperand<int width> : AsmOperandClass { 285 let Name = "SImm" # width; 286 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 287 let RenderMethod = "addImmOperands"; 288 let PredicateMethod = "isSImm<" # width # ">"; 289} 290 291 292class AsmImmRange<int Low, int High> : AsmOperandClass { 293 let Name = "Imm" # Low # "_" # High; 294 let DiagnosticType = "InvalidImm" # Low # "_" # High; 295 let RenderMethod = "addImmOperands"; 296 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 297} 298 299// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 300def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 301def simm10Scaled : Operand<i64> { 302 let ParserMatchClass = SImm10s8Operand; 303 let DecoderMethod = "DecodeSImm<10>"; 304 let PrintMethod = "printImmScale<8>"; 305} 306 307def simm9s16 : Operand<i64> { 308 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 309 let DecoderMethod = "DecodeSImm<9>"; 310 let PrintMethod = "printImmScale<16>"; 311} 312 313// uimm6 predicate - True if the immediate is in the range [0, 63]. 314def UImm6Operand : AsmOperandClass { 315 let Name = "UImm6"; 316 let DiagnosticType = "InvalidImm0_63"; 317} 318 319def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 320 let ParserMatchClass = UImm6Operand; 321} 322 323def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 324 let ParserMatchClass = AsmImmRange<0, 65535>; 325} 326 327def SImm9Operand : SImmOperand<9>; 328def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 329 let ParserMatchClass = SImm9Operand; 330 let DecoderMethod = "DecodeSImm<9>"; 331} 332 333def SImm8Operand : SImmOperand<8>; 334def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> { 335 let ParserMatchClass = SImm8Operand; 336 let DecoderMethod = "DecodeSImm<8>"; 337} 338 339def SImm6Operand : SImmOperand<6>; 340def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 341 let ParserMatchClass = SImm6Operand; 342 let DecoderMethod = "DecodeSImm<6>"; 343} 344 345def SImm5Operand : SImmOperand<5>; 346def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 347 let ParserMatchClass = SImm5Operand; 348 let DecoderMethod = "DecodeSImm<5>"; 349} 350 351def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 352 let ParserMatchClass = SImm5Operand; 353 let DecoderMethod = "DecodeSImm<5>"; 354} 355 356def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 357 let ParserMatchClass = SImm5Operand; 358 let DecoderMethod = "DecodeSImm<5>"; 359 let PrintMethod = "printSImm<8>"; 360} 361 362def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 363 let ParserMatchClass = SImm5Operand; 364 let DecoderMethod = "DecodeSImm<5>"; 365 let PrintMethod = "printSImm<16>"; 366} 367 368// simm7sN predicate - True if the immediate is a multiple of N in the range 369// [-64 * N, 63 * N]. 370 371def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 372def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 373def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 374 375def simm7s4 : Operand<i32> { 376 let ParserMatchClass = SImm7s4Operand; 377 let PrintMethod = "printImmScale<4>"; 378} 379 380def simm7s8 : Operand<i32> { 381 let ParserMatchClass = SImm7s8Operand; 382 let PrintMethod = "printImmScale<8>"; 383} 384 385def simm7s16 : Operand<i32> { 386 let ParserMatchClass = SImm7s16Operand; 387 let PrintMethod = "printImmScale<16>"; 388} 389 390def am_sve_fi : ComplexPattern<i64, 2, "SelectAddrModeFrameIndexSVE", []>; 391 392def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>; 393def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>; 394def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>; 395def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>; 396def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>; 397 398def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>; 399def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>; 400 401def UImmS1XForm : SDNodeXForm<imm, [{ 402 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 403}]>; 404def UImmS2XForm : SDNodeXForm<imm, [{ 405 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 406}]>; 407def UImmS4XForm : SDNodeXForm<imm, [{ 408 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 409}]>; 410def UImmS8XForm : SDNodeXForm<imm, [{ 411 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 412}]>; 413 414// uimm5sN predicate - True if the immediate is a multiple of N in the range 415// [0 * N, 32 * N]. 416def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 417def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 418def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 419 420def uimm5s2 : Operand<i64>, ImmLeaf<i64, 421 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 422 UImmS2XForm> { 423 let ParserMatchClass = UImm5s2Operand; 424 let PrintMethod = "printImmScale<2>"; 425} 426def uimm5s4 : Operand<i64>, ImmLeaf<i64, 427 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 428 UImmS4XForm> { 429 let ParserMatchClass = UImm5s4Operand; 430 let PrintMethod = "printImmScale<4>"; 431} 432def uimm5s8 : Operand<i64>, ImmLeaf<i64, 433 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 434 UImmS8XForm> { 435 let ParserMatchClass = UImm5s8Operand; 436 let PrintMethod = "printImmScale<8>"; 437} 438 439// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 440// instead of ImmLeaf (Constant) 441def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 442 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 443 UImmS2XForm> { 444 let ParserMatchClass = UImm5s2Operand; 445 let PrintMethod = "printImmScale<2>"; 446} 447def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 448 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 449 UImmS4XForm> { 450 let ParserMatchClass = UImm5s4Operand; 451 let PrintMethod = "printImmScale<4>"; 452} 453def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 454 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 455 UImmS8XForm> { 456 let ParserMatchClass = UImm5s8Operand; 457 let PrintMethod = "printImmScale<8>"; 458} 459 460// uimm6sN predicate - True if the immediate is a multiple of N in the range 461// [0 * N, 64 * N]. 462def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 463def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 464def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 465def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 466def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 467 468def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 469 let ParserMatchClass = UImm6s1Operand; 470} 471def uimm6s2 : Operand<i64>, ImmLeaf<i64, 472[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 473 let PrintMethod = "printImmScale<2>"; 474 let ParserMatchClass = UImm6s2Operand; 475} 476def uimm6s4 : Operand<i64>, ImmLeaf<i64, 477[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 478 let PrintMethod = "printImmScale<4>"; 479 let ParserMatchClass = UImm6s4Operand; 480} 481def uimm6s8 : Operand<i64>, ImmLeaf<i64, 482[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 483 let PrintMethod = "printImmScale<8>"; 484 let ParserMatchClass = UImm6s8Operand; 485} 486def uimm6s16 : Operand<i64>, ImmLeaf<i64, 487[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 488 let PrintMethod = "printImmScale<16>"; 489 let ParserMatchClass = UImm6s16Operand; 490} 491 492def SImmS2XForm : SDNodeXForm<imm, [{ 493 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 494}]>; 495def SImmS3XForm : SDNodeXForm<imm, [{ 496 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 497}]>; 498def SImmS4XForm : SDNodeXForm<imm, [{ 499 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 500}]>; 501def SImmS16XForm : SDNodeXForm<imm, [{ 502 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 503}]>; 504def SImmS32XForm : SDNodeXForm<imm, [{ 505 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 506}]>; 507 508// simm6sN predicate - True if the immediate is a multiple of N in the range 509// [-32 * N, 31 * N]. 510def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 511def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 512 let ParserMatchClass = SImm6s1Operand; 513 let DecoderMethod = "DecodeSImm<6>"; 514} 515 516// simm4sN predicate - True if the immediate is a multiple of N in the range 517// [ -8* N, 7 * N]. 518def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 519def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 520def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 521def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 522def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 523def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 524 525def simm4s1 : Operand<i64>, ImmLeaf<i64, 526[{ return Imm >=-8 && Imm <= 7; }]> { 527 let ParserMatchClass = SImm4s1Operand; 528 let DecoderMethod = "DecodeSImm<4>"; 529} 530 531def simm4s2 : Operand<i64>, ImmLeaf<i64, 532[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 533 let PrintMethod = "printImmScale<2>"; 534 let ParserMatchClass = SImm4s2Operand; 535 let DecoderMethod = "DecodeSImm<4>"; 536} 537 538def simm4s3 : Operand<i64>, ImmLeaf<i64, 539[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 540 let PrintMethod = "printImmScale<3>"; 541 let ParserMatchClass = SImm4s3Operand; 542 let DecoderMethod = "DecodeSImm<4>"; 543} 544 545def simm4s4 : Operand<i64>, ImmLeaf<i64, 546[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 547 let PrintMethod = "printImmScale<4>"; 548 let ParserMatchClass = SImm4s4Operand; 549 let DecoderMethod = "DecodeSImm<4>"; 550} 551def simm4s16 : Operand<i64>, ImmLeaf<i64, 552[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 553 let PrintMethod = "printImmScale<16>"; 554 let ParserMatchClass = SImm4s16Operand; 555 let DecoderMethod = "DecodeSImm<4>"; 556} 557def simm4s32 : Operand<i64>, ImmLeaf<i64, 558[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 559 let PrintMethod = "printImmScale<32>"; 560 let ParserMatchClass = SImm4s32Operand; 561 let DecoderMethod = "DecodeSImm<4>"; 562} 563 564def Imm1_8Operand : AsmImmRange<1, 8>; 565def Imm1_16Operand : AsmImmRange<1, 16>; 566def Imm1_32Operand : AsmImmRange<1, 32>; 567def Imm1_64Operand : AsmImmRange<1, 64>; 568 569class BranchTarget<int N> : AsmOperandClass { 570 let Name = "BranchTarget" # N; 571 let DiagnosticType = "InvalidLabel"; 572 let PredicateMethod = "isBranchTarget<" # N # ">"; 573} 574 575class PCRelLabel<int N> : BranchTarget<N> { 576 let Name = "PCRelLabel" # N; 577} 578 579def BranchTarget14Operand : BranchTarget<14>; 580def BranchTarget26Operand : BranchTarget<26>; 581def PCRelLabel19Operand : PCRelLabel<19>; 582 583def MovWSymbolG3AsmOperand : AsmOperandClass { 584 let Name = "MovWSymbolG3"; 585 let RenderMethod = "addImmOperands"; 586} 587 588def movw_symbol_g3 : Operand<i32> { 589 let ParserMatchClass = MovWSymbolG3AsmOperand; 590} 591 592def MovWSymbolG2AsmOperand : AsmOperandClass { 593 let Name = "MovWSymbolG2"; 594 let RenderMethod = "addImmOperands"; 595} 596 597def movw_symbol_g2 : Operand<i32> { 598 let ParserMatchClass = MovWSymbolG2AsmOperand; 599} 600 601def MovWSymbolG1AsmOperand : AsmOperandClass { 602 let Name = "MovWSymbolG1"; 603 let RenderMethod = "addImmOperands"; 604} 605 606def movw_symbol_g1 : Operand<i32> { 607 let ParserMatchClass = MovWSymbolG1AsmOperand; 608} 609 610def MovWSymbolG0AsmOperand : AsmOperandClass { 611 let Name = "MovWSymbolG0"; 612 let RenderMethod = "addImmOperands"; 613} 614 615def movw_symbol_g0 : Operand<i32> { 616 let ParserMatchClass = MovWSymbolG0AsmOperand; 617} 618 619class fixedpoint_i32<ValueType FloatVT> 620 : Operand<FloatVT>, 621 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 622 let EncoderMethod = "getFixedPointScaleOpValue"; 623 let DecoderMethod = "DecodeFixedPointScaleImm32"; 624 let ParserMatchClass = Imm1_32Operand; 625} 626 627class fixedpoint_i64<ValueType FloatVT> 628 : Operand<FloatVT>, 629 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 630 let EncoderMethod = "getFixedPointScaleOpValue"; 631 let DecoderMethod = "DecodeFixedPointScaleImm64"; 632 let ParserMatchClass = Imm1_64Operand; 633} 634 635def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 636def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 637def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 638 639def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 640def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 641def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 642 643def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 644 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 645}]> { 646 let EncoderMethod = "getVecShiftR8OpValue"; 647 let DecoderMethod = "DecodeVecShiftR8Imm"; 648 let ParserMatchClass = Imm1_8Operand; 649} 650def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 651 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 652}]> { 653 let EncoderMethod = "getVecShiftR16OpValue"; 654 let DecoderMethod = "DecodeVecShiftR16Imm"; 655 let ParserMatchClass = Imm1_16Operand; 656} 657def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 658 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 659}]> { 660 let EncoderMethod = "getVecShiftR16OpValue"; 661 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 662 let ParserMatchClass = Imm1_8Operand; 663} 664def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 665 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 666}]> { 667 let EncoderMethod = "getVecShiftR32OpValue"; 668 let DecoderMethod = "DecodeVecShiftR32Imm"; 669 let ParserMatchClass = Imm1_32Operand; 670} 671def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 672 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 673}]> { 674 let EncoderMethod = "getVecShiftR32OpValue"; 675 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 676 let ParserMatchClass = Imm1_16Operand; 677} 678def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 679 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 680}]> { 681 let EncoderMethod = "getVecShiftR64OpValue"; 682 let DecoderMethod = "DecodeVecShiftR64Imm"; 683 let ParserMatchClass = Imm1_64Operand; 684} 685def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 686 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 687}]> { 688 let EncoderMethod = "getVecShiftR64OpValue"; 689 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 690 let ParserMatchClass = Imm1_32Operand; 691} 692 693// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 694// (ImmLeaf) 695def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 696 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 697}]> { 698 let EncoderMethod = "getVecShiftR8OpValue"; 699 let DecoderMethod = "DecodeVecShiftR8Imm"; 700 let ParserMatchClass = Imm1_8Operand; 701} 702def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 703 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 704}]> { 705 let EncoderMethod = "getVecShiftR16OpValue"; 706 let DecoderMethod = "DecodeVecShiftR16Imm"; 707 let ParserMatchClass = Imm1_16Operand; 708} 709def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 710 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 711}]> { 712 let EncoderMethod = "getVecShiftR32OpValue"; 713 let DecoderMethod = "DecodeVecShiftR32Imm"; 714 let ParserMatchClass = Imm1_32Operand; 715} 716def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 717 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 718}]> { 719 let EncoderMethod = "getVecShiftR64OpValue"; 720 let DecoderMethod = "DecodeVecShiftR64Imm"; 721 let ParserMatchClass = Imm1_64Operand; 722} 723 724def Imm0_1Operand : AsmImmRange<0, 1>; 725def Imm0_3Operand : AsmImmRange<0, 3>; 726def Imm0_7Operand : AsmImmRange<0, 7>; 727def Imm0_15Operand : AsmImmRange<0, 15>; 728def Imm0_31Operand : AsmImmRange<0, 31>; 729def Imm0_63Operand : AsmImmRange<0, 63>; 730 731def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 732 return (((uint32_t)Imm) < 8); 733}]> { 734 let EncoderMethod = "getVecShiftL8OpValue"; 735 let DecoderMethod = "DecodeVecShiftL8Imm"; 736 let ParserMatchClass = Imm0_7Operand; 737} 738def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 739 return (((uint32_t)Imm) < 16); 740}]> { 741 let EncoderMethod = "getVecShiftL16OpValue"; 742 let DecoderMethod = "DecodeVecShiftL16Imm"; 743 let ParserMatchClass = Imm0_15Operand; 744} 745def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 746 return (((uint32_t)Imm) < 32); 747}]> { 748 let EncoderMethod = "getVecShiftL32OpValue"; 749 let DecoderMethod = "DecodeVecShiftL32Imm"; 750 let ParserMatchClass = Imm0_31Operand; 751} 752def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 753 return (((uint32_t)Imm) < 64); 754}]> { 755 let EncoderMethod = "getVecShiftL64OpValue"; 756 let DecoderMethod = "DecodeVecShiftL64Imm"; 757 let ParserMatchClass = Imm0_63Operand; 758} 759 760// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 761// (ImmLeaf) 762def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 763 return (((uint32_t)Imm) < 8); 764}]> { 765 let EncoderMethod = "getVecShiftL8OpValue"; 766 let DecoderMethod = "DecodeVecShiftL8Imm"; 767 let ParserMatchClass = Imm0_7Operand; 768} 769def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 770 return (((uint32_t)Imm) < 16); 771}]> { 772 let EncoderMethod = "getVecShiftL16OpValue"; 773 let DecoderMethod = "DecodeVecShiftL16Imm"; 774 let ParserMatchClass = Imm0_15Operand; 775} 776def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 777 return (((uint32_t)Imm) < 32); 778}]> { 779 let EncoderMethod = "getVecShiftL32OpValue"; 780 let DecoderMethod = "DecodeVecShiftL32Imm"; 781 let ParserMatchClass = Imm0_31Operand; 782} 783def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 784 return (((uint32_t)Imm) < 64); 785}]> { 786 let EncoderMethod = "getVecShiftL64OpValue"; 787 let DecoderMethod = "DecodeVecShiftL64Imm"; 788 let ParserMatchClass = Imm0_63Operand; 789} 790 791// Crazy immediate formats used by 32-bit and 64-bit logical immediate 792// instructions for splatting repeating bit patterns across the immediate. 793def logical_imm32_XFORM : SDNodeXForm<imm, [{ 794 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 795 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 796}]>; 797def logical_imm64_XFORM : SDNodeXForm<imm, [{ 798 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 799 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 800}]>; 801 802def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 803 GISDNodeXFormEquiv<logical_imm32_XFORM>; 804def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 805 GISDNodeXFormEquiv<logical_imm64_XFORM>; 806 807let DiagnosticType = "LogicalSecondSource" in { 808 def LogicalImm32Operand : AsmOperandClass { 809 let Name = "LogicalImm32"; 810 let PredicateMethod = "isLogicalImm<int32_t>"; 811 let RenderMethod = "addLogicalImmOperands<int32_t>"; 812 } 813 def LogicalImm64Operand : AsmOperandClass { 814 let Name = "LogicalImm64"; 815 let PredicateMethod = "isLogicalImm<int64_t>"; 816 let RenderMethod = "addLogicalImmOperands<int64_t>"; 817 } 818 def LogicalImm32NotOperand : AsmOperandClass { 819 let Name = "LogicalImm32Not"; 820 let PredicateMethod = "isLogicalImm<int32_t>"; 821 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 822 } 823 def LogicalImm64NotOperand : AsmOperandClass { 824 let Name = "LogicalImm64Not"; 825 let PredicateMethod = "isLogicalImm<int64_t>"; 826 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 827 } 828} 829def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 830 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 831}], logical_imm32_XFORM> { 832 let PrintMethod = "printLogicalImm<int32_t>"; 833 let ParserMatchClass = LogicalImm32Operand; 834} 835def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 836 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 837}], logical_imm64_XFORM> { 838 let PrintMethod = "printLogicalImm<int64_t>"; 839 let ParserMatchClass = LogicalImm64Operand; 840} 841def logical_imm32_not : Operand<i32> { 842 let ParserMatchClass = LogicalImm32NotOperand; 843} 844def logical_imm64_not : Operand<i64> { 845 let ParserMatchClass = LogicalImm64NotOperand; 846} 847 848// iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535]. 849let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 850def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{ 851 return ((uint32_t)Imm) < 65536; 852}]>; 853 854def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{ 855 return ((uint64_t)Imm) < 65536; 856}]>; 857} 858 859// imm0_255 predicate - True if the immediate is in the range [0,255]. 860def Imm0_255Operand : AsmImmRange<0,255>; 861 862def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 863 return ((uint32_t)Imm) < 256; 864}]> { 865 let ParserMatchClass = Imm0_255Operand; 866 let PrintMethod = "printImm"; 867} 868 869// imm0_127 predicate - True if the immediate is in the range [0,127] 870def Imm0_127Operand : AsmImmRange<0, 127>; 871def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 872 return ((uint32_t)Imm) < 128; 873}]> { 874 let ParserMatchClass = Imm0_127Operand; 875 let PrintMethod = "printImm"; 876} 877 878def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 879 return ((uint64_t)Imm) < 128; 880}]> { 881 let ParserMatchClass = Imm0_127Operand; 882 let PrintMethod = "printImm"; 883} 884 885// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 886// for all shift-amounts. 887 888// imm0_63 predicate - True if the immediate is in the range [0,63] 889def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 890 return ((uint64_t)Imm) < 64; 891}]> { 892 let ParserMatchClass = Imm0_63Operand; 893} 894 895def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 896 return ((uint64_t)Imm) < 64; 897}]> { 898 let ParserMatchClass = Imm0_63Operand; 899} 900 901// imm0_31 predicate - True if the immediate is in the range [0,31] 902def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 903 return ((uint64_t)Imm) < 32; 904}]> { 905 let ParserMatchClass = Imm0_31Operand; 906} 907 908// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 909// instead of Constant (ImmLeaf) 910def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 911 return ((uint64_t)Imm) < 32; 912}]> { 913 let ParserMatchClass = Imm0_31Operand; 914} 915 916// True if the 32-bit immediate is in the range [0,31] 917def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 918 return ((uint64_t)Imm) < 32; 919}]> { 920 let ParserMatchClass = Imm0_31Operand; 921} 922 923// imm0_1 predicate - True if the immediate is in the range [0,1] 924def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 925 return ((uint64_t)Imm) < 2; 926}]> { 927 let ParserMatchClass = Imm0_1Operand; 928} 929 930// timm0_1 - as above, but use TargetConstant (TImmLeaf) 931def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 932 return ((uint64_t)Imm) < 2; 933}]> { 934 let ParserMatchClass = Imm0_1Operand; 935} 936 937// imm0_15 predicate - True if the immediate is in the range [0,15] 938def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 939 return ((uint64_t)Imm) < 16; 940}]> { 941 let ParserMatchClass = Imm0_15Operand; 942} 943 944// imm0_7 predicate - True if the immediate is in the range [0,7] 945def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 946 return ((uint64_t)Imm) < 8; 947}]> { 948 let ParserMatchClass = Imm0_7Operand; 949} 950 951// imm0_3 predicate - True if the immediate is in the range [0,3] 952def imm0_3 : Operand<i64>, ImmLeaf<i64, [{ 953 return ((uint64_t)Imm) < 4; 954}]> { 955 let ParserMatchClass = Imm0_3Operand; 956} 957 958// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 959def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 960 return ((uint32_t)Imm) < 8; 961}]> { 962 let ParserMatchClass = Imm0_7Operand; 963} 964 965// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 966def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 967 return ((uint32_t)Imm) < 16; 968}]> { 969 let ParserMatchClass = Imm0_15Operand; 970} 971 972// An arithmetic shifter operand: 973// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 974// {5-0} - imm6 975class arith_shift<ValueType Ty, int width> : Operand<Ty> { 976 let PrintMethod = "printShifter"; 977 let ParserMatchClass = !cast<AsmOperandClass>( 978 "ArithmeticShifterOperand" # width); 979} 980 981def arith_shift32 : arith_shift<i32, 32>; 982def arith_shift64 : arith_shift<i64, 64>; 983 984class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 985 : Operand<Ty>, 986 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 987 let PrintMethod = "printShiftedRegister"; 988 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 989} 990 991def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 992def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 993 994def gi_arith_shifted_reg32 : 995 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 996 GIComplexPatternEquiv<arith_shifted_reg32>; 997 998def gi_arith_shifted_reg64 : 999 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 1000 GIComplexPatternEquiv<arith_shifted_reg64>; 1001 1002// An arithmetic shifter operand: 1003// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 1004// {5-0} - imm6 1005class logical_shift<int width> : Operand<i32> { 1006 let PrintMethod = "printShifter"; 1007 let ParserMatchClass = !cast<AsmOperandClass>( 1008 "LogicalShifterOperand" # width); 1009} 1010 1011def logical_shift32 : logical_shift<32>; 1012def logical_shift64 : logical_shift<64>; 1013 1014class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1015 : Operand<Ty>, 1016 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1017 let PrintMethod = "printShiftedRegister"; 1018 let MIOperandInfo = (ops regclass, shiftop); 1019} 1020 1021def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1022def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1023 1024def gi_logical_shifted_reg32 : 1025 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1026 GIComplexPatternEquiv<logical_shifted_reg32>; 1027 1028def gi_logical_shifted_reg64 : 1029 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1030 GIComplexPatternEquiv<logical_shifted_reg64>; 1031 1032// A logical vector shifter operand: 1033// {7-6} - shift type: 00 = lsl 1034// {5-0} - imm6: #0, #8, #16, or #24 1035def logical_vec_shift : Operand<i32> { 1036 let PrintMethod = "printShifter"; 1037 let EncoderMethod = "getVecShifterOpValue"; 1038 let ParserMatchClass = LogicalVecShifterOperand; 1039} 1040 1041// A logical vector half-word shifter operand: 1042// {7-6} - shift type: 00 = lsl 1043// {5-0} - imm6: #0 or #8 1044def logical_vec_hw_shift : Operand<i32> { 1045 let PrintMethod = "printShifter"; 1046 let EncoderMethod = "getVecShifterOpValue"; 1047 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1048} 1049 1050// A vector move shifter operand: 1051// {0} - imm1: #8 or #16 1052def move_vec_shift : Operand<i32> { 1053 let PrintMethod = "printShifter"; 1054 let EncoderMethod = "getMoveVecShifterOpValue"; 1055 let ParserMatchClass = MoveVecShifterOperand; 1056} 1057 1058let DiagnosticType = "AddSubSecondSource" in { 1059 def AddSubImmOperand : AsmOperandClass { 1060 let Name = "AddSubImm"; 1061 let ParserMethod = "tryParseImmWithOptionalShift"; 1062 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1063 } 1064 def AddSubImmNegOperand : AsmOperandClass { 1065 let Name = "AddSubImmNeg"; 1066 let ParserMethod = "tryParseImmWithOptionalShift"; 1067 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1068 } 1069} 1070// An ADD/SUB immediate shifter operand: 1071// second operand: 1072// {7-6} - shift type: 00 = lsl 1073// {5-0} - imm6: #0 or #12 1074class addsub_shifted_imm<ValueType Ty> 1075 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1076 let PrintMethod = "printAddSubImm"; 1077 let EncoderMethod = "getAddSubImmOpValue"; 1078 let ParserMatchClass = AddSubImmOperand; 1079 let MIOperandInfo = (ops i32imm, i32imm); 1080} 1081 1082class addsub_shifted_imm_neg<ValueType Ty> 1083 : Operand<Ty> { 1084 let EncoderMethod = "getAddSubImmOpValue"; 1085 let ParserMatchClass = AddSubImmNegOperand; 1086 let MIOperandInfo = (ops i32imm, i32imm); 1087} 1088 1089def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1090def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1091def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1092def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1093 1094def gi_addsub_shifted_imm32 : 1095 GIComplexOperandMatcher<s32, "selectArithImmed">, 1096 GIComplexPatternEquiv<addsub_shifted_imm32>; 1097 1098def gi_addsub_shifted_imm64 : 1099 GIComplexOperandMatcher<s64, "selectArithImmed">, 1100 GIComplexPatternEquiv<addsub_shifted_imm64>; 1101 1102class neg_addsub_shifted_imm<ValueType Ty> 1103 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1104 let PrintMethod = "printAddSubImm"; 1105 let EncoderMethod = "getAddSubImmOpValue"; 1106 let ParserMatchClass = AddSubImmOperand; 1107 let MIOperandInfo = (ops i32imm, i32imm); 1108} 1109 1110def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1111def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1112 1113def gi_neg_addsub_shifted_imm32 : 1114 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1115 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1116 1117def gi_neg_addsub_shifted_imm64 : 1118 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1119 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1120 1121// An extend operand: 1122// {5-3} - extend type 1123// {2-0} - imm3 1124def arith_extend : Operand<i32> { 1125 let PrintMethod = "printArithExtend"; 1126 let ParserMatchClass = ExtendOperand; 1127} 1128def arith_extend64 : Operand<i32> { 1129 let PrintMethod = "printArithExtend"; 1130 let ParserMatchClass = ExtendOperand64; 1131} 1132 1133// 'extend' that's a lsl of a 64-bit register. 1134def arith_extendlsl64 : Operand<i32> { 1135 let PrintMethod = "printArithExtend"; 1136 let ParserMatchClass = ExtendOperandLSL64; 1137} 1138 1139class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1140 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1141 let PrintMethod = "printExtendedRegister"; 1142 let MIOperandInfo = (ops GPR32, arith_extend); 1143} 1144 1145class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1146 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1147 let PrintMethod = "printExtendedRegister"; 1148 let MIOperandInfo = (ops GPR32, arith_extend64); 1149} 1150 1151def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1152def gi_arith_extended_reg32_i32 : 1153 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1154 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1155 1156def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1157def gi_arith_extended_reg32_i64 : 1158 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1159 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1160 1161def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1162def gi_arith_extended_reg32to64_i64 : 1163 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1164 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1165 1166// Floating-point immediate. 1167 1168def fpimm16XForm : SDNodeXForm<fpimm, [{ 1169 APFloat InVal = N->getValueAPF(); 1170 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1171 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1172 }]>; 1173 1174def fpimm32XForm : SDNodeXForm<fpimm, [{ 1175 APFloat InVal = N->getValueAPF(); 1176 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1177 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1178 }]>; 1179 1180def fpimm64XForm : SDNodeXForm<fpimm, [{ 1181 APFloat InVal = N->getValueAPF(); 1182 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1183 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1184 }]>; 1185 1186def fpimm16 : Operand<f16>, 1187 FPImmLeaf<f16, [{ 1188 return AArch64_AM::getFP16Imm(Imm) != -1; 1189 }], fpimm16XForm> { 1190 let ParserMatchClass = FPImmOperand; 1191 let PrintMethod = "printFPImmOperand"; 1192} 1193 1194def fpimm32 : Operand<f32>, 1195 FPImmLeaf<f32, [{ 1196 return AArch64_AM::getFP32Imm(Imm) != -1; 1197 }], fpimm32XForm> { 1198 let ParserMatchClass = FPImmOperand; 1199 let PrintMethod = "printFPImmOperand"; 1200} 1201def fpimm64 : Operand<f64>, 1202 FPImmLeaf<f64, [{ 1203 return AArch64_AM::getFP64Imm(Imm) != -1; 1204 }], fpimm64XForm> { 1205 let ParserMatchClass = FPImmOperand; 1206 let PrintMethod = "printFPImmOperand"; 1207} 1208 1209def fpimm8 : Operand<i32> { 1210 let ParserMatchClass = FPImmOperand; 1211 let PrintMethod = "printFPImmOperand"; 1212} 1213 1214def fpimm0 : FPImmLeaf<fAny, [{ 1215 return Imm.isExactlyValue(+0.0); 1216}]>; 1217 1218def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1219 GISDNodeXFormEquiv<fpimm16XForm>; 1220def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1221 GISDNodeXFormEquiv<fpimm32XForm>; 1222def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1223 GISDNodeXFormEquiv<fpimm64XForm>; 1224 1225// Vector lane operands 1226class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1227 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1228 let DiagnosticType = "Invalid" # Name; 1229 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1230 let RenderMethod = "addVectorIndexOperands"; 1231} 1232 1233class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1234 : Operand<ty> { 1235 let ParserMatchClass = mc; 1236 let PrintMethod = "printVectorIndex"; 1237} 1238 1239multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1240 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1241 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1242} 1243 1244def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1245def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1246def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1247def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1248def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1249 1250defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1251 [{ return ((uint64_t)Imm) == 1; }]>; 1252defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1253 [{ return ((uint64_t)Imm) < 16; }]>; 1254defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1255 [{ return ((uint64_t)Imm) < 8; }]>; 1256defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1257 [{ return ((uint64_t)Imm) < 4; }]>; 1258defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1259 [{ return ((uint64_t)Imm) < 2; }]>; 1260 1261defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1262 [{ return ((uint64_t)Imm) == 1; }]>; 1263defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1264 [{ return ((uint64_t)Imm) < 16; }]>; 1265defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1266 [{ return ((uint64_t)Imm) < 8; }]>; 1267defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1268 [{ return ((uint64_t)Imm) < 4; }]>; 1269defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1270 [{ return ((uint64_t)Imm) < 2; }]>; 1271 1272def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1273def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1274def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1275def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1276def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1277 1278defm sve_elm_idx_extdup_b 1279 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1280 [{ return ((uint64_t)Imm) < 64; }]>; 1281defm sve_elm_idx_extdup_h 1282 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1283 [{ return ((uint64_t)Imm) < 32; }]>; 1284defm sve_elm_idx_extdup_s 1285 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1286 [{ return ((uint64_t)Imm) < 16; }]>; 1287defm sve_elm_idx_extdup_d 1288 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1289 [{ return ((uint64_t)Imm) < 8; }]>; 1290defm sve_elm_idx_extdup_q 1291 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1292 [{ return ((uint64_t)Imm) < 4; }]>; 1293 1294// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1295// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1296// are encoded as the eight bit value 'abcdefgh'. 1297def simdimmtype10 : Operand<i32>, 1298 FPImmLeaf<f64, [{ 1299 return AArch64_AM::isAdvSIMDModImmType10( 1300 Imm.bitcastToAPInt().getZExtValue()); 1301 }], SDNodeXForm<fpimm, [{ 1302 APFloat InVal = N->getValueAPF(); 1303 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1304 .bitcastToAPInt() 1305 .getZExtValue()); 1306 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1307 }]>> { 1308 let ParserMatchClass = SIMDImmType10Operand; 1309 let PrintMethod = "printSIMDType10Operand"; 1310} 1311 1312 1313//--- 1314// System management 1315//--- 1316 1317// Base encoding for system instruction operands. 1318let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1319class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1320 list<dag> pattern = []> 1321 : I<oops, iops, asm, operands, "", pattern> { 1322 let Inst{31-22} = 0b1101010100; 1323 let Inst{21} = L; 1324} 1325 1326// System instructions which do not have an Rt register. 1327class SimpleSystemI<bit L, dag iops, string asm, string operands, 1328 list<dag> pattern = []> 1329 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1330 let Inst{4-0} = 0b11111; 1331} 1332 1333// System instructions which have an Rt register. 1334class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1335 list<dag> pattern = []> 1336 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1337 Sched<[WriteSys]> { 1338 bits<5> Rt; 1339 let Inst{4-0} = Rt; 1340} 1341 1342// System instructions for transactional memory extension 1343class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1344 string asm, string operands, list<dag> pattern> 1345 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1346 Sched<[WriteSys]> { 1347 let Inst{20-12} = 0b000110011; 1348 let Inst{11-8} = CRm; 1349 let Inst{7-5} = op2; 1350 let DecoderMethod = ""; 1351 1352 let mayLoad = 1; 1353 let mayStore = 1; 1354} 1355 1356// System instructions for transactional memory - single input operand 1357class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1358 : TMBaseSystemI<0b1, CRm, 0b011, 1359 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1360 bits<5> Rt; 1361 let Inst{4-0} = Rt; 1362} 1363 1364// System instructions that pass a register argument 1365// This class assumes the register is for input rather than output. 1366class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1367 list<dag> pattern = []> 1368 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1369 let Inst{20-12} = 0b000110001; 1370 let Inst{11-8} = CRm; 1371 let Inst{7-5} = Op2; 1372} 1373 1374// System instructions for transactional memory - no operand 1375class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1376 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1377 let Inst{4-0} = 0b11111; 1378} 1379 1380// System instructions for exit from transactions 1381class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1382 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>, 1383 Sched<[WriteSys]> { 1384 bits<16> imm; 1385 let Inst{31-24} = 0b11010100; 1386 let Inst{23-21} = op1; 1387 let Inst{20-5} = imm; 1388 let Inst{4-0} = 0b00000; 1389} 1390 1391// Hint instructions that take both a CRm and a 3-bit immediate. 1392// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1393// model patterns with sufficiently fine granularity 1394let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1395 class HintI<string mnemonic> 1396 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1397 [(int_aarch64_hint imm0_127:$imm)]>, 1398 Sched<[WriteHint]> { 1399 bits <7> imm; 1400 let Inst{20-12} = 0b000110010; 1401 let Inst{11-5} = imm; 1402 } 1403 1404// System instructions taking a single literal operand which encodes into 1405// CRm. op2 differentiates the opcodes. 1406def BarrierAsmOperand : AsmOperandClass { 1407 let Name = "Barrier"; 1408 let ParserMethod = "tryParseBarrierOperand"; 1409} 1410def barrier_op : Operand<i32> { 1411 let PrintMethod = "printBarrierOption"; 1412 let ParserMatchClass = BarrierAsmOperand; 1413} 1414def BarriernXSAsmOperand : AsmOperandClass { 1415 let Name = "BarriernXS"; 1416 let ParserMethod = "tryParseBarriernXSOperand"; 1417} 1418def barrier_nxs_op : Operand<i32> { 1419 let PrintMethod = "printBarriernXSOption"; 1420 let ParserMatchClass = BarriernXSAsmOperand; 1421} 1422class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1423 list<dag> pattern = []> 1424 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1425 Sched<[WriteBarrier]> { 1426 bits<4> CRm; 1427 let Inst{20-12} = 0b000110011; 1428 let Inst{11-8} = CRm; 1429 let Inst{7-5} = opc; 1430} 1431 1432class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1433 : SimpleSystemI<0, (ins), asm, "", pattern>, 1434 Sched<[]> { 1435 bits<4> CRm; 1436 let CRm = 0b0011; 1437 let Inst{31-12} = 0b11010101000000110010; 1438 let Inst{11-8} = CRm; 1439 let Inst{7-5} = op2; 1440 let Inst{4-0} = 0b11111; 1441} 1442 1443// MRS/MSR system instructions. These have different operand classes because 1444// a different subset of registers can be accessed through each instruction. 1445def MRSSystemRegisterOperand : AsmOperandClass { 1446 let Name = "MRSSystemRegister"; 1447 let ParserMethod = "tryParseSysReg"; 1448 let DiagnosticType = "MRS"; 1449} 1450// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1451def mrs_sysreg_op : Operand<i32> { 1452 let ParserMatchClass = MRSSystemRegisterOperand; 1453 let DecoderMethod = "DecodeMRSSystemRegister"; 1454 let PrintMethod = "printMRSSystemRegister"; 1455} 1456 1457def MSRSystemRegisterOperand : AsmOperandClass { 1458 let Name = "MSRSystemRegister"; 1459 let ParserMethod = "tryParseSysReg"; 1460 let DiagnosticType = "MSR"; 1461} 1462def msr_sysreg_op : Operand<i32> { 1463 let ParserMatchClass = MSRSystemRegisterOperand; 1464 let DecoderMethod = "DecodeMSRSystemRegister"; 1465 let PrintMethod = "printMSRSystemRegister"; 1466} 1467 1468def PSBHintOperand : AsmOperandClass { 1469 let Name = "PSBHint"; 1470 let ParserMethod = "tryParsePSBHint"; 1471} 1472def psbhint_op : Operand<i32> { 1473 let ParserMatchClass = PSBHintOperand; 1474 let PrintMethod = "printPSBHintOp"; 1475 let MCOperandPredicate = [{ 1476 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1477 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1478 if (!MCOp.isImm()) 1479 return false; 1480 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1481 }]; 1482} 1483 1484def BTIHintOperand : AsmOperandClass { 1485 let Name = "BTIHint"; 1486 let ParserMethod = "tryParseBTIHint"; 1487} 1488def btihint_op : Operand<i32> { 1489 let ParserMatchClass = BTIHintOperand; 1490 let PrintMethod = "printBTIHintOp"; 1491 let MCOperandPredicate = [{ 1492 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1493 if (!MCOp.isImm()) 1494 return false; 1495 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1496 }]; 1497} 1498 1499class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1500 "mrs", "\t$Rt, $systemreg"> { 1501 bits<16> systemreg; 1502 let Inst{20-5} = systemreg; 1503 let DecoderNamespace = "Fallback"; 1504 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1505 // require doing this. The alternative was to explicitly model each one, but 1506 // it feels like it is unnecessary because it seems there are no negative 1507 // consequences setting these flags for all. 1508 let Defs = [NZCV]; 1509} 1510 1511// FIXME: Some of these def NZCV, others don't. Best way to model that? 1512// Explicitly modeling each of the system register as a register class 1513// would do it, but feels like overkill at this point. 1514class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1515 "msr", "\t$systemreg, $Rt"> { 1516 bits<16> systemreg; 1517 let Inst{20-5} = systemreg; 1518 let DecoderNamespace = "Fallback"; 1519} 1520 1521def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1522 let Name = "SystemPStateFieldWithImm0_15"; 1523 let ParserMethod = "tryParseSysReg"; 1524} 1525def pstatefield4_op : Operand<i32> { 1526 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1527 let PrintMethod = "printSystemPStateField"; 1528} 1529 1530// Instructions to modify PSTATE, no input reg 1531let Defs = [NZCV] in 1532class PstateWriteSimple<dag iops, string asm, string operands> 1533 : SimpleSystemI<0, iops, asm, operands> { 1534 1535 let Inst{20-19} = 0b00; 1536 let Inst{15-12} = 0b0100; 1537} 1538 1539class MSRpstateImm0_15 1540 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1541 "\t$pstatefield, $imm">, 1542 Sched<[WriteSys]> { 1543 1544 bits<6> pstatefield; 1545 bits<4> imm; 1546 let Inst{18-16} = pstatefield{5-3}; 1547 let Inst{11-8} = imm; 1548 let Inst{7-5} = pstatefield{2-0}; 1549 1550 let DecoderMethod = "DecodeSystemPStateInstruction"; 1551 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1552 // Fail the decoder should attempt to decode the instruction as MSRI. 1553 let hasCompleteDecoder = 0; 1554} 1555 1556def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1557 let Name = "SystemPStateFieldWithImm0_1"; 1558 let ParserMethod = "tryParseSysReg"; 1559} 1560def pstatefield1_op : Operand<i32> { 1561 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1562 let PrintMethod = "printSystemPStateField"; 1563} 1564 1565class MSRpstateImm0_1 1566 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1567 "\t$pstatefield, $imm">, 1568 Sched<[WriteSys]> { 1569 1570 bits<6> pstatefield; 1571 bit imm; 1572 let Inst{18-16} = pstatefield{5-3}; 1573 let Inst{11-9} = 0b000; 1574 let Inst{8} = imm; 1575 let Inst{7-5} = pstatefield{2-0}; 1576 1577 let DecoderMethod = "DecodeSystemPStateInstruction"; 1578 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1579 // Fail the decoder should attempt to decode the instruction as MSRI. 1580 let hasCompleteDecoder = 0; 1581} 1582 1583// SYS and SYSL generic system instructions. 1584def SysCRAsmOperand : AsmOperandClass { 1585 let Name = "SysCR"; 1586 let ParserMethod = "tryParseSysCROperand"; 1587} 1588 1589def sys_cr_op : Operand<i32> { 1590 let PrintMethod = "printSysCROperand"; 1591 let ParserMatchClass = SysCRAsmOperand; 1592} 1593 1594class SystemXtI<bit L, string asm> 1595 : RtSystemI<L, (outs), 1596 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1597 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1598 bits<3> op1; 1599 bits<4> Cn; 1600 bits<4> Cm; 1601 bits<3> op2; 1602 let Inst{20-19} = 0b01; 1603 let Inst{18-16} = op1; 1604 let Inst{15-12} = Cn; 1605 let Inst{11-8} = Cm; 1606 let Inst{7-5} = op2; 1607} 1608 1609class SystemLXtI<bit L, string asm> 1610 : RtSystemI<L, (outs), 1611 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1612 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1613 bits<3> op1; 1614 bits<4> Cn; 1615 bits<4> Cm; 1616 bits<3> op2; 1617 let Inst{20-19} = 0b01; 1618 let Inst{18-16} = op1; 1619 let Inst{15-12} = Cn; 1620 let Inst{11-8} = Cm; 1621 let Inst{7-5} = op2; 1622} 1623 1624 1625// Branch (register) instructions: 1626// 1627// case opc of 1628// 0001 blr 1629// 0000 br 1630// 0101 dret 1631// 0100 eret 1632// 0010 ret 1633// otherwise UNDEFINED 1634class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1635 string operands, list<dag> pattern> 1636 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1637 let Inst{31-25} = 0b1101011; 1638 let Inst{24-21} = opc; 1639 let Inst{20-16} = 0b11111; 1640 let Inst{15-10} = 0b000000; 1641 let Inst{4-0} = 0b00000; 1642} 1643 1644class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1645 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1646 bits<5> Rn; 1647 let Inst{9-5} = Rn; 1648} 1649 1650let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1651class SpecialReturn<bits<4> opc, string asm> 1652 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1653 let Inst{9-5} = 0b11111; 1654} 1655 1656let mayLoad = 1 in 1657class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1658 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1659 Sched<[]> { 1660 bits<5> Rn; 1661 bits<5> Rt; 1662 let Inst{31-30} = sz; 1663 let Inst{29-10} = 0b11100010111111110000; 1664 let Inst{9-5} = Rn; 1665 let Inst{4-0} = Rt; 1666} 1667 1668class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1669 list<dag> pattern> 1670 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1671 let isAuthenticated = 1; 1672 let Inst{31-25} = 0b1101011; 1673 let Inst{20-11} = 0b1111100001; 1674 let Inst{10} = M; 1675 let Inst{4-0} = 0b11111; 1676} 1677 1678class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1679 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1680 bits<5> Rn; 1681 bits<5> Rm; 1682 let Inst{24-22} = 0b100; 1683 let Inst{21} = op; 1684 let Inst{9-5} = Rn; 1685 let Inst{4-0} = Rm; 1686} 1687 1688class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1689 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1690 bits<5> Rn; 1691 let Inst{24} = 0; 1692 let Inst{23-21} = opc; 1693 let Inst{9-5} = Rn; 1694} 1695 1696let Uses = [LR,SP] in 1697class AuthReturn<bits<3> op, bits<1> M, string asm> 1698 : AuthBase<M, (outs), (ins), asm, "", []> { 1699 let Inst{24} = 0; 1700 let Inst{23-21} = op; 1701 let Inst{9-0} = 0b1111111111; 1702} 1703 1704let mayLoad = 1 in 1705class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1706 string operands, string cstr, Operand opr> 1707 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1708 bits<10> offset; 1709 bits<5> Rn; 1710 bits<5> Rt; 1711 let isAuthenticated = 1; 1712 let Inst{31-24} = 0b11111000; 1713 let Inst{23} = M; 1714 let Inst{22} = offset{9}; 1715 let Inst{21} = 1; 1716 let Inst{20-12} = offset{8-0}; 1717 let Inst{11} = W; 1718 let Inst{10} = 1; 1719 let Inst{9-5} = Rn; 1720 let Inst{4-0} = Rt; 1721 1722 let DecoderMethod = "DecodeAuthLoadInstruction"; 1723} 1724 1725multiclass AuthLoad<bit M, string asm, Operand opr> { 1726 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1727 (ins GPR64sp:$Rn, opr:$offset), 1728 asm, "\t$Rt, [$Rn, $offset]", "", opr>; 1729 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1730 (ins GPR64sp:$Rn, opr:$offset), 1731 asm, "\t$Rt, [$Rn, $offset]!", 1732 "$Rn = $wback,@earlyclobber $wback", opr>; 1733 1734 def : InstAlias<asm # "\t$Rt, [$Rn]", 1735 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1736 1737 def : InstAlias<asm # "\t$Rt, [$wback]!", 1738 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1739} 1740 1741//--- 1742// Conditional branch instruction. 1743//--- 1744 1745// Condition code. 1746// 4-bit immediate. Pretty-printed as <cc> 1747def ccode : Operand<i32> { 1748 let PrintMethod = "printCondCode"; 1749 let ParserMatchClass = CondCode; 1750} 1751def inv_ccode : Operand<i32> { 1752 // AL and NV are invalid in the aliases which use inv_ccode 1753 let PrintMethod = "printInverseCondCode"; 1754 let ParserMatchClass = CondCode; 1755 let MCOperandPredicate = [{ 1756 return MCOp.isImm() && 1757 MCOp.getImm() != AArch64CC::AL && 1758 MCOp.getImm() != AArch64CC::NV; 1759 }]; 1760} 1761 1762// Conditional branch target. 19-bit immediate. The low two bits of the target 1763// offset are implied zero and so are not part of the immediate. 1764def am_brcond : Operand<OtherVT> { 1765 let EncoderMethod = "getCondBranchTargetOpValue"; 1766 let DecoderMethod = "DecodePCRelLabel19"; 1767 let PrintMethod = "printAlignedLabel"; 1768 let ParserMatchClass = PCRelLabel19Operand; 1769 let OperandType = "OPERAND_PCREL"; 1770} 1771 1772class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1773 "b", ".$cond\t$target", "", 1774 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1775 Sched<[WriteBr]> { 1776 let isBranch = 1; 1777 let isTerminator = 1; 1778 let Uses = [NZCV]; 1779 1780 bits<4> cond; 1781 bits<19> target; 1782 let Inst{31-24} = 0b01010100; 1783 let Inst{23-5} = target; 1784 let Inst{4} = 0; 1785 let Inst{3-0} = cond; 1786} 1787 1788//--- 1789// Compare-and-branch instructions. 1790//--- 1791class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1792 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1793 asm, "\t$Rt, $target", "", 1794 [(node regtype:$Rt, bb:$target)]>, 1795 Sched<[WriteBr]> { 1796 let isBranch = 1; 1797 let isTerminator = 1; 1798 1799 bits<5> Rt; 1800 bits<19> target; 1801 let Inst{30-25} = 0b011010; 1802 let Inst{24} = op; 1803 let Inst{23-5} = target; 1804 let Inst{4-0} = Rt; 1805} 1806 1807multiclass CmpBranch<bit op, string asm, SDNode node> { 1808 def W : BaseCmpBranch<GPR32, op, asm, node> { 1809 let Inst{31} = 0; 1810 } 1811 def X : BaseCmpBranch<GPR64, op, asm, node> { 1812 let Inst{31} = 1; 1813 } 1814} 1815 1816//--- 1817// Test-bit-and-branch instructions. 1818//--- 1819// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1820// the target offset are implied zero and so are not part of the immediate. 1821def am_tbrcond : Operand<OtherVT> { 1822 let EncoderMethod = "getTestBranchTargetOpValue"; 1823 let PrintMethod = "printAlignedLabel"; 1824 let ParserMatchClass = BranchTarget14Operand; 1825 let OperandType = "OPERAND_PCREL"; 1826} 1827 1828// AsmOperand classes to emit (or not) special diagnostics 1829def TBZImm0_31Operand : AsmOperandClass { 1830 let Name = "TBZImm0_31"; 1831 let PredicateMethod = "isImmInRange<0,31>"; 1832 let RenderMethod = "addImmOperands"; 1833} 1834def TBZImm32_63Operand : AsmOperandClass { 1835 let Name = "Imm32_63"; 1836 let PredicateMethod = "isImmInRange<32,63>"; 1837 let DiagnosticType = "InvalidImm0_63"; 1838 let RenderMethod = "addImmOperands"; 1839} 1840 1841class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1842 return (((uint32_t)Imm) < 32); 1843}]> { 1844 let ParserMatchClass = matcher; 1845} 1846 1847def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1848def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1849 1850def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1851 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1852}]> { 1853 let ParserMatchClass = TBZImm32_63Operand; 1854} 1855 1856class BaseTestBranch<RegisterClass regtype, Operand immtype, 1857 bit op, string asm, SDNode node> 1858 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1859 asm, "\t$Rt, $bit_off, $target", "", 1860 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1861 Sched<[WriteBr]> { 1862 let isBranch = 1; 1863 let isTerminator = 1; 1864 1865 bits<5> Rt; 1866 bits<6> bit_off; 1867 bits<14> target; 1868 1869 let Inst{30-25} = 0b011011; 1870 let Inst{24} = op; 1871 let Inst{23-19} = bit_off{4-0}; 1872 let Inst{18-5} = target; 1873 let Inst{4-0} = Rt; 1874 1875 let DecoderMethod = "DecodeTestAndBranch"; 1876} 1877 1878multiclass TestBranch<bit op, string asm, SDNode node> { 1879 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1880 let Inst{31} = 0; 1881 } 1882 1883 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1884 let Inst{31} = 1; 1885 } 1886 1887 // Alias X-reg with 0-31 imm to W-Reg. 1888 def : InstAlias<asm # "\t$Rd, $imm, $target", 1889 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1890 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1891 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1892 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1893 tbz_imm0_31_diag:$imm, bb:$target)>; 1894} 1895 1896//--- 1897// Unconditional branch (immediate) instructions. 1898//--- 1899def am_b_target : Operand<OtherVT> { 1900 let EncoderMethod = "getBranchTargetOpValue"; 1901 let PrintMethod = "printAlignedLabel"; 1902 let ParserMatchClass = BranchTarget26Operand; 1903 let OperandType = "OPERAND_PCREL"; 1904} 1905def am_bl_target : Operand<i64> { 1906 let EncoderMethod = "getBranchTargetOpValue"; 1907 let PrintMethod = "printAlignedLabel"; 1908 let ParserMatchClass = BranchTarget26Operand; 1909 let OperandType = "OPERAND_PCREL"; 1910} 1911 1912class BImm<bit op, dag iops, string asm, list<dag> pattern> 1913 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1914 bits<26> addr; 1915 let Inst{31} = op; 1916 let Inst{30-26} = 0b00101; 1917 let Inst{25-0} = addr; 1918 1919 let DecoderMethod = "DecodeUnconditionalBranch"; 1920} 1921 1922class BranchImm<bit op, string asm, list<dag> pattern> 1923 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1924class CallImm<bit op, string asm, list<dag> pattern> 1925 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1926 1927//--- 1928// Basic one-operand data processing instructions. 1929//--- 1930 1931let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1932class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1933 SDPatternOperator node> 1934 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1935 [(set regtype:$Rd, (node regtype:$Rn))]>, 1936 Sched<[WriteI, ReadI]> { 1937 bits<5> Rd; 1938 bits<5> Rn; 1939 1940 let Inst{30-13} = 0b101101011000000000; 1941 let Inst{12-10} = opc; 1942 let Inst{9-5} = Rn; 1943 let Inst{4-0} = Rd; 1944} 1945 1946let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1947multiclass OneOperandData<bits<3> opc, string asm, 1948 SDPatternOperator node = null_frag> { 1949 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1950 let Inst{31} = 0; 1951 } 1952 1953 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1954 let Inst{31} = 1; 1955 } 1956} 1957 1958class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1959 : BaseOneOperandData<opc, GPR32, asm, node> { 1960 let Inst{31} = 0; 1961} 1962 1963class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1964 : BaseOneOperandData<opc, GPR64, asm, node> { 1965 let Inst{31} = 1; 1966} 1967 1968class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm> 1969 : I<(outs GPR64:$Rd), (ins GPR64:$src, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 1970 "$Rd = $src", 1971 []>, 1972 Sched<[WriteI, ReadI]> { 1973 bits<5> Rd; 1974 bits<5> Rn; 1975 let Inst{31-15} = 0b11011010110000010; 1976 let Inst{14-12} = opcode_prefix; 1977 let Inst{11-10} = opcode; 1978 let Inst{9-5} = Rn; 1979 let Inst{4-0} = Rd; 1980} 1981 1982class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm> 1983 : I<(outs GPR64:$Rd), (ins GPR64:$src), asm, "\t$Rd", "$Rd = $src", 1984 []>, Sched<[]> { 1985 bits<5> Rd; 1986 let Inst{31-15} = 0b11011010110000010; 1987 let Inst{14-12} = opcode_prefix; 1988 let Inst{11-10} = opcode; 1989 let Inst{9-5} = 0b11111; 1990 let Inst{4-0} = Rd; 1991} 1992 1993class SignAuthTwoOperand<bits<4> opc, string asm, 1994 SDPatternOperator OpNode> 1995 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 1996 asm, "\t$Rd, $Rn, $Rm", "", 1997 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 1998 Sched<[WriteI, ReadI, ReadI]> { 1999 bits<5> Rd; 2000 bits<5> Rn; 2001 bits<5> Rm; 2002 let Inst{31-21} = 0b10011010110; 2003 let Inst{20-16} = Rm; 2004 let Inst{15-14} = 0b00; 2005 let Inst{13-10} = opc; 2006 let Inst{9-5} = Rn; 2007 let Inst{4-0} = Rd; 2008} 2009 2010class ClearAuth<bits<1> data, string asm> 2011 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2012 bits<5> Rd; 2013 let Inst{31-11} = 0b110110101100000101000; 2014 let Inst{10} = data; 2015 let Inst{9-5} = 0b11111; 2016 let Inst{4-0} = Rd; 2017} 2018 2019// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2020class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2021 : I<(outs), iops, asm, ops, "", []>, 2022 Sched<[WriteI, ReadI, ReadI]> { 2023 let Uses = [NZCV]; 2024 let Defs = [NZCV]; 2025 bits<5> Rn; 2026 let Inst{31} = sf; 2027 let Inst{30-15} = 0b0111010000000000; 2028 let Inst{14} = sz; 2029 let Inst{13-10} = 0b0010; 2030 let Inst{9-5} = Rn; 2031 let Inst{4-0} = 0b01101; 2032} 2033 2034class FlagRotate<dag iops, string asm, string ops> 2035 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2036 bits<6> imm; 2037 bits<4> mask; 2038 let Inst{20-15} = imm; 2039 let Inst{13-10} = 0b0001; 2040 let Inst{4} = 0b0; 2041 let Inst{3-0} = mask; 2042} 2043 2044//--- 2045// Basic two-operand data processing instructions. 2046//--- 2047class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2048 list<dag> pattern> 2049 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2050 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2051 Sched<[WriteI, ReadI, ReadI]> { 2052 let Uses = [NZCV]; 2053 bits<5> Rd; 2054 bits<5> Rn; 2055 bits<5> Rm; 2056 let Inst{30} = isSub; 2057 let Inst{28-21} = 0b11010000; 2058 let Inst{20-16} = Rm; 2059 let Inst{15-10} = 0; 2060 let Inst{9-5} = Rn; 2061 let Inst{4-0} = Rd; 2062} 2063 2064class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2065 SDNode OpNode> 2066 : BaseBaseAddSubCarry<isSub, regtype, asm, 2067 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2068 2069class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2070 SDNode OpNode> 2071 : BaseBaseAddSubCarry<isSub, regtype, asm, 2072 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2073 (implicit NZCV)]> { 2074 let Defs = [NZCV]; 2075} 2076 2077multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2078 SDNode OpNode, SDNode OpNode_setflags> { 2079 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2080 let Inst{31} = 0; 2081 let Inst{29} = 0; 2082 } 2083 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2084 let Inst{31} = 1; 2085 let Inst{29} = 0; 2086 } 2087 2088 // Sets flags. 2089 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2090 OpNode_setflags> { 2091 let Inst{31} = 0; 2092 let Inst{29} = 1; 2093 } 2094 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2095 OpNode_setflags> { 2096 let Inst{31} = 1; 2097 let Inst{29} = 1; 2098 } 2099} 2100 2101class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2102 SDPatternOperator OpNode, 2103 RegisterClass in1regtype = regtype, 2104 RegisterClass in2regtype = regtype> 2105 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2106 asm, "\t$Rd, $Rn, $Rm", "", 2107 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2108 bits<5> Rd; 2109 bits<5> Rn; 2110 bits<5> Rm; 2111 let Inst{30-21} = 0b0011010110; 2112 let Inst{20-16} = Rm; 2113 let Inst{15-14} = 0b00; 2114 let Inst{13-10} = opc; 2115 let Inst{9-5} = Rn; 2116 let Inst{4-0} = Rd; 2117} 2118 2119class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2120 SDPatternOperator OpNode> 2121 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2122 let Inst{10} = isSigned; 2123} 2124 2125multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2126 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2127 Sched<[WriteID32, ReadID, ReadID]> { 2128 let Inst{31} = 0; 2129 } 2130 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2131 Sched<[WriteID64, ReadID, ReadID]> { 2132 let Inst{31} = 1; 2133 } 2134} 2135 2136class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2137 SDPatternOperator OpNode = null_frag> 2138 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2139 Sched<[WriteIS, ReadI]> { 2140 let Inst{11-10} = shift_type; 2141} 2142 2143multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2144 def Wr : BaseShift<shift_type, GPR32, asm> { 2145 let Inst{31} = 0; 2146 } 2147 2148 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2149 let Inst{31} = 1; 2150 } 2151 2152 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2153 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2154 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2155 2156 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2157 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2158 2159 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2160 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2161 2162 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2163 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2164 2165 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2166 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2167 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2168 2169 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2170 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2171 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2172} 2173 2174class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2175 : InstAlias<asm#"\t$dst, $src1, $src2", 2176 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2177 2178class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2179 RegisterClass addtype, string asm, 2180 list<dag> pattern> 2181 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2182 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2183 bits<5> Rd; 2184 bits<5> Rn; 2185 bits<5> Rm; 2186 bits<5> Ra; 2187 let Inst{30-24} = 0b0011011; 2188 let Inst{23-21} = opc; 2189 let Inst{20-16} = Rm; 2190 let Inst{15} = isSub; 2191 let Inst{14-10} = Ra; 2192 let Inst{9-5} = Rn; 2193 let Inst{4-0} = Rd; 2194} 2195 2196multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 2197 // MADD/MSUB generation is decided by MachineCombiner.cpp 2198 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 2199 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 2200 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2201 let Inst{31} = 0; 2202 } 2203 2204 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 2205 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 2206 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2207 let Inst{31} = 1; 2208 } 2209} 2210 2211class WideMulAccum<bit isSub, bits<3> opc, string asm, 2212 SDNode AccNode, SDNode ExtNode> 2213 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2214 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2215 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2216 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2217 let Inst{31} = 1; 2218} 2219 2220class MulHi<bits<3> opc, string asm, SDNode OpNode> 2221 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2222 asm, "\t$Rd, $Rn, $Rm", "", 2223 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2224 Sched<[WriteIM64, ReadIM, ReadIM]> { 2225 bits<5> Rd; 2226 bits<5> Rn; 2227 bits<5> Rm; 2228 let Inst{31-24} = 0b10011011; 2229 let Inst{23-21} = opc; 2230 let Inst{20-16} = Rm; 2231 let Inst{15} = 0; 2232 let Inst{9-5} = Rn; 2233 let Inst{4-0} = Rd; 2234 2235 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2236 // (i.e. all bits 1) but is ignored by the processor. 2237 let PostEncoderMethod = "fixMulHigh"; 2238} 2239 2240class MulAccumWAlias<string asm, Instruction inst> 2241 : InstAlias<asm#"\t$dst, $src1, $src2", 2242 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2243class MulAccumXAlias<string asm, Instruction inst> 2244 : InstAlias<asm#"\t$dst, $src1, $src2", 2245 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2246class WideMulAccumAlias<string asm, Instruction inst> 2247 : InstAlias<asm#"\t$dst, $src1, $src2", 2248 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2249 2250class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2251 SDPatternOperator OpNode, string asm> 2252 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2253 asm, "\t$Rd, $Rn, $Rm", "", 2254 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2255 Sched<[WriteISReg, ReadI, ReadISReg]> { 2256 bits<5> Rd; 2257 bits<5> Rn; 2258 bits<5> Rm; 2259 2260 let Inst{31} = sf; 2261 let Inst{30-21} = 0b0011010110; 2262 let Inst{20-16} = Rm; 2263 let Inst{15-13} = 0b010; 2264 let Inst{12} = C; 2265 let Inst{11-10} = sz; 2266 let Inst{9-5} = Rn; 2267 let Inst{4-0} = Rd; 2268 let Predicates = [HasCRC]; 2269} 2270 2271//--- 2272// Address generation. 2273//--- 2274 2275class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2276 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2277 pattern>, 2278 Sched<[WriteI]> { 2279 bits<5> Xd; 2280 bits<21> label; 2281 let Inst{31} = page; 2282 let Inst{30-29} = label{1-0}; 2283 let Inst{28-24} = 0b10000; 2284 let Inst{23-5} = label{20-2}; 2285 let Inst{4-0} = Xd; 2286 2287 let DecoderMethod = "DecodeAdrInstruction"; 2288} 2289 2290//--- 2291// Move immediate. 2292//--- 2293 2294def movimm32_imm : Operand<i32> { 2295 let ParserMatchClass = AsmImmRange<0, 65535>; 2296 let EncoderMethod = "getMoveWideImmOpValue"; 2297 let PrintMethod = "printImm"; 2298} 2299def movimm32_shift : Operand<i32> { 2300 let PrintMethod = "printShifter"; 2301 let ParserMatchClass = MovImm32ShifterOperand; 2302} 2303def movimm64_shift : Operand<i32> { 2304 let PrintMethod = "printShifter"; 2305 let ParserMatchClass = MovImm64ShifterOperand; 2306} 2307 2308let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2309class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2310 string asm> 2311 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2312 asm, "\t$Rd, $imm$shift", "", []>, 2313 Sched<[WriteImm]> { 2314 bits<5> Rd; 2315 bits<16> imm; 2316 bits<6> shift; 2317 let Inst{30-29} = opc; 2318 let Inst{28-23} = 0b100101; 2319 let Inst{22-21} = shift{5-4}; 2320 let Inst{20-5} = imm; 2321 let Inst{4-0} = Rd; 2322 2323 let DecoderMethod = "DecodeMoveImmInstruction"; 2324} 2325 2326multiclass MoveImmediate<bits<2> opc, string asm> { 2327 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2328 let Inst{31} = 0; 2329 } 2330 2331 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2332 let Inst{31} = 1; 2333 } 2334} 2335 2336let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2337class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2338 string asm> 2339 : I<(outs regtype:$Rd), 2340 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2341 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2342 Sched<[WriteI, ReadI]> { 2343 bits<5> Rd; 2344 bits<16> imm; 2345 bits<6> shift; 2346 let Inst{30-29} = opc; 2347 let Inst{28-23} = 0b100101; 2348 let Inst{22-21} = shift{5-4}; 2349 let Inst{20-5} = imm; 2350 let Inst{4-0} = Rd; 2351 2352 let DecoderMethod = "DecodeMoveImmInstruction"; 2353} 2354 2355multiclass InsertImmediate<bits<2> opc, string asm> { 2356 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2357 let Inst{31} = 0; 2358 } 2359 2360 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2361 let Inst{31} = 1; 2362 } 2363} 2364 2365//--- 2366// Add/Subtract 2367//--- 2368 2369class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2370 string asm_inst, string asm_ops, 2371 dag inputs, dag pattern> 2372 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2373 Sched<[WriteI, ReadI]> { 2374 bits<5> Rd; 2375 bits<5> Rn; 2376 let Inst{30} = isSub; 2377 let Inst{29} = setFlags; 2378 let Inst{28-24} = 0b10001; 2379 let Inst{9-5} = Rn; 2380 let Inst{4-0} = Rd; 2381} 2382 2383class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2384 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2385 string asm_inst, SDPatternOperator OpNode> 2386 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2387 (ins srcRegtype:$Rn, immtype:$imm), 2388 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2389 bits<14> imm; 2390 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2391 let Inst{21-10} = imm{11-0}; 2392 let DecoderMethod = "DecodeAddSubImmShift"; 2393} 2394 2395class BaseAddSubRegPseudo<RegisterClass regtype, 2396 SDPatternOperator OpNode> 2397 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2398 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2399 Sched<[WriteI, ReadI, ReadI]>; 2400 2401class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2402 arith_shifted_reg shifted_regtype, string asm, 2403 SDPatternOperator OpNode> 2404 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2405 asm, "\t$Rd, $Rn, $Rm", "", 2406 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2407 Sched<[WriteISReg, ReadI, ReadISReg]> { 2408 // The operands are in order to match the 'addr' MI operands, so we 2409 // don't need an encoder method and by-name matching. Just use the default 2410 // in-order handling. Since we're using by-order, make sure the names 2411 // do not match. 2412 bits<5> dst; 2413 bits<5> src1; 2414 bits<5> src2; 2415 bits<8> shift; 2416 let Inst{30} = isSub; 2417 let Inst{29} = setFlags; 2418 let Inst{28-24} = 0b01011; 2419 let Inst{23-22} = shift{7-6}; 2420 let Inst{21} = 0; 2421 let Inst{20-16} = src2; 2422 let Inst{15-10} = shift{5-0}; 2423 let Inst{9-5} = src1; 2424 let Inst{4-0} = dst; 2425 2426 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2427} 2428 2429class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2430 RegisterClass src1Regtype, Operand src2Regtype, 2431 string asm, SDPatternOperator OpNode> 2432 : I<(outs dstRegtype:$R1), 2433 (ins src1Regtype:$R2, src2Regtype:$R3), 2434 asm, "\t$R1, $R2, $R3", "", 2435 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2436 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2437 bits<5> Rd; 2438 bits<5> Rn; 2439 bits<5> Rm; 2440 bits<6> ext; 2441 let Inst{30} = isSub; 2442 let Inst{29} = setFlags; 2443 let Inst{28-24} = 0b01011; 2444 let Inst{23-21} = 0b001; 2445 let Inst{20-16} = Rm; 2446 let Inst{15-13} = ext{5-3}; 2447 let Inst{12-10} = ext{2-0}; 2448 let Inst{9-5} = Rn; 2449 let Inst{4-0} = Rd; 2450 2451 let DecoderMethod = "DecodeAddSubERegInstruction"; 2452} 2453 2454let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2455class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2456 RegisterClass src1Regtype, RegisterClass src2Regtype, 2457 Operand ext_op, string asm> 2458 : I<(outs dstRegtype:$Rd), 2459 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2460 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2461 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2462 bits<5> Rd; 2463 bits<5> Rn; 2464 bits<5> Rm; 2465 bits<6> ext; 2466 let Inst{30} = isSub; 2467 let Inst{29} = setFlags; 2468 let Inst{28-24} = 0b01011; 2469 let Inst{23-21} = 0b001; 2470 let Inst{20-16} = Rm; 2471 let Inst{15} = ext{5}; 2472 let Inst{12-10} = ext{2-0}; 2473 let Inst{9-5} = Rn; 2474 let Inst{4-0} = Rd; 2475 2476 let DecoderMethod = "DecodeAddSubERegInstruction"; 2477} 2478 2479// Aliases for register+register add/subtract. 2480class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2481 RegisterClass src1Regtype, RegisterClass src2Regtype, 2482 int shiftExt> 2483 : InstAlias<asm#"\t$dst, $src1, $src2", 2484 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2485 shiftExt)>; 2486 2487multiclass AddSub<bit isSub, string mnemonic, string alias, 2488 SDPatternOperator OpNode = null_frag> { 2489 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2490 // Add/Subtract immediate 2491 // Increase the weight of the immediate variant to try to match it before 2492 // the extended register variant. 2493 // We used to match the register variant before the immediate when the 2494 // register argument could be implicitly zero-extended. 2495 let AddedComplexity = 6 in 2496 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2497 mnemonic, OpNode> { 2498 let Inst{31} = 0; 2499 } 2500 let AddedComplexity = 6 in 2501 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2502 mnemonic, OpNode> { 2503 let Inst{31} = 1; 2504 } 2505 2506 // Add/Subtract register - Only used for CodeGen 2507 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2508 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2509 2510 // Add/Subtract shifted register 2511 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2512 OpNode> { 2513 let Inst{31} = 0; 2514 } 2515 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2516 OpNode> { 2517 let Inst{31} = 1; 2518 } 2519 } 2520 2521 // Add/Subtract extended register 2522 let AddedComplexity = 1, hasSideEffects = 0 in { 2523 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2524 arith_extended_reg32_i32, mnemonic, OpNode> { 2525 let Inst{31} = 0; 2526 } 2527 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2528 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2529 let Inst{31} = 1; 2530 } 2531 } 2532 2533 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2534 arith_extendlsl64, mnemonic> { 2535 // UXTX and SXTX only. 2536 let Inst{14-13} = 0b11; 2537 let Inst{31} = 1; 2538 } 2539 2540 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2541 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2542 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2543 addsub_shifted_imm32_neg:$imm), 0>; 2544 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2545 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2546 addsub_shifted_imm64_neg:$imm), 0>; 2547 2548 // Register/register aliases with no shift when SP is not used. 2549 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2550 GPR32, GPR32, GPR32, 0>; 2551 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2552 GPR64, GPR64, GPR64, 0>; 2553 2554 // Register/register aliases with no shift when either the destination or 2555 // first source register is SP. 2556 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2557 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2558 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2559 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2560 def : AddSubRegAlias<mnemonic, 2561 !cast<Instruction>(NAME#"Xrx64"), 2562 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2563 def : AddSubRegAlias<mnemonic, 2564 !cast<Instruction>(NAME#"Xrx64"), 2565 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2566} 2567 2568multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2569 string alias, string cmpAlias> { 2570 let isCompare = 1, Defs = [NZCV] in { 2571 // Add/Subtract immediate 2572 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2573 mnemonic, OpNode> { 2574 let Inst{31} = 0; 2575 } 2576 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2577 mnemonic, OpNode> { 2578 let Inst{31} = 1; 2579 } 2580 2581 // Add/Subtract register 2582 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2583 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2584 2585 // Add/Subtract shifted register 2586 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2587 OpNode> { 2588 let Inst{31} = 0; 2589 } 2590 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2591 OpNode> { 2592 let Inst{31} = 1; 2593 } 2594 2595 // Add/Subtract extended register 2596 let AddedComplexity = 1 in { 2597 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2598 arith_extended_reg32_i32, mnemonic, OpNode> { 2599 let Inst{31} = 0; 2600 } 2601 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2602 arith_extended_reg32_i64, mnemonic, OpNode> { 2603 let Inst{31} = 1; 2604 } 2605 } 2606 2607 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2608 arith_extendlsl64, mnemonic> { 2609 // UXTX and SXTX only. 2610 let Inst{14-13} = 0b11; 2611 let Inst{31} = 1; 2612 } 2613 } // Defs = [NZCV] 2614 2615 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2616 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2617 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2618 addsub_shifted_imm32_neg:$imm), 0>; 2619 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2620 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2621 addsub_shifted_imm64_neg:$imm), 0>; 2622 2623 // Compare aliases 2624 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2625 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2626 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2627 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2628 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2629 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2630 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2631 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2632 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2633 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2634 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2635 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2636 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2637 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2638 2639 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2640 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2641 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2642 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2643 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2644 2645 // Compare shorthands 2646 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2647 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2648 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2649 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2650 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2651 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2652 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2653 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2654 2655 // Register/register aliases with no shift when SP is not used. 2656 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2657 GPR32, GPR32, GPR32, 0>; 2658 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2659 GPR64, GPR64, GPR64, 0>; 2660 2661 // Register/register aliases with no shift when the first source register 2662 // is SP. 2663 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2664 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2665 def : AddSubRegAlias<mnemonic, 2666 !cast<Instruction>(NAME#"Xrx64"), 2667 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2668} 2669 2670class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2671 : BaseAddSubImm< 2672 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2673 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2674 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2675 bits<6> imm6; 2676 bits<4> imm4; 2677 let Inst{31} = 1; 2678 let Inst{23-22} = 0b10; 2679 let Inst{21-16} = imm6; 2680 let Inst{15-14} = 0b00; 2681 let Inst{13-10} = imm4; 2682 let Unpredictable{15-14} = 0b11; 2683} 2684 2685class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2686 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2687 let Inst{31} = 1; 2688 let Inst{29} = setsFlags; 2689} 2690 2691//--- 2692// Extract 2693//--- 2694def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2695 SDTCisPtrTy<3>]>; 2696def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2697 2698class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2699 list<dag> patterns> 2700 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2701 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2702 Sched<[WriteExtr, ReadExtrHi]> { 2703 bits<5> Rd; 2704 bits<5> Rn; 2705 bits<5> Rm; 2706 bits<6> imm; 2707 2708 let Inst{30-23} = 0b00100111; 2709 let Inst{21} = 0; 2710 let Inst{20-16} = Rm; 2711 let Inst{15-10} = imm; 2712 let Inst{9-5} = Rn; 2713 let Inst{4-0} = Rd; 2714} 2715 2716multiclass ExtractImm<string asm> { 2717 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2718 [(set GPR32:$Rd, 2719 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2720 let Inst{31} = 0; 2721 let Inst{22} = 0; 2722 // imm<5> must be zero. 2723 let imm{5} = 0; 2724 } 2725 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2726 [(set GPR64:$Rd, 2727 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2728 2729 let Inst{31} = 1; 2730 let Inst{22} = 1; 2731 } 2732} 2733 2734//--- 2735// Bitfield 2736//--- 2737 2738let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2739class BaseBitfieldImm<bits<2> opc, 2740 RegisterClass regtype, Operand imm_type, string asm> 2741 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2742 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2743 Sched<[WriteIS, ReadI]> { 2744 bits<5> Rd; 2745 bits<5> Rn; 2746 bits<6> immr; 2747 bits<6> imms; 2748 2749 let Inst{30-29} = opc; 2750 let Inst{28-23} = 0b100110; 2751 let Inst{21-16} = immr; 2752 let Inst{15-10} = imms; 2753 let Inst{9-5} = Rn; 2754 let Inst{4-0} = Rd; 2755} 2756 2757multiclass BitfieldImm<bits<2> opc, string asm> { 2758 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2759 let Inst{31} = 0; 2760 let Inst{22} = 0; 2761 // imms<5> and immr<5> must be zero, else ReservedValue(). 2762 let Inst{21} = 0; 2763 let Inst{15} = 0; 2764 } 2765 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2766 let Inst{31} = 1; 2767 let Inst{22} = 1; 2768 } 2769} 2770 2771let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2772class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2773 RegisterClass regtype, Operand imm_type, string asm> 2774 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2775 imm_type:$imms), 2776 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2777 Sched<[WriteIS, ReadI]> { 2778 bits<5> Rd; 2779 bits<5> Rn; 2780 bits<6> immr; 2781 bits<6> imms; 2782 2783 let Inst{30-29} = opc; 2784 let Inst{28-23} = 0b100110; 2785 let Inst{21-16} = immr; 2786 let Inst{15-10} = imms; 2787 let Inst{9-5} = Rn; 2788 let Inst{4-0} = Rd; 2789} 2790 2791multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2792 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2793 let Inst{31} = 0; 2794 let Inst{22} = 0; 2795 // imms<5> and immr<5> must be zero, else ReservedValue(). 2796 let Inst{21} = 0; 2797 let Inst{15} = 0; 2798 } 2799 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2800 let Inst{31} = 1; 2801 let Inst{22} = 1; 2802 } 2803} 2804 2805//--- 2806// Logical 2807//--- 2808 2809// Logical (immediate) 2810class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2811 RegisterClass sregtype, Operand imm_type, string asm, 2812 list<dag> pattern> 2813 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2814 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2815 Sched<[WriteI, ReadI]> { 2816 bits<5> Rd; 2817 bits<5> Rn; 2818 bits<13> imm; 2819 let Inst{30-29} = opc; 2820 let Inst{28-23} = 0b100100; 2821 let Inst{22} = imm{12}; 2822 let Inst{21-16} = imm{11-6}; 2823 let Inst{15-10} = imm{5-0}; 2824 let Inst{9-5} = Rn; 2825 let Inst{4-0} = Rd; 2826 2827 let DecoderMethod = "DecodeLogicalImmInstruction"; 2828} 2829 2830// Logical (shifted register) 2831class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2832 logical_shifted_reg shifted_regtype, string asm, 2833 list<dag> pattern> 2834 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2835 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2836 Sched<[WriteISReg, ReadI, ReadISReg]> { 2837 // The operands are in order to match the 'addr' MI operands, so we 2838 // don't need an encoder method and by-name matching. Just use the default 2839 // in-order handling. Since we're using by-order, make sure the names 2840 // do not match. 2841 bits<5> dst; 2842 bits<5> src1; 2843 bits<5> src2; 2844 bits<8> shift; 2845 let Inst{30-29} = opc; 2846 let Inst{28-24} = 0b01010; 2847 let Inst{23-22} = shift{7-6}; 2848 let Inst{21} = N; 2849 let Inst{20-16} = src2; 2850 let Inst{15-10} = shift{5-0}; 2851 let Inst{9-5} = src1; 2852 let Inst{4-0} = dst; 2853 2854 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2855} 2856 2857// Aliases for register+register logical instructions. 2858class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2859 : InstAlias<asm#"\t$dst, $src1, $src2", 2860 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2861 2862multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2863 string Alias> { 2864 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2865 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2866 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2867 logical_imm32:$imm))]> { 2868 let Inst{31} = 0; 2869 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2870 } 2871 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2872 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2873 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2874 logical_imm64:$imm))]> { 2875 let Inst{31} = 1; 2876 } 2877 2878 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2879 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2880 logical_imm32_not:$imm), 0>; 2881 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2882 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2883 logical_imm64_not:$imm), 0>; 2884} 2885 2886multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2887 string Alias> { 2888 let isCompare = 1, Defs = [NZCV] in { 2889 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2890 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2891 let Inst{31} = 0; 2892 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2893 } 2894 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2895 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2896 let Inst{31} = 1; 2897 } 2898 } // end Defs = [NZCV] 2899 2900 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2901 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2902 logical_imm32_not:$imm), 0>; 2903 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2904 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2905 logical_imm64_not:$imm), 0>; 2906} 2907 2908class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2909 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2910 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2911 Sched<[WriteI, ReadI, ReadI]>; 2912 2913// Split from LogicalImm as not all instructions have both. 2914multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2915 SDPatternOperator OpNode> { 2916 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2917 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2918 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2919 } 2920 2921 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2922 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2923 logical_shifted_reg32:$Rm))]> { 2924 let Inst{31} = 0; 2925 } 2926 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2927 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2928 logical_shifted_reg64:$Rm))]> { 2929 let Inst{31} = 1; 2930 } 2931 2932 def : LogicalRegAlias<mnemonic, 2933 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2934 def : LogicalRegAlias<mnemonic, 2935 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2936} 2937 2938// Split from LogicalReg to allow setting NZCV Defs 2939multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2940 SDPatternOperator OpNode = null_frag> { 2941 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2942 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2943 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2944 2945 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2946 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2947 let Inst{31} = 0; 2948 } 2949 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2950 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2951 let Inst{31} = 1; 2952 } 2953 } // Defs = [NZCV] 2954 2955 def : LogicalRegAlias<mnemonic, 2956 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2957 def : LogicalRegAlias<mnemonic, 2958 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2959} 2960 2961//--- 2962// Conditionally set flags 2963//--- 2964 2965let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2966class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2967 string mnemonic, SDNode OpNode> 2968 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2969 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2970 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2971 (i32 imm:$cond), NZCV))]>, 2972 Sched<[WriteI, ReadI]> { 2973 let Uses = [NZCV]; 2974 let Defs = [NZCV]; 2975 2976 bits<5> Rn; 2977 bits<5> imm; 2978 bits<4> nzcv; 2979 bits<4> cond; 2980 2981 let Inst{30} = op; 2982 let Inst{29-21} = 0b111010010; 2983 let Inst{20-16} = imm; 2984 let Inst{15-12} = cond; 2985 let Inst{11-10} = 0b10; 2986 let Inst{9-5} = Rn; 2987 let Inst{4} = 0b0; 2988 let Inst{3-0} = nzcv; 2989} 2990 2991let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2992class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2993 SDNode OpNode> 2994 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2995 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2996 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2997 (i32 imm:$cond), NZCV))]>, 2998 Sched<[WriteI, ReadI, ReadI]> { 2999 let Uses = [NZCV]; 3000 let Defs = [NZCV]; 3001 3002 bits<5> Rn; 3003 bits<5> Rm; 3004 bits<4> nzcv; 3005 bits<4> cond; 3006 3007 let Inst{30} = op; 3008 let Inst{29-21} = 0b111010010; 3009 let Inst{20-16} = Rm; 3010 let Inst{15-12} = cond; 3011 let Inst{11-10} = 0b00; 3012 let Inst{9-5} = Rn; 3013 let Inst{4} = 0b0; 3014 let Inst{3-0} = nzcv; 3015} 3016 3017multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3018 // immediate operand variants 3019 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3020 let Inst{31} = 0; 3021 } 3022 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3023 let Inst{31} = 1; 3024 } 3025 // register operand variants 3026 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3027 let Inst{31} = 0; 3028 } 3029 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3030 let Inst{31} = 1; 3031 } 3032} 3033 3034//--- 3035// Conditional select 3036//--- 3037 3038class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3039 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3040 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3041 [(set regtype:$Rd, 3042 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3043 Sched<[WriteI, ReadI, ReadI]> { 3044 let Uses = [NZCV]; 3045 3046 bits<5> Rd; 3047 bits<5> Rn; 3048 bits<5> Rm; 3049 bits<4> cond; 3050 3051 let Inst{30} = op; 3052 let Inst{29-21} = 0b011010100; 3053 let Inst{20-16} = Rm; 3054 let Inst{15-12} = cond; 3055 let Inst{11-10} = op2; 3056 let Inst{9-5} = Rn; 3057 let Inst{4-0} = Rd; 3058} 3059 3060multiclass CondSelect<bit op, bits<2> op2, string asm> { 3061 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3062 let Inst{31} = 0; 3063 } 3064 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3065 let Inst{31} = 1; 3066 } 3067} 3068 3069class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3070 PatFrag frag> 3071 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3072 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3073 [(set regtype:$Rd, 3074 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3075 (i32 imm:$cond), NZCV))]>, 3076 Sched<[WriteI, ReadI, ReadI]> { 3077 let Uses = [NZCV]; 3078 3079 bits<5> Rd; 3080 bits<5> Rn; 3081 bits<5> Rm; 3082 bits<4> cond; 3083 3084 let Inst{30} = op; 3085 let Inst{29-21} = 0b011010100; 3086 let Inst{20-16} = Rm; 3087 let Inst{15-12} = cond; 3088 let Inst{11-10} = op2; 3089 let Inst{9-5} = Rn; 3090 let Inst{4-0} = Rd; 3091} 3092 3093def inv_cond_XFORM : SDNodeXForm<imm, [{ 3094 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3095 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3096 MVT::i32); 3097}]>; 3098 3099multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3100 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3101 let Inst{31} = 0; 3102 } 3103 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3104 let Inst{31} = 1; 3105 } 3106 3107 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3108 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3109 (inv_cond_XFORM imm:$cond))>; 3110 3111 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3112 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3113 (inv_cond_XFORM imm:$cond))>; 3114} 3115 3116//--- 3117// Special Mask Value 3118//--- 3119def maski8_or_more : Operand<i32>, 3120 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3121} 3122def maski16_or_more : Operand<i32>, 3123 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3124} 3125 3126 3127//--- 3128// Load/store 3129//--- 3130 3131// (unsigned immediate) 3132// Indexed for 8-bit registers. offset is in range [0,4095]. 3133def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 3134def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 3135def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 3136def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 3137def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 3138 3139// (unsigned immediate) 3140// Indexed for 8-bit registers. offset is in range [0,63]. 3141def am_indexed8_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3142def am_indexed16_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3143def am_indexed32_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3144def am_indexed64_6b : ComplexPattern<i64, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3145 3146def gi_am_indexed8 : 3147 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3148 GIComplexPatternEquiv<am_indexed8>; 3149def gi_am_indexed16 : 3150 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3151 GIComplexPatternEquiv<am_indexed16>; 3152def gi_am_indexed32 : 3153 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3154 GIComplexPatternEquiv<am_indexed32>; 3155def gi_am_indexed64 : 3156 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3157 GIComplexPatternEquiv<am_indexed64>; 3158def gi_am_indexed128 : 3159 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3160 GIComplexPatternEquiv<am_indexed128>; 3161 3162class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3163 let Name = "UImm12Offset" # Scale; 3164 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3165 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3166 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3167} 3168 3169def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3170def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3171def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3172def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3173def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3174 3175class uimm12_scaled<int Scale> : Operand<i64> { 3176 let ParserMatchClass 3177 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3178 let EncoderMethod 3179 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3180 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3181} 3182 3183def uimm12s1 : uimm12_scaled<1>; 3184def uimm12s2 : uimm12_scaled<2>; 3185def uimm12s4 : uimm12_scaled<4>; 3186def uimm12s8 : uimm12_scaled<8>; 3187def uimm12s16 : uimm12_scaled<16>; 3188 3189class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3190 string asm, list<dag> pattern> 3191 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3192 bits<5> Rt; 3193 3194 bits<5> Rn; 3195 bits<12> offset; 3196 3197 let Inst{31-30} = sz; 3198 let Inst{29-27} = 0b111; 3199 let Inst{26} = V; 3200 let Inst{25-24} = 0b01; 3201 let Inst{23-22} = opc; 3202 let Inst{21-10} = offset; 3203 let Inst{9-5} = Rn; 3204 let Inst{4-0} = Rt; 3205 3206 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3207} 3208 3209multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3210 Operand indextype, string asm, list<dag> pattern> { 3211 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3212 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3213 (ins GPR64sp:$Rn, indextype:$offset), 3214 asm, pattern>, 3215 Sched<[WriteLD]>; 3216 3217 def : InstAlias<asm # "\t$Rt, [$Rn]", 3218 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3219} 3220 3221multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3222 Operand indextype, string asm, list<dag> pattern> { 3223 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3224 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3225 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3226 asm, pattern>, 3227 Sched<[WriteST]>; 3228 3229 def : InstAlias<asm # "\t$Rt, [$Rn]", 3230 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3231} 3232 3233// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3234// substitute zero-registers automatically. 3235// 3236// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3237// into StoreUI. 3238multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3239 Operand indextype, string asm, list<dag> pattern> { 3240 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3241 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3242 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3243 asm, pattern>, 3244 Sched<[WriteST]>; 3245 3246 def : InstAlias<asm # "\t$Rt, [$Rn]", 3247 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3248} 3249 3250def PrefetchOperand : AsmOperandClass { 3251 let Name = "Prefetch"; 3252 let ParserMethod = "tryParsePrefetch"; 3253} 3254def prfop : Operand<i32> { 3255 let PrintMethod = "printPrefetchOp"; 3256 let ParserMatchClass = PrefetchOperand; 3257} 3258 3259let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3260class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3261 : BaseLoadStoreUI<sz, V, opc, 3262 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3263 asm, pat>, 3264 Sched<[WriteLD]>; 3265 3266//--- 3267// Load literal 3268//--- 3269 3270// Load literal address: 19-bit immediate. The low two bits of the target 3271// offset are implied zero and so are not part of the immediate. 3272def am_ldrlit : Operand<iPTR> { 3273 let EncoderMethod = "getLoadLiteralOpValue"; 3274 let DecoderMethod = "DecodePCRelLabel19"; 3275 let PrintMethod = "printAlignedLabel"; 3276 let ParserMatchClass = PCRelLabel19Operand; 3277 let OperandType = "OPERAND_PCREL"; 3278} 3279 3280let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3281class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3282 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3283 asm, "\t$Rt, $label", "", pat>, 3284 Sched<[WriteLD]> { 3285 bits<5> Rt; 3286 bits<19> label; 3287 let Inst{31-30} = opc; 3288 let Inst{29-27} = 0b011; 3289 let Inst{26} = V; 3290 let Inst{25-24} = 0b00; 3291 let Inst{23-5} = label; 3292 let Inst{4-0} = Rt; 3293} 3294 3295let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3296class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3297 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3298 asm, "\t$Rt, $label", "", pat>, 3299 Sched<[WriteLD]> { 3300 bits<5> Rt; 3301 bits<19> label; 3302 let Inst{31-30} = opc; 3303 let Inst{29-27} = 0b011; 3304 let Inst{26} = V; 3305 let Inst{25-24} = 0b00; 3306 let Inst{23-5} = label; 3307 let Inst{4-0} = Rt; 3308} 3309 3310//--- 3311// Load/store register offset 3312//--- 3313 3314def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 3315def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 3316def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 3317def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 3318def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 3319 3320def gi_ro_Xindexed8 : 3321 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3322 GIComplexPatternEquiv<ro_Xindexed8>; 3323def gi_ro_Xindexed16 : 3324 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3325 GIComplexPatternEquiv<ro_Xindexed16>; 3326def gi_ro_Xindexed32 : 3327 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3328 GIComplexPatternEquiv<ro_Xindexed32>; 3329def gi_ro_Xindexed64 : 3330 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3331 GIComplexPatternEquiv<ro_Xindexed64>; 3332def gi_ro_Xindexed128 : 3333 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3334 GIComplexPatternEquiv<ro_Xindexed128>; 3335 3336def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 3337def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 3338def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 3339def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 3340def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 3341 3342def gi_ro_Windexed8 : 3343 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3344 GIComplexPatternEquiv<ro_Windexed8>; 3345def gi_ro_Windexed16 : 3346 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3347 GIComplexPatternEquiv<ro_Windexed16>; 3348def gi_ro_Windexed32 : 3349 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3350 GIComplexPatternEquiv<ro_Windexed32>; 3351def gi_ro_Windexed64 : 3352 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3353 GIComplexPatternEquiv<ro_Windexed64>; 3354def gi_ro_Windexed128 : 3355 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3356 GIComplexPatternEquiv<ro_Windexed128>; 3357 3358class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3359 let Name = "Mem" # Reg # "Extend" # Width; 3360 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3361 let RenderMethod = "addMemExtendOperands"; 3362 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3363} 3364 3365def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3366 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3367 // the trivial shift. 3368 let RenderMethod = "addMemExtend8Operands"; 3369} 3370def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3371def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3372def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3373def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3374 3375def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3376 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3377 // the trivial shift. 3378 let RenderMethod = "addMemExtend8Operands"; 3379} 3380def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3381def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3382def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3383def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3384 3385class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3386 : Operand<i32> { 3387 let ParserMatchClass = ParserClass; 3388 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3389 let DecoderMethod = "DecodeMemExtend"; 3390 let EncoderMethod = "getMemExtendOpValue"; 3391 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3392} 3393 3394def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3395def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3396def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3397def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3398def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3399 3400def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3401def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3402def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3403def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3404def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3405 3406class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3407 Operand wextend, Operand xextend> { 3408 // CodeGen-level pattern covering the entire addressing mode. 3409 ComplexPattern Wpat = windex; 3410 ComplexPattern Xpat = xindex; 3411 3412 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3413 Operand Wext = wextend; 3414 Operand Xext = xextend; 3415} 3416 3417def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3418def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3419def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3420def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3421def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3422 ro_Xextend128>; 3423 3424class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3425 string asm, dag ins, dag outs, list<dag> pat> 3426 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3427 bits<5> Rt; 3428 bits<5> Rn; 3429 bits<5> Rm; 3430 bits<2> extend; 3431 let Inst{31-30} = sz; 3432 let Inst{29-27} = 0b111; 3433 let Inst{26} = V; 3434 let Inst{25-24} = 0b00; 3435 let Inst{23-22} = opc; 3436 let Inst{21} = 1; 3437 let Inst{20-16} = Rm; 3438 let Inst{15} = extend{1}; // sign extend Rm? 3439 let Inst{14} = 1; 3440 let Inst{12} = extend{0}; // do shift? 3441 let Inst{11-10} = 0b10; 3442 let Inst{9-5} = Rn; 3443 let Inst{4-0} = Rt; 3444} 3445 3446class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3447 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3448 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3449 3450multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3451 string asm, ValueType Ty, SDPatternOperator loadop> { 3452 let AddedComplexity = 10 in 3453 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 3454 (outs regtype:$Rt), 3455 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3456 [(set (Ty regtype:$Rt), 3457 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3458 ro_Wextend8:$extend)))]>, 3459 Sched<[WriteLDIdx, ReadAdrBase]> { 3460 let Inst{13} = 0b0; 3461 } 3462 3463 let AddedComplexity = 10 in 3464 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 3465 (outs regtype:$Rt), 3466 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3467 [(set (Ty regtype:$Rt), 3468 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3469 ro_Xextend8:$extend)))]>, 3470 Sched<[WriteLDIdx, ReadAdrBase]> { 3471 let Inst{13} = 0b1; 3472 } 3473 3474 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3475} 3476 3477multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3478 string asm, ValueType Ty, SDPatternOperator storeop> { 3479 let AddedComplexity = 10 in 3480 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3481 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3482 [(storeop (Ty regtype:$Rt), 3483 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3484 ro_Wextend8:$extend))]>, 3485 Sched<[WriteSTIdx, ReadAdrBase]> { 3486 let Inst{13} = 0b0; 3487 } 3488 3489 let AddedComplexity = 10 in 3490 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3491 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3492 [(storeop (Ty regtype:$Rt), 3493 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3494 ro_Xextend8:$extend))]>, 3495 Sched<[WriteSTIdx, ReadAdrBase]> { 3496 let Inst{13} = 0b1; 3497 } 3498 3499 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3500} 3501 3502class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3503 string asm, dag ins, dag outs, list<dag> pat> 3504 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3505 bits<5> Rt; 3506 bits<5> Rn; 3507 bits<5> Rm; 3508 bits<2> extend; 3509 let Inst{31-30} = sz; 3510 let Inst{29-27} = 0b111; 3511 let Inst{26} = V; 3512 let Inst{25-24} = 0b00; 3513 let Inst{23-22} = opc; 3514 let Inst{21} = 1; 3515 let Inst{20-16} = Rm; 3516 let Inst{15} = extend{1}; // sign extend Rm? 3517 let Inst{14} = 1; 3518 let Inst{12} = extend{0}; // do shift? 3519 let Inst{11-10} = 0b10; 3520 let Inst{9-5} = Rn; 3521 let Inst{4-0} = Rt; 3522} 3523 3524multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3525 string asm, ValueType Ty, SDPatternOperator loadop> { 3526 let AddedComplexity = 10 in 3527 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3528 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3529 [(set (Ty regtype:$Rt), 3530 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3531 ro_Wextend16:$extend)))]>, 3532 Sched<[WriteLDIdx, ReadAdrBase]> { 3533 let Inst{13} = 0b0; 3534 } 3535 3536 let AddedComplexity = 10 in 3537 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3538 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3539 [(set (Ty regtype:$Rt), 3540 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3541 ro_Xextend16:$extend)))]>, 3542 Sched<[WriteLDIdx, ReadAdrBase]> { 3543 let Inst{13} = 0b1; 3544 } 3545 3546 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3547} 3548 3549multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3550 string asm, ValueType Ty, SDPatternOperator storeop> { 3551 let AddedComplexity = 10 in 3552 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3553 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3554 [(storeop (Ty regtype:$Rt), 3555 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3556 ro_Wextend16:$extend))]>, 3557 Sched<[WriteSTIdx, ReadAdrBase]> { 3558 let Inst{13} = 0b0; 3559 } 3560 3561 let AddedComplexity = 10 in 3562 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3563 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3564 [(storeop (Ty regtype:$Rt), 3565 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3566 ro_Xextend16:$extend))]>, 3567 Sched<[WriteSTIdx, ReadAdrBase]> { 3568 let Inst{13} = 0b1; 3569 } 3570 3571 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3572} 3573 3574class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3575 string asm, dag ins, dag outs, list<dag> pat> 3576 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3577 bits<5> Rt; 3578 bits<5> Rn; 3579 bits<5> Rm; 3580 bits<2> extend; 3581 let Inst{31-30} = sz; 3582 let Inst{29-27} = 0b111; 3583 let Inst{26} = V; 3584 let Inst{25-24} = 0b00; 3585 let Inst{23-22} = opc; 3586 let Inst{21} = 1; 3587 let Inst{20-16} = Rm; 3588 let Inst{15} = extend{1}; // sign extend Rm? 3589 let Inst{14} = 1; 3590 let Inst{12} = extend{0}; // do shift? 3591 let Inst{11-10} = 0b10; 3592 let Inst{9-5} = Rn; 3593 let Inst{4-0} = Rt; 3594} 3595 3596multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3597 string asm, ValueType Ty, SDPatternOperator loadop> { 3598 let AddedComplexity = 10 in 3599 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3600 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3601 [(set (Ty regtype:$Rt), 3602 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3603 ro_Wextend32:$extend)))]>, 3604 Sched<[WriteLDIdx, ReadAdrBase]> { 3605 let Inst{13} = 0b0; 3606 } 3607 3608 let AddedComplexity = 10 in 3609 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3610 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3611 [(set (Ty regtype:$Rt), 3612 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3613 ro_Xextend32:$extend)))]>, 3614 Sched<[WriteLDIdx, ReadAdrBase]> { 3615 let Inst{13} = 0b1; 3616 } 3617 3618 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3619} 3620 3621multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3622 string asm, ValueType Ty, SDPatternOperator storeop> { 3623 let AddedComplexity = 10 in 3624 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3625 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3626 [(storeop (Ty regtype:$Rt), 3627 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3628 ro_Wextend32:$extend))]>, 3629 Sched<[WriteSTIdx, ReadAdrBase]> { 3630 let Inst{13} = 0b0; 3631 } 3632 3633 let AddedComplexity = 10 in 3634 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3635 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3636 [(storeop (Ty regtype:$Rt), 3637 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3638 ro_Xextend32:$extend))]>, 3639 Sched<[WriteSTIdx, ReadAdrBase]> { 3640 let Inst{13} = 0b1; 3641 } 3642 3643 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3644} 3645 3646class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3647 string asm, dag ins, dag outs, list<dag> pat> 3648 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3649 bits<5> Rt; 3650 bits<5> Rn; 3651 bits<5> Rm; 3652 bits<2> extend; 3653 let Inst{31-30} = sz; 3654 let Inst{29-27} = 0b111; 3655 let Inst{26} = V; 3656 let Inst{25-24} = 0b00; 3657 let Inst{23-22} = opc; 3658 let Inst{21} = 1; 3659 let Inst{20-16} = Rm; 3660 let Inst{15} = extend{1}; // sign extend Rm? 3661 let Inst{14} = 1; 3662 let Inst{12} = extend{0}; // do shift? 3663 let Inst{11-10} = 0b10; 3664 let Inst{9-5} = Rn; 3665 let Inst{4-0} = Rt; 3666} 3667 3668multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3669 string asm, ValueType Ty, SDPatternOperator loadop> { 3670 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3671 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3672 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3673 [(set (Ty regtype:$Rt), 3674 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3675 ro_Wextend64:$extend)))]>, 3676 Sched<[WriteLDIdx, ReadAdrBase]> { 3677 let Inst{13} = 0b0; 3678 } 3679 3680 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3681 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3682 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3683 [(set (Ty regtype:$Rt), 3684 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3685 ro_Xextend64:$extend)))]>, 3686 Sched<[WriteLDIdx, ReadAdrBase]> { 3687 let Inst{13} = 0b1; 3688 } 3689 3690 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3691} 3692 3693multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3694 string asm, ValueType Ty, SDPatternOperator storeop> { 3695 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3696 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3697 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3698 [(storeop (Ty regtype:$Rt), 3699 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3700 ro_Wextend64:$extend))]>, 3701 Sched<[WriteSTIdx, ReadAdrBase]> { 3702 let Inst{13} = 0b0; 3703 } 3704 3705 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3706 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3707 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3708 [(storeop (Ty regtype:$Rt), 3709 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3710 ro_Xextend64:$extend))]>, 3711 Sched<[WriteSTIdx, ReadAdrBase]> { 3712 let Inst{13} = 0b1; 3713 } 3714 3715 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3716} 3717 3718class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3719 string asm, dag ins, dag outs, list<dag> pat> 3720 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3721 bits<5> Rt; 3722 bits<5> Rn; 3723 bits<5> Rm; 3724 bits<2> extend; 3725 let Inst{31-30} = sz; 3726 let Inst{29-27} = 0b111; 3727 let Inst{26} = V; 3728 let Inst{25-24} = 0b00; 3729 let Inst{23-22} = opc; 3730 let Inst{21} = 1; 3731 let Inst{20-16} = Rm; 3732 let Inst{15} = extend{1}; // sign extend Rm? 3733 let Inst{14} = 1; 3734 let Inst{12} = extend{0}; // do shift? 3735 let Inst{11-10} = 0b10; 3736 let Inst{9-5} = Rn; 3737 let Inst{4-0} = Rt; 3738} 3739 3740multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3741 string asm, ValueType Ty, SDPatternOperator loadop> { 3742 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3743 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3744 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3745 [(set (Ty regtype:$Rt), 3746 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3747 ro_Wextend128:$extend)))]>, 3748 Sched<[WriteLDIdx, ReadAdrBase]> { 3749 let Inst{13} = 0b0; 3750 } 3751 3752 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3753 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3754 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3755 [(set (Ty regtype:$Rt), 3756 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3757 ro_Xextend128:$extend)))]>, 3758 Sched<[WriteLDIdx, ReadAdrBase]> { 3759 let Inst{13} = 0b1; 3760 } 3761 3762 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3763} 3764 3765multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3766 string asm, ValueType Ty, SDPatternOperator storeop> { 3767 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3768 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3769 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3770 []>, 3771 Sched<[WriteSTIdx, ReadAdrBase]> { 3772 let Inst{13} = 0b0; 3773 } 3774 3775 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3776 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3777 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3778 []>, 3779 Sched<[WriteSTIdx, ReadAdrBase]> { 3780 let Inst{13} = 0b1; 3781 } 3782 3783 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3784} 3785 3786let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3787class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3788 string asm, list<dag> pat> 3789 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3790 Sched<[WriteLD]> { 3791 bits<5> Rt; 3792 bits<5> Rn; 3793 bits<5> Rm; 3794 bits<2> extend; 3795 let Inst{31-30} = sz; 3796 let Inst{29-27} = 0b111; 3797 let Inst{26} = V; 3798 let Inst{25-24} = 0b00; 3799 let Inst{23-22} = opc; 3800 let Inst{21} = 1; 3801 let Inst{20-16} = Rm; 3802 let Inst{15} = extend{1}; // sign extend Rm? 3803 let Inst{14} = 1; 3804 let Inst{12} = extend{0}; // do shift? 3805 let Inst{11-10} = 0b10; 3806 let Inst{9-5} = Rn; 3807 let Inst{4-0} = Rt; 3808} 3809 3810multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3811 def roW : BasePrefetchRO<sz, V, opc, (outs), 3812 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3813 asm, [(AArch64Prefetch imm:$Rt, 3814 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3815 ro_Wextend64:$extend))]> { 3816 let Inst{13} = 0b0; 3817 } 3818 3819 def roX : BasePrefetchRO<sz, V, opc, (outs), 3820 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3821 asm, [(AArch64Prefetch imm:$Rt, 3822 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3823 ro_Xextend64:$extend))]> { 3824 let Inst{13} = 0b1; 3825 } 3826 3827 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3828 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3829 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3830} 3831 3832//--- 3833// Load/store unscaled immediate 3834//--- 3835 3836def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 3837def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 3838def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 3839def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 3840def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3841 3842def gi_am_unscaled8 : 3843 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3844 GIComplexPatternEquiv<am_unscaled8>; 3845def gi_am_unscaled16 : 3846 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3847 GIComplexPatternEquiv<am_unscaled16>; 3848def gi_am_unscaled32 : 3849 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3850 GIComplexPatternEquiv<am_unscaled32>; 3851def gi_am_unscaled64 : 3852 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3853 GIComplexPatternEquiv<am_unscaled64>; 3854def gi_am_unscaled128 : 3855 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3856 GIComplexPatternEquiv<am_unscaled128>; 3857 3858 3859class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3860 string asm, list<dag> pattern> 3861 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3862 bits<5> Rt; 3863 bits<5> Rn; 3864 bits<9> offset; 3865 let Inst{31-30} = sz; 3866 let Inst{29-27} = 0b111; 3867 let Inst{26} = V; 3868 let Inst{25-24} = 0b00; 3869 let Inst{23-22} = opc; 3870 let Inst{21} = 0; 3871 let Inst{20-12} = offset; 3872 let Inst{11-10} = 0b00; 3873 let Inst{9-5} = Rn; 3874 let Inst{4-0} = Rt; 3875 3876 let DecoderMethod = "DecodeSignedLdStInstruction"; 3877} 3878 3879// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3880multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3881 DAGOperand regtype > { 3882 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3883 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3884 Sched<[WriteST]> { 3885 let Inst{29} = 0; 3886 let Inst{24} = 1; 3887 } 3888 def : InstAlias<asm # "\t$Rt, [$Rn]", 3889 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3890} 3891 3892multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3893 DAGOperand regtype > { 3894 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3895 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3896 asm, []>, 3897 Sched<[WriteST]> { 3898 let Inst{29} = 0; 3899 let Inst{24} = 1; 3900 } 3901 def : InstAlias<asm # "\t$Rt, [$Rn]", 3902 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3903} 3904 3905multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3906 string asm, list<dag> pattern> { 3907 let AddedComplexity = 1 in // try this before LoadUI 3908 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3909 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3910 Sched<[WriteLD]>; 3911 3912 def : InstAlias<asm # "\t$Rt, [$Rn]", 3913 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3914} 3915 3916multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3917 string asm, list<dag> pattern> { 3918 let AddedComplexity = 1 in // try this before StoreUI 3919 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3920 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3921 asm, pattern>, 3922 Sched<[WriteST]>; 3923 3924 def : InstAlias<asm # "\t$Rt, [$Rn]", 3925 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3926} 3927 3928multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3929 list<dag> pat> { 3930 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3931 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3932 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3933 asm, pat>, 3934 Sched<[WriteLD]>; 3935 3936 def : InstAlias<asm # "\t$Rt, [$Rn]", 3937 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3938} 3939 3940//--- 3941// Load/store unscaled immediate, unprivileged 3942//--- 3943 3944class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3945 dag oops, dag iops, string asm> 3946 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3947 bits<5> Rt; 3948 bits<5> Rn; 3949 bits<9> offset; 3950 let Inst{31-30} = sz; 3951 let Inst{29-27} = 0b111; 3952 let Inst{26} = V; 3953 let Inst{25-24} = 0b00; 3954 let Inst{23-22} = opc; 3955 let Inst{21} = 0; 3956 let Inst{20-12} = offset; 3957 let Inst{11-10} = 0b10; 3958 let Inst{9-5} = Rn; 3959 let Inst{4-0} = Rt; 3960 3961 let DecoderMethod = "DecodeSignedLdStInstruction"; 3962} 3963 3964multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3965 RegisterClass regtype, string asm> { 3966 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3967 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3968 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3969 Sched<[WriteLD]>; 3970 3971 def : InstAlias<asm # "\t$Rt, [$Rn]", 3972 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3973} 3974 3975multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3976 RegisterClass regtype, string asm> { 3977 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3978 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3979 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3980 asm>, 3981 Sched<[WriteST]>; 3982 3983 def : InstAlias<asm # "\t$Rt, [$Rn]", 3984 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3985} 3986 3987//--- 3988// Load/store pre-indexed 3989//--- 3990 3991class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3992 string asm, string cstr, list<dag> pat> 3993 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3994 bits<5> Rt; 3995 bits<5> Rn; 3996 bits<9> offset; 3997 let Inst{31-30} = sz; 3998 let Inst{29-27} = 0b111; 3999 let Inst{26} = V; 4000 let Inst{25-24} = 0; 4001 let Inst{23-22} = opc; 4002 let Inst{21} = 0; 4003 let Inst{20-12} = offset; 4004 let Inst{11-10} = 0b11; 4005 let Inst{9-5} = Rn; 4006 let Inst{4-0} = Rt; 4007 4008 let DecoderMethod = "DecodeSignedLdStInstruction"; 4009} 4010 4011let hasSideEffects = 0 in { 4012let mayStore = 0, mayLoad = 1 in 4013class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4014 string asm> 4015 : BaseLoadStorePreIdx<sz, V, opc, 4016 (outs GPR64sp:$wback, regtype:$Rt), 4017 (ins GPR64sp:$Rn, simm9:$offset), asm, 4018 "$Rn = $wback,@earlyclobber $wback", []>, 4019 Sched<[WriteAdr, WriteLD]>; 4020 4021let mayStore = 1, mayLoad = 0 in 4022class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4023 string asm, SDPatternOperator storeop, ValueType Ty> 4024 : BaseLoadStorePreIdx<sz, V, opc, 4025 (outs GPR64sp:$wback), 4026 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4027 asm, "$Rn = $wback,@earlyclobber $wback", 4028 [(set GPR64sp:$wback, 4029 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4030 Sched<[WriteAdr, WriteST]>; 4031} // hasSideEffects = 0 4032 4033//--- 4034// Load/store post-indexed 4035//--- 4036 4037class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4038 string asm, string cstr, list<dag> pat> 4039 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4040 bits<5> Rt; 4041 bits<5> Rn; 4042 bits<9> offset; 4043 let Inst{31-30} = sz; 4044 let Inst{29-27} = 0b111; 4045 let Inst{26} = V; 4046 let Inst{25-24} = 0b00; 4047 let Inst{23-22} = opc; 4048 let Inst{21} = 0b0; 4049 let Inst{20-12} = offset; 4050 let Inst{11-10} = 0b01; 4051 let Inst{9-5} = Rn; 4052 let Inst{4-0} = Rt; 4053 4054 let DecoderMethod = "DecodeSignedLdStInstruction"; 4055} 4056 4057let hasSideEffects = 0 in { 4058let mayStore = 0, mayLoad = 1 in 4059class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4060 string asm> 4061 : BaseLoadStorePostIdx<sz, V, opc, 4062 (outs GPR64sp:$wback, regtype:$Rt), 4063 (ins GPR64sp:$Rn, simm9:$offset), 4064 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4065 Sched<[WriteAdr, WriteLD]>; 4066 4067let mayStore = 1, mayLoad = 0 in 4068class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4069 string asm, SDPatternOperator storeop, ValueType Ty> 4070 : BaseLoadStorePostIdx<sz, V, opc, 4071 (outs GPR64sp:$wback), 4072 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4073 asm, "$Rn = $wback,@earlyclobber $wback", 4074 [(set GPR64sp:$wback, 4075 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4076 Sched<[WriteAdr, WriteST]>; 4077} // hasSideEffects = 0 4078 4079 4080//--- 4081// Load/store pair 4082//--- 4083 4084// (indexed, offset) 4085 4086class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4087 string asm> 4088 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4089 bits<5> Rt; 4090 bits<5> Rt2; 4091 bits<5> Rn; 4092 bits<7> offset; 4093 let Inst{31-30} = opc; 4094 let Inst{29-27} = 0b101; 4095 let Inst{26} = V; 4096 let Inst{25-23} = 0b010; 4097 let Inst{22} = L; 4098 let Inst{21-15} = offset; 4099 let Inst{14-10} = Rt2; 4100 let Inst{9-5} = Rn; 4101 let Inst{4-0} = Rt; 4102 4103 let DecoderMethod = "DecodePairLdStInstruction"; 4104} 4105 4106multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4107 Operand indextype, string asm> { 4108 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4109 def i : BaseLoadStorePairOffset<opc, V, 1, 4110 (outs regtype:$Rt, regtype:$Rt2), 4111 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4112 Sched<[WriteLD, WriteLDHi]>; 4113 4114 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4115 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4116 GPR64sp:$Rn, 0)>; 4117} 4118 4119 4120multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4121 Operand indextype, string asm> { 4122 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4123 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4124 (ins regtype:$Rt, regtype:$Rt2, 4125 GPR64sp:$Rn, indextype:$offset), 4126 asm>, 4127 Sched<[WriteSTP]>; 4128 4129 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4130 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4131 GPR64sp:$Rn, 0)>; 4132} 4133 4134// (pre-indexed) 4135class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4136 string asm> 4137 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4138 bits<5> Rt; 4139 bits<5> Rt2; 4140 bits<5> Rn; 4141 bits<7> offset; 4142 let Inst{31-30} = opc; 4143 let Inst{29-27} = 0b101; 4144 let Inst{26} = V; 4145 let Inst{25-23} = 0b011; 4146 let Inst{22} = L; 4147 let Inst{21-15} = offset; 4148 let Inst{14-10} = Rt2; 4149 let Inst{9-5} = Rn; 4150 let Inst{4-0} = Rt; 4151 4152 let DecoderMethod = "DecodePairLdStInstruction"; 4153} 4154 4155let hasSideEffects = 0 in { 4156let mayStore = 0, mayLoad = 1 in 4157class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4158 Operand indextype, string asm> 4159 : BaseLoadStorePairPreIdx<opc, V, 1, 4160 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4161 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4162 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4163 4164let mayStore = 1, mayLoad = 0 in 4165class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4166 Operand indextype, string asm> 4167 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4168 (ins regtype:$Rt, regtype:$Rt2, 4169 GPR64sp:$Rn, indextype:$offset), 4170 asm>, 4171 Sched<[WriteAdr, WriteSTP]>; 4172} // hasSideEffects = 0 4173 4174// (post-indexed) 4175 4176class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4177 string asm> 4178 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4179 bits<5> Rt; 4180 bits<5> Rt2; 4181 bits<5> Rn; 4182 bits<7> offset; 4183 let Inst{31-30} = opc; 4184 let Inst{29-27} = 0b101; 4185 let Inst{26} = V; 4186 let Inst{25-23} = 0b001; 4187 let Inst{22} = L; 4188 let Inst{21-15} = offset; 4189 let Inst{14-10} = Rt2; 4190 let Inst{9-5} = Rn; 4191 let Inst{4-0} = Rt; 4192 4193 let DecoderMethod = "DecodePairLdStInstruction"; 4194} 4195 4196let hasSideEffects = 0 in { 4197let mayStore = 0, mayLoad = 1 in 4198class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4199 Operand idxtype, string asm> 4200 : BaseLoadStorePairPostIdx<opc, V, 1, 4201 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4202 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4203 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4204 4205let mayStore = 1, mayLoad = 0 in 4206class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4207 Operand idxtype, string asm> 4208 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4209 (ins regtype:$Rt, regtype:$Rt2, 4210 GPR64sp:$Rn, idxtype:$offset), 4211 asm>, 4212 Sched<[WriteAdr, WriteSTP]>; 4213} // hasSideEffects = 0 4214 4215// (no-allocate) 4216 4217class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4218 string asm> 4219 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4220 bits<5> Rt; 4221 bits<5> Rt2; 4222 bits<5> Rn; 4223 bits<7> offset; 4224 let Inst{31-30} = opc; 4225 let Inst{29-27} = 0b101; 4226 let Inst{26} = V; 4227 let Inst{25-23} = 0b000; 4228 let Inst{22} = L; 4229 let Inst{21-15} = offset; 4230 let Inst{14-10} = Rt2; 4231 let Inst{9-5} = Rn; 4232 let Inst{4-0} = Rt; 4233 4234 let DecoderMethod = "DecodePairLdStInstruction"; 4235} 4236 4237multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4238 Operand indextype, string asm> { 4239 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4240 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4241 (outs regtype:$Rt, regtype:$Rt2), 4242 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4243 Sched<[WriteLD, WriteLDHi]>; 4244 4245 4246 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4247 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4248 GPR64sp:$Rn, 0)>; 4249} 4250 4251multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4252 Operand indextype, string asm> { 4253 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4254 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4255 (ins regtype:$Rt, regtype:$Rt2, 4256 GPR64sp:$Rn, indextype:$offset), 4257 asm>, 4258 Sched<[WriteSTP]>; 4259 4260 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4261 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4262 GPR64sp:$Rn, 0)>; 4263} 4264 4265//--- 4266// Load/store exclusive 4267//--- 4268 4269// True exclusive operations write to and/or read from the system's exclusive 4270// monitors, which as far as a compiler is concerned can be modelled as a 4271// random shared memory address. Hence LoadExclusive mayStore. 4272// 4273// Since these instructions have the undefined register bits set to 1 in 4274// their canonical form, we need a post encoder method to set those bits 4275// to 1 when encoding these instructions. We do this using the 4276// fixLoadStoreExclusive function. This function has template parameters: 4277// 4278// fixLoadStoreExclusive<int hasRs, int hasRt2> 4279// 4280// hasRs indicates that the instruction uses the Rs field, so we won't set 4281// it to 1 (and the same for Rt2). We don't need template parameters for 4282// the other register fields since Rt and Rn are always used. 4283// 4284let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4285class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4286 dag oops, dag iops, string asm, string operands> 4287 : I<oops, iops, asm, operands, "", []> { 4288 let Inst{31-30} = sz; 4289 let Inst{29-24} = 0b001000; 4290 let Inst{23} = o2; 4291 let Inst{22} = L; 4292 let Inst{21} = o1; 4293 let Inst{15} = o0; 4294 4295 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4296} 4297 4298// Neither Rs nor Rt2 operands. 4299class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4300 dag oops, dag iops, string asm, string operands> 4301 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4302 bits<5> Rt; 4303 bits<5> Rn; 4304 let Inst{20-16} = 0b11111; 4305 let Unpredictable{20-16} = 0b11111; 4306 let Inst{14-10} = 0b11111; 4307 let Unpredictable{14-10} = 0b11111; 4308 let Inst{9-5} = Rn; 4309 let Inst{4-0} = Rt; 4310 4311 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4312} 4313 4314// Simple load acquires don't set the exclusive monitor 4315let mayLoad = 1, mayStore = 0 in 4316class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4317 RegisterClass regtype, string asm> 4318 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4319 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4320 Sched<[WriteLD]>; 4321 4322class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4323 RegisterClass regtype, string asm> 4324 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4325 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4326 Sched<[WriteLD]>; 4327 4328class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4329 RegisterClass regtype, string asm> 4330 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4331 (outs regtype:$Rt, regtype:$Rt2), 4332 (ins GPR64sp0:$Rn), asm, 4333 "\t$Rt, $Rt2, [$Rn]">, 4334 Sched<[WriteLD, WriteLDHi]> { 4335 bits<5> Rt; 4336 bits<5> Rt2; 4337 bits<5> Rn; 4338 let Inst{14-10} = Rt2; 4339 let Inst{9-5} = Rn; 4340 let Inst{4-0} = Rt; 4341 4342 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4343} 4344 4345// Simple store release operations do not check the exclusive monitor. 4346let mayLoad = 0, mayStore = 1 in 4347class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4348 RegisterClass regtype, string asm> 4349 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4350 (ins regtype:$Rt, GPR64sp0:$Rn), 4351 asm, "\t$Rt, [$Rn]">, 4352 Sched<[WriteST]>; 4353 4354let mayLoad = 1, mayStore = 1 in 4355class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4356 RegisterClass regtype, string asm> 4357 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4358 (ins regtype:$Rt, GPR64sp0:$Rn), 4359 asm, "\t$Ws, $Rt, [$Rn]">, 4360 Sched<[WriteSTX]> { 4361 bits<5> Ws; 4362 bits<5> Rt; 4363 bits<5> Rn; 4364 let Inst{20-16} = Ws; 4365 let Inst{9-5} = Rn; 4366 let Inst{4-0} = Rt; 4367 4368 let Constraints = "@earlyclobber $Ws"; 4369 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4370} 4371 4372class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4373 RegisterClass regtype, string asm> 4374 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4375 (outs GPR32:$Ws), 4376 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4377 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4378 Sched<[WriteSTX]> { 4379 bits<5> Ws; 4380 bits<5> Rt; 4381 bits<5> Rt2; 4382 bits<5> Rn; 4383 let Inst{20-16} = Ws; 4384 let Inst{14-10} = Rt2; 4385 let Inst{9-5} = Rn; 4386 let Inst{4-0} = Rt; 4387 4388 let Constraints = "@earlyclobber $Ws"; 4389} 4390 4391// Armv8.5-A Memory Tagging Extension 4392class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4393 string asm_opnds, string cstr, dag oops, dag iops> 4394 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4395 Sched<[]> { 4396 bits<5> Rn; 4397 4398 let Inst{31-24} = 0b11011001; 4399 let Inst{23-22} = opc1; 4400 let Inst{21} = 1; 4401 // Inst{20-12} defined by subclass 4402 let Inst{11-10} = opc2; 4403 let Inst{9-5} = Rn; 4404 // Inst{4-0} defined by subclass 4405} 4406 4407class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4408 dag oops, dag iops> 4409 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4410 "", oops, iops> { 4411 bits<5> Rt; 4412 4413 let Inst{20-12} = 0b000000000; 4414 let Inst{4-0} = Rt; 4415 4416 let mayLoad = Load; 4417} 4418 4419class MemTagLoad<string asm_insn, string asm_opnds> 4420 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4421 (outs GPR64:$wback), 4422 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4423 bits<5> Rt; 4424 bits<9> offset; 4425 4426 let Inst{20-12} = offset; 4427 let Inst{4-0} = Rt; 4428 4429 let mayLoad = 1; 4430} 4431 4432class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4433 string asm_opnds, string cstr, dag oops, dag iops> 4434 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4435 bits<5> Rt; 4436 bits<9> offset; 4437 4438 let Inst{20-12} = offset; 4439 let Inst{4-0} = Rt; 4440 4441 let mayStore = 1; 4442} 4443 4444multiclass MemTagStore<bits<2> opc1, string insn> { 4445 def Offset : 4446 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4447 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4448 def PreIndex : 4449 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4450 "$Rn = $wback", 4451 (outs GPR64sp:$wback), 4452 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4453 def PostIndex : 4454 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4455 "$Rn = $wback", 4456 (outs GPR64sp:$wback), 4457 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4458 4459 def : InstAlias<insn # "\t$Rt, [$Rn]", 4460 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4461} 4462 4463//--- 4464// Exception generation 4465//--- 4466 4467let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4468class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4469 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>, 4470 Sched<[WriteSys]> { 4471 bits<16> imm; 4472 let Inst{31-24} = 0b11010100; 4473 let Inst{23-21} = op1; 4474 let Inst{20-5} = imm; 4475 let Inst{4-2} = 0b000; 4476 let Inst{1-0} = ll; 4477} 4478 4479//--- 4480// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4481//-- 4482let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4483class UDFType<bits<16> opc, string asm> 4484 : I<(outs), (ins uimm16:$imm), 4485 asm, "\t$imm", "", []>, 4486 Sched<[]> { 4487 bits<16> imm; 4488 let Inst{31-16} = opc; 4489 let Inst{15-0} = imm; 4490} 4491} 4492let Predicates = [HasFPARMv8] in { 4493 4494//--- 4495// Floating point to integer conversion 4496//--- 4497 4498class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4499 RegisterClass srcType, RegisterClass dstType, 4500 string asm, list<dag> pattern> 4501 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4502 asm, "\t$Rd, $Rn", "", pattern>, 4503 Sched<[WriteFCvt]> { 4504 bits<5> Rd; 4505 bits<5> Rn; 4506 let Inst{30-29} = 0b00; 4507 let Inst{28-24} = 0b11110; 4508 let Inst{23-22} = type; 4509 let Inst{21} = 1; 4510 let Inst{20-19} = rmode; 4511 let Inst{18-16} = opcode; 4512 let Inst{15-10} = 0; 4513 let Inst{9-5} = Rn; 4514 let Inst{4-0} = Rd; 4515} 4516 4517let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4518class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4519 RegisterClass srcType, RegisterClass dstType, 4520 Operand immType, string asm, list<dag> pattern> 4521 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4522 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4523 Sched<[WriteFCvt]> { 4524 bits<5> Rd; 4525 bits<5> Rn; 4526 bits<6> scale; 4527 let Inst{30-29} = 0b00; 4528 let Inst{28-24} = 0b11110; 4529 let Inst{23-22} = type; 4530 let Inst{21} = 0; 4531 let Inst{20-19} = rmode; 4532 let Inst{18-16} = opcode; 4533 let Inst{15-10} = scale; 4534 let Inst{9-5} = Rn; 4535 let Inst{4-0} = Rd; 4536} 4537 4538multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4539 SDPatternOperator OpN> { 4540 // Unscaled half-precision to 32-bit 4541 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4542 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4543 let Inst{31} = 0; // 32-bit GPR flag 4544 let Predicates = [HasFullFP16]; 4545 } 4546 4547 // Unscaled half-precision to 64-bit 4548 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4549 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4550 let Inst{31} = 1; // 64-bit GPR flag 4551 let Predicates = [HasFullFP16]; 4552 } 4553 4554 // Unscaled single-precision to 32-bit 4555 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4556 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4557 let Inst{31} = 0; // 32-bit GPR flag 4558 } 4559 4560 // Unscaled single-precision to 64-bit 4561 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4562 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4563 let Inst{31} = 1; // 64-bit GPR flag 4564 } 4565 4566 // Unscaled double-precision to 32-bit 4567 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4568 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4569 let Inst{31} = 0; // 32-bit GPR flag 4570 } 4571 4572 // Unscaled double-precision to 64-bit 4573 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4574 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4575 let Inst{31} = 1; // 64-bit GPR flag 4576 } 4577} 4578 4579multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4580 SDPatternOperator OpN> { 4581 // Scaled half-precision to 32-bit 4582 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4583 fixedpoint_f16_i32, asm, 4584 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4585 fixedpoint_f16_i32:$scale)))]> { 4586 let Inst{31} = 0; // 32-bit GPR flag 4587 let scale{5} = 1; 4588 let Predicates = [HasFullFP16]; 4589 } 4590 4591 // Scaled half-precision to 64-bit 4592 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4593 fixedpoint_f16_i64, asm, 4594 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4595 fixedpoint_f16_i64:$scale)))]> { 4596 let Inst{31} = 1; // 64-bit GPR flag 4597 let Predicates = [HasFullFP16]; 4598 } 4599 4600 // Scaled single-precision to 32-bit 4601 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4602 fixedpoint_f32_i32, asm, 4603 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4604 fixedpoint_f32_i32:$scale)))]> { 4605 let Inst{31} = 0; // 32-bit GPR flag 4606 let scale{5} = 1; 4607 } 4608 4609 // Scaled single-precision to 64-bit 4610 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4611 fixedpoint_f32_i64, asm, 4612 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4613 fixedpoint_f32_i64:$scale)))]> { 4614 let Inst{31} = 1; // 64-bit GPR flag 4615 } 4616 4617 // Scaled double-precision to 32-bit 4618 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4619 fixedpoint_f64_i32, asm, 4620 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4621 fixedpoint_f64_i32:$scale)))]> { 4622 let Inst{31} = 0; // 32-bit GPR flag 4623 let scale{5} = 1; 4624 } 4625 4626 // Scaled double-precision to 64-bit 4627 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4628 fixedpoint_f64_i64, asm, 4629 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4630 fixedpoint_f64_i64:$scale)))]> { 4631 let Inst{31} = 1; // 64-bit GPR flag 4632 } 4633} 4634 4635//--- 4636// Integer to floating point conversion 4637//--- 4638 4639let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4640class BaseIntegerToFP<bit isUnsigned, 4641 RegisterClass srcType, RegisterClass dstType, 4642 Operand immType, string asm, list<dag> pattern> 4643 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4644 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4645 Sched<[WriteFCvt]> { 4646 bits<5> Rd; 4647 bits<5> Rn; 4648 bits<6> scale; 4649 let Inst{30-24} = 0b0011110; 4650 let Inst{21-17} = 0b00001; 4651 let Inst{16} = isUnsigned; 4652 let Inst{15-10} = scale; 4653 let Inst{9-5} = Rn; 4654 let Inst{4-0} = Rd; 4655} 4656 4657class BaseIntegerToFPUnscaled<bit isUnsigned, 4658 RegisterClass srcType, RegisterClass dstType, 4659 ValueType dvt, string asm, SDPatternOperator node> 4660 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4661 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4662 Sched<[WriteFCvt]> { 4663 bits<5> Rd; 4664 bits<5> Rn; 4665 bits<6> scale; 4666 let Inst{30-24} = 0b0011110; 4667 let Inst{21-17} = 0b10001; 4668 let Inst{16} = isUnsigned; 4669 let Inst{15-10} = 0b000000; 4670 let Inst{9-5} = Rn; 4671 let Inst{4-0} = Rd; 4672} 4673 4674multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4675 // Unscaled 4676 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4677 let Inst{31} = 0; // 32-bit GPR flag 4678 let Inst{23-22} = 0b11; // 16-bit FPR flag 4679 let Predicates = [HasFullFP16]; 4680 } 4681 4682 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4683 let Inst{31} = 0; // 32-bit GPR flag 4684 let Inst{23-22} = 0b00; // 32-bit FPR flag 4685 } 4686 4687 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4688 let Inst{31} = 0; // 32-bit GPR flag 4689 let Inst{23-22} = 0b01; // 64-bit FPR flag 4690 } 4691 4692 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4693 let Inst{31} = 1; // 64-bit GPR flag 4694 let Inst{23-22} = 0b11; // 16-bit FPR flag 4695 let Predicates = [HasFullFP16]; 4696 } 4697 4698 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4699 let Inst{31} = 1; // 64-bit GPR flag 4700 let Inst{23-22} = 0b00; // 32-bit FPR flag 4701 } 4702 4703 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4704 let Inst{31} = 1; // 64-bit GPR flag 4705 let Inst{23-22} = 0b01; // 64-bit FPR flag 4706 } 4707 4708 // Scaled 4709 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4710 [(set (f16 FPR16:$Rd), 4711 (fdiv (node GPR32:$Rn), 4712 fixedpoint_f16_i32:$scale))]> { 4713 let Inst{31} = 0; // 32-bit GPR flag 4714 let Inst{23-22} = 0b11; // 16-bit FPR flag 4715 let scale{5} = 1; 4716 let Predicates = [HasFullFP16]; 4717 } 4718 4719 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4720 [(set FPR32:$Rd, 4721 (fdiv (node GPR32:$Rn), 4722 fixedpoint_f32_i32:$scale))]> { 4723 let Inst{31} = 0; // 32-bit GPR flag 4724 let Inst{23-22} = 0b00; // 32-bit FPR flag 4725 let scale{5} = 1; 4726 } 4727 4728 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4729 [(set FPR64:$Rd, 4730 (fdiv (node GPR32:$Rn), 4731 fixedpoint_f64_i32:$scale))]> { 4732 let Inst{31} = 0; // 32-bit GPR flag 4733 let Inst{23-22} = 0b01; // 64-bit FPR flag 4734 let scale{5} = 1; 4735 } 4736 4737 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4738 [(set (f16 FPR16:$Rd), 4739 (fdiv (node GPR64:$Rn), 4740 fixedpoint_f16_i64:$scale))]> { 4741 let Inst{31} = 1; // 64-bit GPR flag 4742 let Inst{23-22} = 0b11; // 16-bit FPR flag 4743 let Predicates = [HasFullFP16]; 4744 } 4745 4746 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4747 [(set FPR32:$Rd, 4748 (fdiv (node GPR64:$Rn), 4749 fixedpoint_f32_i64:$scale))]> { 4750 let Inst{31} = 1; // 64-bit GPR flag 4751 let Inst{23-22} = 0b00; // 32-bit FPR flag 4752 } 4753 4754 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4755 [(set FPR64:$Rd, 4756 (fdiv (node GPR64:$Rn), 4757 fixedpoint_f64_i64:$scale))]> { 4758 let Inst{31} = 1; // 64-bit GPR flag 4759 let Inst{23-22} = 0b01; // 64-bit FPR flag 4760 } 4761} 4762 4763//--- 4764// Unscaled integer <-> floating point conversion (i.e. FMOV) 4765//--- 4766 4767let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4768class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4769 RegisterClass srcType, RegisterClass dstType, 4770 string asm> 4771 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4772 // We use COPY_TO_REGCLASS for these bitconvert operations. 4773 // copyPhysReg() expands the resultant COPY instructions after 4774 // regalloc is done. This gives greater freedom for the allocator 4775 // and related passes (coalescing, copy propagation, et. al.) to 4776 // be more effective. 4777 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4778 Sched<[WriteFCopy]> { 4779 bits<5> Rd; 4780 bits<5> Rn; 4781 let Inst{30-24} = 0b0011110; 4782 let Inst{21} = 1; 4783 let Inst{20-19} = rmode; 4784 let Inst{18-16} = opcode; 4785 let Inst{15-10} = 0b000000; 4786 let Inst{9-5} = Rn; 4787 let Inst{4-0} = Rd; 4788} 4789 4790let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4791class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4792 RegisterClass srcType, RegisterOperand dstType, string asm, 4793 string kind> 4794 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4795 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4796 Sched<[WriteFCopy]> { 4797 bits<5> Rd; 4798 bits<5> Rn; 4799 let Inst{30-23} = 0b00111101; 4800 let Inst{21} = 1; 4801 let Inst{20-19} = rmode; 4802 let Inst{18-16} = opcode; 4803 let Inst{15-10} = 0b000000; 4804 let Inst{9-5} = Rn; 4805 let Inst{4-0} = Rd; 4806 4807 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4808} 4809 4810let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4811class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4812 RegisterOperand srcType, RegisterClass dstType, string asm, 4813 string kind> 4814 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4815 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4816 Sched<[WriteFCopy]> { 4817 bits<5> Rd; 4818 bits<5> Rn; 4819 let Inst{30-23} = 0b00111101; 4820 let Inst{21} = 1; 4821 let Inst{20-19} = rmode; 4822 let Inst{18-16} = opcode; 4823 let Inst{15-10} = 0b000000; 4824 let Inst{9-5} = Rn; 4825 let Inst{4-0} = Rd; 4826 4827 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4828} 4829 4830 4831multiclass UnscaledConversion<string asm> { 4832 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4833 let Inst{31} = 0; // 32-bit GPR flag 4834 let Inst{23-22} = 0b11; // 16-bit FPR flag 4835 let Predicates = [HasFullFP16]; 4836 } 4837 4838 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4839 let Inst{31} = 1; // 64-bit GPR flag 4840 let Inst{23-22} = 0b11; // 16-bit FPR flag 4841 let Predicates = [HasFullFP16]; 4842 } 4843 4844 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4845 let Inst{31} = 0; // 32-bit GPR flag 4846 let Inst{23-22} = 0b00; // 32-bit FPR flag 4847 } 4848 4849 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4850 let Inst{31} = 1; // 64-bit GPR flag 4851 let Inst{23-22} = 0b01; // 64-bit FPR flag 4852 } 4853 4854 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4855 let Inst{31} = 0; // 32-bit GPR flag 4856 let Inst{23-22} = 0b11; // 16-bit FPR flag 4857 let Predicates = [HasFullFP16]; 4858 } 4859 4860 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4861 let Inst{31} = 1; // 64-bit GPR flag 4862 let Inst{23-22} = 0b11; // 16-bit FPR flag 4863 let Predicates = [HasFullFP16]; 4864 } 4865 4866 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4867 let Inst{31} = 0; // 32-bit GPR flag 4868 let Inst{23-22} = 0b00; // 32-bit FPR flag 4869 } 4870 4871 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4872 let Inst{31} = 1; // 64-bit GPR flag 4873 let Inst{23-22} = 0b01; // 64-bit FPR flag 4874 } 4875 4876 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4877 asm, ".d"> { 4878 let Inst{31} = 1; 4879 let Inst{22} = 0; 4880 } 4881 4882 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4883 asm, ".d"> { 4884 let Inst{31} = 1; 4885 let Inst{22} = 0; 4886 } 4887} 4888 4889//--- 4890// Floating point conversion 4891//--- 4892 4893class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4894 RegisterClass srcType, string asm, list<dag> pattern> 4895 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4896 Sched<[WriteFCvt]> { 4897 bits<5> Rd; 4898 bits<5> Rn; 4899 let Inst{31-24} = 0b00011110; 4900 let Inst{23-22} = type; 4901 let Inst{21-17} = 0b10001; 4902 let Inst{16-15} = opcode; 4903 let Inst{14-10} = 0b10000; 4904 let Inst{9-5} = Rn; 4905 let Inst{4-0} = Rd; 4906} 4907 4908multiclass FPConversion<string asm> { 4909 // Double-precision to Half-precision 4910 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4911 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4912 4913 // Double-precision to Single-precision 4914 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4915 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4916 4917 // Half-precision to Double-precision 4918 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4919 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4920 4921 // Half-precision to Single-precision 4922 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4923 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4924 4925 // Single-precision to Double-precision 4926 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4927 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4928 4929 // Single-precision to Half-precision 4930 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4931 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 4932} 4933 4934//--- 4935// Single operand floating point data processing 4936//--- 4937 4938let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4939class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4940 ValueType vt, string asm, SDPatternOperator node> 4941 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4942 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4943 Sched<[WriteF]> { 4944 bits<5> Rd; 4945 bits<5> Rn; 4946 let Inst{31-24} = 0b00011110; 4947 let Inst{21} = 0b1; 4948 let Inst{20-15} = opcode; 4949 let Inst{14-10} = 0b10000; 4950 let Inst{9-5} = Rn; 4951 let Inst{4-0} = Rd; 4952} 4953 4954multiclass SingleOperandFPData<bits<4> opcode, string asm, 4955 SDPatternOperator node = null_frag> { 4956 4957 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 4958 let Inst{23-22} = 0b11; // 16-bit size flag 4959 let Predicates = [HasFullFP16]; 4960 } 4961 4962 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 4963 let Inst{23-22} = 0b00; // 32-bit size flag 4964 } 4965 4966 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 4967 let Inst{23-22} = 0b01; // 64-bit size flag 4968 } 4969} 4970 4971multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 4972 SDPatternOperator node = null_frag>{ 4973 4974 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 4975 let Inst{23-22} = 0b00; // 32-bit registers 4976 } 4977 4978 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 4979 let Inst{23-22} = 0b01; // 64-bit registers 4980 } 4981} 4982 4983// FRInt[32|64][Z|N] instructions 4984multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 4985 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 4986 4987//--- 4988// Two operand floating point data processing 4989//--- 4990 4991let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4992class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4993 string asm, list<dag> pat> 4994 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4995 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4996 Sched<[WriteF]> { 4997 bits<5> Rd; 4998 bits<5> Rn; 4999 bits<5> Rm; 5000 let Inst{31-24} = 0b00011110; 5001 let Inst{21} = 1; 5002 let Inst{20-16} = Rm; 5003 let Inst{15-12} = opcode; 5004 let Inst{11-10} = 0b10; 5005 let Inst{9-5} = Rn; 5006 let Inst{4-0} = Rd; 5007} 5008 5009multiclass TwoOperandFPData<bits<4> opcode, string asm, 5010 SDPatternOperator node = null_frag> { 5011 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5012 [(set (f16 FPR16:$Rd), 5013 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5014 let Inst{23-22} = 0b11; // 16-bit size flag 5015 let Predicates = [HasFullFP16]; 5016 } 5017 5018 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5019 [(set (f32 FPR32:$Rd), 5020 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5021 let Inst{23-22} = 0b00; // 32-bit size flag 5022 } 5023 5024 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5025 [(set (f64 FPR64:$Rd), 5026 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5027 let Inst{23-22} = 0b01; // 64-bit size flag 5028 } 5029} 5030 5031multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 5032 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5033 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5034 let Inst{23-22} = 0b11; // 16-bit size flag 5035 let Predicates = [HasFullFP16]; 5036 } 5037 5038 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5039 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5040 let Inst{23-22} = 0b00; // 32-bit size flag 5041 } 5042 5043 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5044 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5045 let Inst{23-22} = 0b01; // 64-bit size flag 5046 } 5047} 5048 5049 5050//--- 5051// Three operand floating point data processing 5052//--- 5053 5054class BaseThreeOperandFPData<bit isNegated, bit isSub, 5055 RegisterClass regtype, string asm, list<dag> pat> 5056 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5057 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5058 Sched<[WriteFMul]> { 5059 bits<5> Rd; 5060 bits<5> Rn; 5061 bits<5> Rm; 5062 bits<5> Ra; 5063 let Inst{31-24} = 0b00011111; 5064 let Inst{21} = isNegated; 5065 let Inst{20-16} = Rm; 5066 let Inst{15} = isSub; 5067 let Inst{14-10} = Ra; 5068 let Inst{9-5} = Rn; 5069 let Inst{4-0} = Rd; 5070} 5071 5072multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5073 SDPatternOperator node> { 5074 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5075 [(set (f16 FPR16:$Rd), 5076 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5077 let Inst{23-22} = 0b11; // 16-bit size flag 5078 let Predicates = [HasFullFP16]; 5079 } 5080 5081 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5082 [(set FPR32:$Rd, 5083 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5084 let Inst{23-22} = 0b00; // 32-bit size flag 5085 } 5086 5087 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5088 [(set FPR64:$Rd, 5089 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5090 let Inst{23-22} = 0b01; // 64-bit size flag 5091 } 5092} 5093 5094//--- 5095// Floating point data comparisons 5096//--- 5097 5098let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5099class BaseOneOperandFPComparison<bit signalAllNans, 5100 RegisterClass regtype, string asm, 5101 list<dag> pat> 5102 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5103 Sched<[WriteFCmp]> { 5104 bits<5> Rn; 5105 let Inst{31-24} = 0b00011110; 5106 let Inst{21} = 1; 5107 5108 let Inst{15-10} = 0b001000; 5109 let Inst{9-5} = Rn; 5110 let Inst{4} = signalAllNans; 5111 let Inst{3-0} = 0b1000; 5112 5113 // Rm should be 0b00000 canonically, but we need to accept any value. 5114 let PostEncoderMethod = "fixOneOperandFPComparison"; 5115} 5116 5117let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5118class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5119 string asm, list<dag> pat> 5120 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5121 Sched<[WriteFCmp]> { 5122 bits<5> Rm; 5123 bits<5> Rn; 5124 let Inst{31-24} = 0b00011110; 5125 let Inst{21} = 1; 5126 let Inst{20-16} = Rm; 5127 let Inst{15-10} = 0b001000; 5128 let Inst{9-5} = Rn; 5129 let Inst{4} = signalAllNans; 5130 let Inst{3-0} = 0b0000; 5131} 5132 5133multiclass FPComparison<bit signalAllNans, string asm, 5134 SDPatternOperator OpNode = null_frag> { 5135 let Defs = [NZCV] in { 5136 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5137 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5138 let Inst{23-22} = 0b11; 5139 let Predicates = [HasFullFP16]; 5140 } 5141 5142 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5143 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5144 let Inst{23-22} = 0b11; 5145 let Predicates = [HasFullFP16]; 5146 } 5147 5148 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5149 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5150 let Inst{23-22} = 0b00; 5151 } 5152 5153 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5154 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5155 let Inst{23-22} = 0b00; 5156 } 5157 5158 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5159 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5160 let Inst{23-22} = 0b01; 5161 } 5162 5163 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5164 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5165 let Inst{23-22} = 0b01; 5166 } 5167 } // Defs = [NZCV] 5168} 5169 5170//--- 5171// Floating point conditional comparisons 5172//--- 5173 5174let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5175class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5176 string mnemonic, list<dag> pat> 5177 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5178 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5179 Sched<[WriteFCmp]> { 5180 let Uses = [NZCV]; 5181 let Defs = [NZCV]; 5182 5183 bits<5> Rn; 5184 bits<5> Rm; 5185 bits<4> nzcv; 5186 bits<4> cond; 5187 5188 let Inst{31-24} = 0b00011110; 5189 let Inst{21} = 1; 5190 let Inst{20-16} = Rm; 5191 let Inst{15-12} = cond; 5192 let Inst{11-10} = 0b01; 5193 let Inst{9-5} = Rn; 5194 let Inst{4} = signalAllNans; 5195 let Inst{3-0} = nzcv; 5196} 5197 5198multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5199 SDPatternOperator OpNode = null_frag> { 5200 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5201 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5202 (i32 imm:$cond), NZCV))]> { 5203 let Inst{23-22} = 0b11; 5204 let Predicates = [HasFullFP16]; 5205 } 5206 5207 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5208 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5209 (i32 imm:$cond), NZCV))]> { 5210 let Inst{23-22} = 0b00; 5211 } 5212 5213 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5214 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5215 (i32 imm:$cond), NZCV))]> { 5216 let Inst{23-22} = 0b01; 5217 } 5218} 5219 5220//--- 5221// Floating point conditional select 5222//--- 5223 5224class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5225 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5226 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5227 [(set regtype:$Rd, 5228 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5229 (i32 imm:$cond), NZCV))]>, 5230 Sched<[WriteF]> { 5231 bits<5> Rd; 5232 bits<5> Rn; 5233 bits<5> Rm; 5234 bits<4> cond; 5235 5236 let Inst{31-24} = 0b00011110; 5237 let Inst{21} = 1; 5238 let Inst{20-16} = Rm; 5239 let Inst{15-12} = cond; 5240 let Inst{11-10} = 0b11; 5241 let Inst{9-5} = Rn; 5242 let Inst{4-0} = Rd; 5243} 5244 5245multiclass FPCondSelect<string asm> { 5246 let Uses = [NZCV] in { 5247 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5248 let Inst{23-22} = 0b11; 5249 let Predicates = [HasFullFP16]; 5250 } 5251 5252 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5253 let Inst{23-22} = 0b00; 5254 } 5255 5256 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5257 let Inst{23-22} = 0b01; 5258 } 5259 } // Uses = [NZCV] 5260} 5261 5262//--- 5263// Floating move immediate 5264//--- 5265 5266class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5267 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5268 [(set regtype:$Rd, fpimmtype:$imm)]>, 5269 Sched<[WriteFImm]> { 5270 bits<5> Rd; 5271 bits<8> imm; 5272 let Inst{31-24} = 0b00011110; 5273 let Inst{21} = 1; 5274 let Inst{20-13} = imm; 5275 let Inst{12-5} = 0b10000000; 5276 let Inst{4-0} = Rd; 5277} 5278 5279multiclass FPMoveImmediate<string asm> { 5280 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5281 let Inst{23-22} = 0b11; 5282 let Predicates = [HasFullFP16]; 5283 } 5284 5285 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5286 let Inst{23-22} = 0b00; 5287 } 5288 5289 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5290 let Inst{23-22} = 0b01; 5291 } 5292} 5293} // end of 'let Predicates = [HasFPARMv8]' 5294 5295//---------------------------------------------------------------------------- 5296// AdvSIMD 5297//---------------------------------------------------------------------------- 5298 5299let Predicates = [HasNEON] in { 5300 5301//---------------------------------------------------------------------------- 5302// AdvSIMD three register vector instructions 5303//---------------------------------------------------------------------------- 5304 5305let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5306class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5307 RegisterOperand regtype, string asm, string kind, 5308 list<dag> pattern> 5309 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5310 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5311 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5312 Sched<[WriteV]> { 5313 bits<5> Rd; 5314 bits<5> Rn; 5315 bits<5> Rm; 5316 let Inst{31} = 0; 5317 let Inst{30} = Q; 5318 let Inst{29} = U; 5319 let Inst{28-24} = 0b01110; 5320 let Inst{23-21} = size; 5321 let Inst{20-16} = Rm; 5322 let Inst{15-11} = opcode; 5323 let Inst{10} = 1; 5324 let Inst{9-5} = Rn; 5325 let Inst{4-0} = Rd; 5326} 5327 5328let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5329class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5330 RegisterOperand regtype, string asm, string kind, 5331 list<dag> pattern> 5332 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5333 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5334 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5335 Sched<[WriteV]> { 5336 bits<5> Rd; 5337 bits<5> Rn; 5338 bits<5> Rm; 5339 let Inst{31} = 0; 5340 let Inst{30} = Q; 5341 let Inst{29} = U; 5342 let Inst{28-24} = 0b01110; 5343 let Inst{23-21} = size; 5344 let Inst{20-16} = Rm; 5345 let Inst{15-11} = opcode; 5346 let Inst{10} = 1; 5347 let Inst{9-5} = Rn; 5348 let Inst{4-0} = Rd; 5349} 5350 5351let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5352class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5353 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5354 Sched<[WriteV]>; 5355 5356multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5357 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5358 [(set (v8i8 V64:$dst), 5359 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5360 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5361 [(set (v16i8 V128:$dst), 5362 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5363 (v16i8 V128:$Rm)))]>; 5364 5365 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5366 (v4i16 V64:$RHS))), 5367 (!cast<Instruction>(NAME#"v8i8") 5368 V64:$LHS, V64:$MHS, V64:$RHS)>; 5369 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5370 (v2i32 V64:$RHS))), 5371 (!cast<Instruction>(NAME#"v8i8") 5372 V64:$LHS, V64:$MHS, V64:$RHS)>; 5373 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5374 (v1i64 V64:$RHS))), 5375 (!cast<Instruction>(NAME#"v8i8") 5376 V64:$LHS, V64:$MHS, V64:$RHS)>; 5377 5378 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5379 (v8i16 V128:$RHS))), 5380 (!cast<Instruction>(NAME#"v16i8") 5381 V128:$LHS, V128:$MHS, V128:$RHS)>; 5382 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5383 (v4i32 V128:$RHS))), 5384 (!cast<Instruction>(NAME#"v16i8") 5385 V128:$LHS, V128:$MHS, V128:$RHS)>; 5386 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5387 (v2i64 V128:$RHS))), 5388 (!cast<Instruction>(NAME#"v16i8") 5389 V128:$LHS, V128:$MHS, V128:$RHS)>; 5390} 5391 5392// All operand sizes distinguished in the encoding. 5393multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5394 SDPatternOperator OpNode> { 5395 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5396 asm, ".8b", 5397 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5398 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5399 asm, ".16b", 5400 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5401 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5402 asm, ".4h", 5403 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5404 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5405 asm, ".8h", 5406 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5407 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5408 asm, ".2s", 5409 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5410 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5411 asm, ".4s", 5412 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5413 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5414 asm, ".2d", 5415 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5416} 5417 5418multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5419 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5420 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5421 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5422 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5423 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5424 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5425 5426 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5427 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5428 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5429 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5430 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5431 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5432 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5433 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5434} 5435 5436// As above, but D sized elements unsupported. 5437multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5438 SDPatternOperator OpNode> { 5439 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5440 asm, ".8b", 5441 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5442 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5443 asm, ".16b", 5444 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5445 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5446 asm, ".4h", 5447 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5448 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5449 asm, ".8h", 5450 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5451 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5452 asm, ".2s", 5453 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5454 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5455 asm, ".4s", 5456 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5457} 5458 5459multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5460 SDPatternOperator OpNode> { 5461 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5462 asm, ".8b", 5463 [(set (v8i8 V64:$dst), 5464 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5465 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5466 asm, ".16b", 5467 [(set (v16i8 V128:$dst), 5468 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5469 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5470 asm, ".4h", 5471 [(set (v4i16 V64:$dst), 5472 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5473 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5474 asm, ".8h", 5475 [(set (v8i16 V128:$dst), 5476 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5477 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5478 asm, ".2s", 5479 [(set (v2i32 V64:$dst), 5480 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5481 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5482 asm, ".4s", 5483 [(set (v4i32 V128:$dst), 5484 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5485} 5486 5487// As above, but only B sized elements supported. 5488multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5489 SDPatternOperator OpNode> { 5490 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5491 asm, ".8b", 5492 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5493 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5494 asm, ".16b", 5495 [(set (v16i8 V128:$Rd), 5496 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5497} 5498 5499// As above, but only floating point elements supported. 5500multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5501 string asm, SDPatternOperator OpNode> { 5502 let Predicates = [HasNEON, HasFullFP16] in { 5503 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5504 asm, ".4h", 5505 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5506 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5507 asm, ".8h", 5508 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5509 } // Predicates = [HasNEON, HasFullFP16] 5510 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5511 asm, ".2s", 5512 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5513 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5514 asm, ".4s", 5515 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5516 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5517 asm, ".2d", 5518 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5519} 5520 5521multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5522 string asm, 5523 SDPatternOperator OpNode> { 5524 let Predicates = [HasNEON, HasFullFP16] in { 5525 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5526 asm, ".4h", 5527 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5528 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5529 asm, ".8h", 5530 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5531 } // Predicates = [HasNEON, HasFullFP16] 5532 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5533 asm, ".2s", 5534 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5535 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5536 asm, ".4s", 5537 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5538 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5539 asm, ".2d", 5540 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5541} 5542 5543multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5544 string asm, SDPatternOperator OpNode> { 5545 let Predicates = [HasNEON, HasFullFP16] in { 5546 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5547 asm, ".4h", 5548 [(set (v4f16 V64:$dst), 5549 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5550 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5551 asm, ".8h", 5552 [(set (v8f16 V128:$dst), 5553 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5554 } // Predicates = [HasNEON, HasFullFP16] 5555 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5556 asm, ".2s", 5557 [(set (v2f32 V64:$dst), 5558 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5559 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5560 asm, ".4s", 5561 [(set (v4f32 V128:$dst), 5562 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5563 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5564 asm, ".2d", 5565 [(set (v2f64 V128:$dst), 5566 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5567} 5568 5569// As above, but D and B sized elements unsupported. 5570multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5571 SDPatternOperator OpNode> { 5572 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5573 asm, ".4h", 5574 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5575 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5576 asm, ".8h", 5577 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5578 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5579 asm, ".2s", 5580 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5581 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5582 asm, ".4s", 5583 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5584} 5585 5586// Logical three vector ops share opcode bits, and only use B sized elements. 5587multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5588 SDPatternOperator OpNode = null_frag> { 5589 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5590 asm, ".8b", 5591 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5592 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5593 asm, ".16b", 5594 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5595 5596 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5597 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5598 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5599 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5600 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5601 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5602 5603 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5604 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5605 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5606 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5607 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5608 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5609} 5610 5611multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5612 string asm, SDPatternOperator OpNode = null_frag> { 5613 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5614 asm, ".8b", 5615 [(set (v8i8 V64:$dst), 5616 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5617 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5618 asm, ".16b", 5619 [(set (v16i8 V128:$dst), 5620 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5621 (v16i8 V128:$Rm)))]>; 5622 5623 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5624 (v4i16 V64:$RHS))), 5625 (!cast<Instruction>(NAME#"v8i8") 5626 V64:$LHS, V64:$MHS, V64:$RHS)>; 5627 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5628 (v2i32 V64:$RHS))), 5629 (!cast<Instruction>(NAME#"v8i8") 5630 V64:$LHS, V64:$MHS, V64:$RHS)>; 5631 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5632 (v1i64 V64:$RHS))), 5633 (!cast<Instruction>(NAME#"v8i8") 5634 V64:$LHS, V64:$MHS, V64:$RHS)>; 5635 5636 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5637 (v8i16 V128:$RHS))), 5638 (!cast<Instruction>(NAME#"v16i8") 5639 V128:$LHS, V128:$MHS, V128:$RHS)>; 5640 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5641 (v4i32 V128:$RHS))), 5642 (!cast<Instruction>(NAME#"v16i8") 5643 V128:$LHS, V128:$MHS, V128:$RHS)>; 5644 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5645 (v2i64 V128:$RHS))), 5646 (!cast<Instruction>(NAME#"v16i8") 5647 V128:$LHS, V128:$MHS, V128:$RHS)>; 5648} 5649 5650// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5651// bytes from S-sized elements. 5652class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5653 string kind2, RegisterOperand RegType, 5654 ValueType AccumType, ValueType InputType, 5655 SDPatternOperator OpNode> : 5656 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5657 [(set (AccumType RegType:$dst), 5658 (OpNode (AccumType RegType:$Rd), 5659 (InputType RegType:$Rn), 5660 (InputType RegType:$Rm)))]> { 5661 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5662} 5663 5664multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5665 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5666 v2i32, v8i8, OpNode>; 5667 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5668 v4i32, v16i8, OpNode>; 5669} 5670 5671// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5672// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5673// 8H to 4S, when Q=1). 5674class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5675 string kind2, RegisterOperand RegType, 5676 ValueType AccumType, ValueType InputType, 5677 SDPatternOperator OpNode> : 5678 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5679 [(set (AccumType RegType:$dst), 5680 (OpNode (AccumType RegType:$Rd), 5681 (InputType RegType:$Rn), 5682 (InputType RegType:$Rm)))]> { 5683 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5684 let Inst{13} = b13; 5685} 5686 5687multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5688 SDPatternOperator OpNode> { 5689 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5690 v2f32, v4f16, OpNode>; 5691 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5692 v4f32, v8f16, OpNode>; 5693} 5694 5695 5696//---------------------------------------------------------------------------- 5697// AdvSIMD two register vector instructions. 5698//---------------------------------------------------------------------------- 5699 5700let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5701class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5702 bits<2> size2, RegisterOperand regtype, string asm, 5703 string dstkind, string srckind, list<dag> pattern> 5704 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5705 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5706 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5707 Sched<[WriteV]> { 5708 bits<5> Rd; 5709 bits<5> Rn; 5710 let Inst{31} = 0; 5711 let Inst{30} = Q; 5712 let Inst{29} = U; 5713 let Inst{28-24} = 0b01110; 5714 let Inst{23-22} = size; 5715 let Inst{21} = 0b1; 5716 let Inst{20-19} = size2; 5717 let Inst{18-17} = 0b00; 5718 let Inst{16-12} = opcode; 5719 let Inst{11-10} = 0b10; 5720 let Inst{9-5} = Rn; 5721 let Inst{4-0} = Rd; 5722} 5723 5724let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5725class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5726 bits<2> size2, RegisterOperand regtype, 5727 string asm, string dstkind, string srckind, 5728 list<dag> pattern> 5729 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5730 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5731 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5732 Sched<[WriteV]> { 5733 bits<5> Rd; 5734 bits<5> Rn; 5735 let Inst{31} = 0; 5736 let Inst{30} = Q; 5737 let Inst{29} = U; 5738 let Inst{28-24} = 0b01110; 5739 let Inst{23-22} = size; 5740 let Inst{21} = 0b1; 5741 let Inst{20-19} = size2; 5742 let Inst{18-17} = 0b00; 5743 let Inst{16-12} = opcode; 5744 let Inst{11-10} = 0b10; 5745 let Inst{9-5} = Rn; 5746 let Inst{4-0} = Rd; 5747} 5748 5749// Supports B, H, and S element sizes. 5750multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5751 SDPatternOperator OpNode> { 5752 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5753 asm, ".8b", ".8b", 5754 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5755 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5756 asm, ".16b", ".16b", 5757 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5758 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5759 asm, ".4h", ".4h", 5760 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5761 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5762 asm, ".8h", ".8h", 5763 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5764 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5765 asm, ".2s", ".2s", 5766 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5767 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5768 asm, ".4s", ".4s", 5769 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5770} 5771 5772class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5773 RegisterOperand regtype, string asm, string dstkind, 5774 string srckind, string amount> 5775 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5776 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5777 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5778 Sched<[WriteV]> { 5779 bits<5> Rd; 5780 bits<5> Rn; 5781 let Inst{31} = 0; 5782 let Inst{30} = Q; 5783 let Inst{29-24} = 0b101110; 5784 let Inst{23-22} = size; 5785 let Inst{21-10} = 0b100001001110; 5786 let Inst{9-5} = Rn; 5787 let Inst{4-0} = Rd; 5788} 5789 5790multiclass SIMDVectorLShiftLongBySizeBHS { 5791 let hasSideEffects = 0 in { 5792 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5793 "shll", ".8h", ".8b", "8">; 5794 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5795 "shll2", ".8h", ".16b", "8">; 5796 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5797 "shll", ".4s", ".4h", "16">; 5798 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5799 "shll2", ".4s", ".8h", "16">; 5800 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5801 "shll", ".2d", ".2s", "32">; 5802 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5803 "shll2", ".2d", ".4s", "32">; 5804 } 5805} 5806 5807// Supports all element sizes. 5808multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5809 SDPatternOperator OpNode> { 5810 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5811 asm, ".4h", ".8b", 5812 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5813 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5814 asm, ".8h", ".16b", 5815 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5816 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5817 asm, ".2s", ".4h", 5818 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5819 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5820 asm, ".4s", ".8h", 5821 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5822 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5823 asm, ".1d", ".2s", 5824 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5825 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5826 asm, ".2d", ".4s", 5827 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5828} 5829 5830multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5831 SDPatternOperator OpNode> { 5832 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5833 asm, ".4h", ".8b", 5834 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5835 (v8i8 V64:$Rn)))]>; 5836 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5837 asm, ".8h", ".16b", 5838 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5839 (v16i8 V128:$Rn)))]>; 5840 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5841 asm, ".2s", ".4h", 5842 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5843 (v4i16 V64:$Rn)))]>; 5844 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5845 asm, ".4s", ".8h", 5846 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5847 (v8i16 V128:$Rn)))]>; 5848 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5849 asm, ".1d", ".2s", 5850 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5851 (v2i32 V64:$Rn)))]>; 5852 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5853 asm, ".2d", ".4s", 5854 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5855 (v4i32 V128:$Rn)))]>; 5856} 5857 5858// Supports all element sizes, except 1xD. 5859multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5860 SDPatternOperator OpNode> { 5861 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5862 asm, ".8b", ".8b", 5863 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5864 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5865 asm, ".16b", ".16b", 5866 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5867 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5868 asm, ".4h", ".4h", 5869 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5870 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5871 asm, ".8h", ".8h", 5872 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5873 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5874 asm, ".2s", ".2s", 5875 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5876 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5877 asm, ".4s", ".4s", 5878 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5879 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5880 asm, ".2d", ".2d", 5881 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5882} 5883 5884multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5885 SDPatternOperator OpNode = null_frag> { 5886 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5887 asm, ".8b", ".8b", 5888 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5889 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5890 asm, ".16b", ".16b", 5891 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5892 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5893 asm, ".4h", ".4h", 5894 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5895 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5896 asm, ".8h", ".8h", 5897 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5898 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5899 asm, ".2s", ".2s", 5900 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5901 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5902 asm, ".4s", ".4s", 5903 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5904 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5905 asm, ".2d", ".2d", 5906 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5907} 5908 5909 5910// Supports only B element sizes. 5911multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5912 SDPatternOperator OpNode> { 5913 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5914 asm, ".8b", ".8b", 5915 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5916 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5917 asm, ".16b", ".16b", 5918 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5919 5920} 5921 5922// Supports only B and H element sizes. 5923multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5924 SDPatternOperator OpNode> { 5925 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5926 asm, ".8b", ".8b", 5927 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5928 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5929 asm, ".16b", ".16b", 5930 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5931 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5932 asm, ".4h", ".4h", 5933 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5934 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5935 asm, ".8h", ".8h", 5936 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5937} 5938 5939// Supports H, S and D element sizes, uses high bit of the size field 5940// as an extra opcode bit. 5941multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5942 SDPatternOperator OpNode> { 5943 let Predicates = [HasNEON, HasFullFP16] in { 5944 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5945 asm, ".4h", ".4h", 5946 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5947 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5948 asm, ".8h", ".8h", 5949 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5950 } // Predicates = [HasNEON, HasFullFP16] 5951 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5952 asm, ".2s", ".2s", 5953 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5954 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5955 asm, ".4s", ".4s", 5956 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5957 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5958 asm, ".2d", ".2d", 5959 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5960} 5961 5962// Supports only S and D element sizes 5963multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 5964 SDPatternOperator OpNode = null_frag> { 5965 5966 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 5967 asm, ".2s", ".2s", 5968 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5969 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 5970 asm, ".4s", ".4s", 5971 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5972 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 5973 asm, ".2d", ".2d", 5974 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5975} 5976 5977multiclass FRIntNNTVector<bit U, bit op, string asm, 5978 SDPatternOperator OpNode = null_frag> : 5979 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 5980 5981// Supports only S element size. 5982multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 5983 SDPatternOperator OpNode> { 5984 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5985 asm, ".2s", ".2s", 5986 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5987 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5988 asm, ".4s", ".4s", 5989 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5990} 5991 5992 5993multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 5994 SDPatternOperator OpNode> { 5995 let Predicates = [HasNEON, HasFullFP16] in { 5996 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5997 asm, ".4h", ".4h", 5998 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5999 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6000 asm, ".8h", ".8h", 6001 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6002 } // Predicates = [HasNEON, HasFullFP16] 6003 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6004 asm, ".2s", ".2s", 6005 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6006 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6007 asm, ".4s", ".4s", 6008 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6009 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6010 asm, ".2d", ".2d", 6011 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6012} 6013 6014multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6015 SDPatternOperator OpNode> { 6016 let Predicates = [HasNEON, HasFullFP16] in { 6017 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6018 asm, ".4h", ".4h", 6019 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6020 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6021 asm, ".8h", ".8h", 6022 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6023 } // Predicates = [HasNEON, HasFullFP16] 6024 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6025 asm, ".2s", ".2s", 6026 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6027 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6028 asm, ".4s", ".4s", 6029 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6030 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6031 asm, ".2d", ".2d", 6032 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6033} 6034 6035 6036class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6037 RegisterOperand inreg, RegisterOperand outreg, 6038 string asm, string outkind, string inkind, 6039 list<dag> pattern> 6040 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6041 "{\t$Rd" # outkind # ", $Rn" # inkind # 6042 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6043 Sched<[WriteV]> { 6044 bits<5> Rd; 6045 bits<5> Rn; 6046 let Inst{31} = 0; 6047 let Inst{30} = Q; 6048 let Inst{29} = U; 6049 let Inst{28-24} = 0b01110; 6050 let Inst{23-22} = size; 6051 let Inst{21-17} = 0b10000; 6052 let Inst{16-12} = opcode; 6053 let Inst{11-10} = 0b10; 6054 let Inst{9-5} = Rn; 6055 let Inst{4-0} = Rd; 6056} 6057 6058class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6059 RegisterOperand inreg, RegisterOperand outreg, 6060 string asm, string outkind, string inkind, 6061 list<dag> pattern> 6062 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6063 "{\t$Rd" # outkind # ", $Rn" # inkind # 6064 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6065 Sched<[WriteV]> { 6066 bits<5> Rd; 6067 bits<5> Rn; 6068 let Inst{31} = 0; 6069 let Inst{30} = Q; 6070 let Inst{29} = U; 6071 let Inst{28-24} = 0b01110; 6072 let Inst{23-22} = size; 6073 let Inst{21-17} = 0b10000; 6074 let Inst{16-12} = opcode; 6075 let Inst{11-10} = 0b10; 6076 let Inst{9-5} = Rn; 6077 let Inst{4-0} = Rd; 6078} 6079 6080multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6081 SDPatternOperator OpNode> { 6082 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6083 asm, ".8b", ".8h", 6084 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6085 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6086 asm#"2", ".16b", ".8h", []>; 6087 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6088 asm, ".4h", ".4s", 6089 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6090 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6091 asm#"2", ".8h", ".4s", []>; 6092 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6093 asm, ".2s", ".2d", 6094 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6095 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6096 asm#"2", ".4s", ".2d", []>; 6097 6098 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6099 (!cast<Instruction>(NAME # "v16i8") 6100 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6101 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6102 (!cast<Instruction>(NAME # "v8i16") 6103 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6104 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6105 (!cast<Instruction>(NAME # "v4i32") 6106 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6107} 6108 6109class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6110 bits<5> opcode, RegisterOperand regtype, string asm, 6111 string kind, string zero, ValueType dty, 6112 ValueType sty, SDNode OpNode> 6113 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6114 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6115 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6116 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6117 Sched<[WriteV]> { 6118 bits<5> Rd; 6119 bits<5> Rn; 6120 let Inst{31} = 0; 6121 let Inst{30} = Q; 6122 let Inst{29} = U; 6123 let Inst{28-24} = 0b01110; 6124 let Inst{23-22} = size; 6125 let Inst{21} = 0b1; 6126 let Inst{20-19} = size2; 6127 let Inst{18-17} = 0b00; 6128 let Inst{16-12} = opcode; 6129 let Inst{11-10} = 0b10; 6130 let Inst{9-5} = Rn; 6131 let Inst{4-0} = Rd; 6132} 6133 6134// Comparisons support all element sizes, except 1xD. 6135multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6136 SDNode OpNode> { 6137 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6138 asm, ".8b", "0", 6139 v8i8, v8i8, OpNode>; 6140 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6141 asm, ".16b", "0", 6142 v16i8, v16i8, OpNode>; 6143 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6144 asm, ".4h", "0", 6145 v4i16, v4i16, OpNode>; 6146 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6147 asm, ".8h", "0", 6148 v8i16, v8i16, OpNode>; 6149 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6150 asm, ".2s", "0", 6151 v2i32, v2i32, OpNode>; 6152 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6153 asm, ".4s", "0", 6154 v4i32, v4i32, OpNode>; 6155 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6156 asm, ".2d", "0", 6157 v2i64, v2i64, OpNode>; 6158} 6159 6160// FP Comparisons support only S and D element sizes (and H for v8.2a). 6161multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6162 string asm, SDNode OpNode> { 6163 6164 let Predicates = [HasNEON, HasFullFP16] in { 6165 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6166 asm, ".4h", "0.0", 6167 v4i16, v4f16, OpNode>; 6168 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6169 asm, ".8h", "0.0", 6170 v8i16, v8f16, OpNode>; 6171 } // Predicates = [HasNEON, HasFullFP16] 6172 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6173 asm, ".2s", "0.0", 6174 v2i32, v2f32, OpNode>; 6175 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6176 asm, ".4s", "0.0", 6177 v4i32, v4f32, OpNode>; 6178 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6179 asm, ".2d", "0.0", 6180 v2i64, v2f64, OpNode>; 6181 6182 let Predicates = [HasNEON, HasFullFP16] in { 6183 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6184 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6185 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6186 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6187 } 6188 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6189 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6190 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6191 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6192 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6193 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6194 let Predicates = [HasNEON, HasFullFP16] in { 6195 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6196 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6197 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6198 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6199 } 6200 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6201 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6202 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6203 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6204 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6205 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6206} 6207 6208let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6209class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6210 RegisterOperand outtype, RegisterOperand intype, 6211 string asm, string VdTy, string VnTy, 6212 list<dag> pattern> 6213 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6214 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6215 Sched<[WriteV]> { 6216 bits<5> Rd; 6217 bits<5> Rn; 6218 let Inst{31} = 0; 6219 let Inst{30} = Q; 6220 let Inst{29} = U; 6221 let Inst{28-24} = 0b01110; 6222 let Inst{23-22} = size; 6223 let Inst{21-17} = 0b10000; 6224 let Inst{16-12} = opcode; 6225 let Inst{11-10} = 0b10; 6226 let Inst{9-5} = Rn; 6227 let Inst{4-0} = Rd; 6228} 6229 6230class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6231 RegisterOperand outtype, RegisterOperand intype, 6232 string asm, string VdTy, string VnTy, 6233 list<dag> pattern> 6234 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6235 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6236 Sched<[WriteV]> { 6237 bits<5> Rd; 6238 bits<5> Rn; 6239 let Inst{31} = 0; 6240 let Inst{30} = Q; 6241 let Inst{29} = U; 6242 let Inst{28-24} = 0b01110; 6243 let Inst{23-22} = size; 6244 let Inst{21-17} = 0b10000; 6245 let Inst{16-12} = opcode; 6246 let Inst{11-10} = 0b10; 6247 let Inst{9-5} = Rn; 6248 let Inst{4-0} = Rd; 6249} 6250 6251multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6252 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6253 asm, ".4s", ".4h", []>; 6254 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6255 asm#"2", ".4s", ".8h", []>; 6256 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6257 asm, ".2d", ".2s", []>; 6258 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6259 asm#"2", ".2d", ".4s", []>; 6260} 6261 6262multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6263 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6264 asm, ".4h", ".4s", []>; 6265 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6266 asm#"2", ".8h", ".4s", []>; 6267 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6268 asm, ".2s", ".2d", []>; 6269 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6270 asm#"2", ".4s", ".2d", []>; 6271} 6272 6273multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6274 Intrinsic OpNode> { 6275 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6276 asm, ".2s", ".2d", 6277 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6278 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6279 asm#"2", ".4s", ".2d", []>; 6280 6281 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6282 (!cast<Instruction>(NAME # "v4f32") 6283 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6284} 6285 6286//---------------------------------------------------------------------------- 6287// AdvSIMD three register different-size vector instructions. 6288//---------------------------------------------------------------------------- 6289 6290let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6291class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6292 RegisterOperand outtype, RegisterOperand intype1, 6293 RegisterOperand intype2, string asm, 6294 string outkind, string inkind1, string inkind2, 6295 list<dag> pattern> 6296 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6297 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6298 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6299 Sched<[WriteV]> { 6300 bits<5> Rd; 6301 bits<5> Rn; 6302 bits<5> Rm; 6303 let Inst{31} = 0; 6304 let Inst{30} = size{0}; 6305 let Inst{29} = U; 6306 let Inst{28-24} = 0b01110; 6307 let Inst{23-22} = size{2-1}; 6308 let Inst{21} = 1; 6309 let Inst{20-16} = Rm; 6310 let Inst{15-12} = opcode; 6311 let Inst{11-10} = 0b00; 6312 let Inst{9-5} = Rn; 6313 let Inst{4-0} = Rd; 6314} 6315 6316let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6317class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6318 RegisterOperand outtype, RegisterOperand intype1, 6319 RegisterOperand intype2, string asm, 6320 string outkind, string inkind1, string inkind2, 6321 list<dag> pattern> 6322 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6323 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6324 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6325 Sched<[WriteV]> { 6326 bits<5> Rd; 6327 bits<5> Rn; 6328 bits<5> Rm; 6329 let Inst{31} = 0; 6330 let Inst{30} = size{0}; 6331 let Inst{29} = U; 6332 let Inst{28-24} = 0b01110; 6333 let Inst{23-22} = size{2-1}; 6334 let Inst{21} = 1; 6335 let Inst{20-16} = Rm; 6336 let Inst{15-12} = opcode; 6337 let Inst{11-10} = 0b00; 6338 let Inst{9-5} = Rn; 6339 let Inst{4-0} = Rd; 6340} 6341 6342// FIXME: TableGen doesn't know how to deal with expanded types that also 6343// change the element count (in this case, placing the results in 6344// the high elements of the result register rather than the low 6345// elements). Until that's fixed, we can't code-gen those. 6346multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6347 Intrinsic IntOp> { 6348 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6349 V64, V128, V128, 6350 asm, ".8b", ".8h", ".8h", 6351 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6352 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6353 V128, V128, V128, 6354 asm#"2", ".16b", ".8h", ".8h", 6355 []>; 6356 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6357 V64, V128, V128, 6358 asm, ".4h", ".4s", ".4s", 6359 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6360 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6361 V128, V128, V128, 6362 asm#"2", ".8h", ".4s", ".4s", 6363 []>; 6364 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6365 V64, V128, V128, 6366 asm, ".2s", ".2d", ".2d", 6367 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6368 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6369 V128, V128, V128, 6370 asm#"2", ".4s", ".2d", ".2d", 6371 []>; 6372 6373 6374 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6375 // a version attached to an instruction. 6376 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6377 (v8i16 V128:$Rm))), 6378 (!cast<Instruction>(NAME # "v8i16_v16i8") 6379 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6380 V128:$Rn, V128:$Rm)>; 6381 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6382 (v4i32 V128:$Rm))), 6383 (!cast<Instruction>(NAME # "v4i32_v8i16") 6384 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6385 V128:$Rn, V128:$Rm)>; 6386 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6387 (v2i64 V128:$Rm))), 6388 (!cast<Instruction>(NAME # "v2i64_v4i32") 6389 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6390 V128:$Rn, V128:$Rm)>; 6391} 6392 6393multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6394 Intrinsic IntOp> { 6395 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6396 V128, V64, V64, 6397 asm, ".8h", ".8b", ".8b", 6398 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6399 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6400 V128, V128, V128, 6401 asm#"2", ".8h", ".16b", ".16b", []>; 6402 let Predicates = [HasAES] in { 6403 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6404 V128, V64, V64, 6405 asm, ".1q", ".1d", ".1d", []>; 6406 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6407 V128, V128, V128, 6408 asm#"2", ".1q", ".2d", ".2d", []>; 6409 } 6410 6411 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6412 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6413 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6414} 6415 6416multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6417 SDPatternOperator OpNode> { 6418 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6419 V128, V64, V64, 6420 asm, ".4s", ".4h", ".4h", 6421 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6422 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6423 V128, V128, V128, 6424 asm#"2", ".4s", ".8h", ".8h", 6425 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6426 (extract_high_v8i16 V128:$Rm)))]>; 6427 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6428 V128, V64, V64, 6429 asm, ".2d", ".2s", ".2s", 6430 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6431 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6432 V128, V128, V128, 6433 asm#"2", ".2d", ".4s", ".4s", 6434 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6435 (extract_high_v4i32 V128:$Rm)))]>; 6436} 6437 6438multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6439 SDPatternOperator OpNode = null_frag> { 6440 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6441 V128, V64, V64, 6442 asm, ".8h", ".8b", ".8b", 6443 [(set (v8i16 V128:$Rd), 6444 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6445 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6446 V128, V128, V128, 6447 asm#"2", ".8h", ".16b", ".16b", 6448 [(set (v8i16 V128:$Rd), 6449 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6450 (extract_high_v16i8 V128:$Rm)))))]>; 6451 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6452 V128, V64, V64, 6453 asm, ".4s", ".4h", ".4h", 6454 [(set (v4i32 V128:$Rd), 6455 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6456 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6457 V128, V128, V128, 6458 asm#"2", ".4s", ".8h", ".8h", 6459 [(set (v4i32 V128:$Rd), 6460 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6461 (extract_high_v8i16 V128:$Rm)))))]>; 6462 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6463 V128, V64, V64, 6464 asm, ".2d", ".2s", ".2s", 6465 [(set (v2i64 V128:$Rd), 6466 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6467 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6468 V128, V128, V128, 6469 asm#"2", ".2d", ".4s", ".4s", 6470 [(set (v2i64 V128:$Rd), 6471 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6472 (extract_high_v4i32 V128:$Rm)))))]>; 6473} 6474 6475multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6476 string asm, 6477 SDPatternOperator OpNode> { 6478 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6479 V128, V64, V64, 6480 asm, ".8h", ".8b", ".8b", 6481 [(set (v8i16 V128:$dst), 6482 (add (v8i16 V128:$Rd), 6483 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6484 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6485 V128, V128, V128, 6486 asm#"2", ".8h", ".16b", ".16b", 6487 [(set (v8i16 V128:$dst), 6488 (add (v8i16 V128:$Rd), 6489 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6490 (extract_high_v16i8 V128:$Rm))))))]>; 6491 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6492 V128, V64, V64, 6493 asm, ".4s", ".4h", ".4h", 6494 [(set (v4i32 V128:$dst), 6495 (add (v4i32 V128:$Rd), 6496 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6497 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6498 V128, V128, V128, 6499 asm#"2", ".4s", ".8h", ".8h", 6500 [(set (v4i32 V128:$dst), 6501 (add (v4i32 V128:$Rd), 6502 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6503 (extract_high_v8i16 V128:$Rm))))))]>; 6504 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6505 V128, V64, V64, 6506 asm, ".2d", ".2s", ".2s", 6507 [(set (v2i64 V128:$dst), 6508 (add (v2i64 V128:$Rd), 6509 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6510 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6511 V128, V128, V128, 6512 asm#"2", ".2d", ".4s", ".4s", 6513 [(set (v2i64 V128:$dst), 6514 (add (v2i64 V128:$Rd), 6515 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6516 (extract_high_v4i32 V128:$Rm))))))]>; 6517} 6518 6519multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6520 SDPatternOperator OpNode = null_frag> { 6521 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6522 V128, V64, V64, 6523 asm, ".8h", ".8b", ".8b", 6524 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6525 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6526 V128, V128, V128, 6527 asm#"2", ".8h", ".16b", ".16b", 6528 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6529 (extract_high_v16i8 V128:$Rm)))]>; 6530 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6531 V128, V64, V64, 6532 asm, ".4s", ".4h", ".4h", 6533 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6534 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6535 V128, V128, V128, 6536 asm#"2", ".4s", ".8h", ".8h", 6537 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6538 (extract_high_v8i16 V128:$Rm)))]>; 6539 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6540 V128, V64, V64, 6541 asm, ".2d", ".2s", ".2s", 6542 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6543 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6544 V128, V128, V128, 6545 asm#"2", ".2d", ".4s", ".4s", 6546 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6547 (extract_high_v4i32 V128:$Rm)))]>; 6548} 6549 6550multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6551 string asm, 6552 SDPatternOperator OpNode> { 6553 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6554 V128, V64, V64, 6555 asm, ".8h", ".8b", ".8b", 6556 [(set (v8i16 V128:$dst), 6557 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6558 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6559 V128, V128, V128, 6560 asm#"2", ".8h", ".16b", ".16b", 6561 [(set (v8i16 V128:$dst), 6562 (OpNode (v8i16 V128:$Rd), 6563 (extract_high_v16i8 V128:$Rn), 6564 (extract_high_v16i8 V128:$Rm)))]>; 6565 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6566 V128, V64, V64, 6567 asm, ".4s", ".4h", ".4h", 6568 [(set (v4i32 V128:$dst), 6569 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6570 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6571 V128, V128, V128, 6572 asm#"2", ".4s", ".8h", ".8h", 6573 [(set (v4i32 V128:$dst), 6574 (OpNode (v4i32 V128:$Rd), 6575 (extract_high_v8i16 V128:$Rn), 6576 (extract_high_v8i16 V128:$Rm)))]>; 6577 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6578 V128, V64, V64, 6579 asm, ".2d", ".2s", ".2s", 6580 [(set (v2i64 V128:$dst), 6581 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6582 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6583 V128, V128, V128, 6584 asm#"2", ".2d", ".4s", ".4s", 6585 [(set (v2i64 V128:$dst), 6586 (OpNode (v2i64 V128:$Rd), 6587 (extract_high_v4i32 V128:$Rn), 6588 (extract_high_v4i32 V128:$Rm)))]>; 6589} 6590 6591multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6592 SDPatternOperator Accum> { 6593 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6594 V128, V64, V64, 6595 asm, ".4s", ".4h", ".4h", 6596 [(set (v4i32 V128:$dst), 6597 (Accum (v4i32 V128:$Rd), 6598 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6599 (v4i16 V64:$Rm)))))]>; 6600 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6601 V128, V128, V128, 6602 asm#"2", ".4s", ".8h", ".8h", 6603 [(set (v4i32 V128:$dst), 6604 (Accum (v4i32 V128:$Rd), 6605 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6606 (extract_high_v8i16 V128:$Rm)))))]>; 6607 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6608 V128, V64, V64, 6609 asm, ".2d", ".2s", ".2s", 6610 [(set (v2i64 V128:$dst), 6611 (Accum (v2i64 V128:$Rd), 6612 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6613 (v2i32 V64:$Rm)))))]>; 6614 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6615 V128, V128, V128, 6616 asm#"2", ".2d", ".4s", ".4s", 6617 [(set (v2i64 V128:$dst), 6618 (Accum (v2i64 V128:$Rd), 6619 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6620 (extract_high_v4i32 V128:$Rm)))))]>; 6621} 6622 6623multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6624 SDPatternOperator OpNode> { 6625 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6626 V128, V128, V64, 6627 asm, ".8h", ".8h", ".8b", 6628 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6629 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6630 V128, V128, V128, 6631 asm#"2", ".8h", ".8h", ".16b", 6632 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6633 (extract_high_v16i8 V128:$Rm)))]>; 6634 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6635 V128, V128, V64, 6636 asm, ".4s", ".4s", ".4h", 6637 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6638 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6639 V128, V128, V128, 6640 asm#"2", ".4s", ".4s", ".8h", 6641 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6642 (extract_high_v8i16 V128:$Rm)))]>; 6643 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6644 V128, V128, V64, 6645 asm, ".2d", ".2d", ".2s", 6646 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6647 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6648 V128, V128, V128, 6649 asm#"2", ".2d", ".2d", ".4s", 6650 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6651 (extract_high_v4i32 V128:$Rm)))]>; 6652} 6653 6654//---------------------------------------------------------------------------- 6655// AdvSIMD bitwise extract from vector 6656//---------------------------------------------------------------------------- 6657 6658class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6659 string asm, string kind> 6660 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6661 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6662 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6663 [(set (vty regtype:$Rd), 6664 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6665 Sched<[WriteV]> { 6666 bits<5> Rd; 6667 bits<5> Rn; 6668 bits<5> Rm; 6669 bits<4> imm; 6670 let Inst{31} = 0; 6671 let Inst{30} = size; 6672 let Inst{29-21} = 0b101110000; 6673 let Inst{20-16} = Rm; 6674 let Inst{15} = 0; 6675 let Inst{14-11} = imm; 6676 let Inst{10} = 0; 6677 let Inst{9-5} = Rn; 6678 let Inst{4-0} = Rd; 6679} 6680 6681 6682multiclass SIMDBitwiseExtract<string asm> { 6683 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6684 let imm{3} = 0; 6685 } 6686 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6687} 6688 6689//---------------------------------------------------------------------------- 6690// AdvSIMD zip vector 6691//---------------------------------------------------------------------------- 6692 6693class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6694 string asm, string kind, SDNode OpNode, ValueType valty> 6695 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6696 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6697 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6698 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6699 Sched<[WriteV]> { 6700 bits<5> Rd; 6701 bits<5> Rn; 6702 bits<5> Rm; 6703 let Inst{31} = 0; 6704 let Inst{30} = size{0}; 6705 let Inst{29-24} = 0b001110; 6706 let Inst{23-22} = size{2-1}; 6707 let Inst{21} = 0; 6708 let Inst{20-16} = Rm; 6709 let Inst{15} = 0; 6710 let Inst{14-12} = opc; 6711 let Inst{11-10} = 0b10; 6712 let Inst{9-5} = Rn; 6713 let Inst{4-0} = Rd; 6714} 6715 6716multiclass SIMDZipVector<bits<3>opc, string asm, 6717 SDNode OpNode> { 6718 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6719 asm, ".8b", OpNode, v8i8>; 6720 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6721 asm, ".16b", OpNode, v16i8>; 6722 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6723 asm, ".4h", OpNode, v4i16>; 6724 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6725 asm, ".8h", OpNode, v8i16>; 6726 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6727 asm, ".2s", OpNode, v2i32>; 6728 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6729 asm, ".4s", OpNode, v4i32>; 6730 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6731 asm, ".2d", OpNode, v2i64>; 6732 6733 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6734 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6735 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6736 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6737 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6738 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6739 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6740 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6741 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6742 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6743} 6744 6745//---------------------------------------------------------------------------- 6746// AdvSIMD three register scalar instructions 6747//---------------------------------------------------------------------------- 6748 6749let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6750class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6751 RegisterClass regtype, string asm, 6752 list<dag> pattern> 6753 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6754 "\t$Rd, $Rn, $Rm", "", pattern>, 6755 Sched<[WriteV]> { 6756 bits<5> Rd; 6757 bits<5> Rn; 6758 bits<5> Rm; 6759 let Inst{31-30} = 0b01; 6760 let Inst{29} = U; 6761 let Inst{28-24} = 0b11110; 6762 let Inst{23-21} = size; 6763 let Inst{20-16} = Rm; 6764 let Inst{15-11} = opcode; 6765 let Inst{10} = 1; 6766 let Inst{9-5} = Rn; 6767 let Inst{4-0} = Rd; 6768} 6769 6770let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6771class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6772 dag oops, dag iops, string asm, 6773 list<dag> pattern> 6774 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6775 Sched<[WriteV]> { 6776 bits<5> Rd; 6777 bits<5> Rn; 6778 bits<5> Rm; 6779 let Inst{31-30} = 0b01; 6780 let Inst{29} = U; 6781 let Inst{28-24} = 0b11110; 6782 let Inst{23-22} = size; 6783 let Inst{21} = R; 6784 let Inst{20-16} = Rm; 6785 let Inst{15-11} = opcode; 6786 let Inst{10} = 1; 6787 let Inst{9-5} = Rn; 6788 let Inst{4-0} = Rd; 6789} 6790 6791multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6792 SDPatternOperator OpNode> { 6793 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6794 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6795} 6796 6797multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6798 SDPatternOperator OpNode> { 6799 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6800 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6801 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6802 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6803 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6804 6805 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6806 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6807 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6808 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6809} 6810 6811multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6812 SDPatternOperator OpNode> { 6813 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6814 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6815 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6816} 6817 6818multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 6819 SDPatternOperator OpNode = null_frag> { 6820 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6821 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6822 asm, []>; 6823 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6824 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6825 asm, []>; 6826} 6827 6828multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6829 SDPatternOperator OpNode = null_frag> { 6830 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6831 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6832 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6833 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6834 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6835 let Predicates = [HasNEON, HasFullFP16] in { 6836 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6837 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6838 } // Predicates = [HasNEON, HasFullFP16] 6839 } 6840 6841 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6842 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6843} 6844 6845multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6846 SDPatternOperator OpNode = null_frag> { 6847 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6848 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6849 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6850 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6851 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6852 let Predicates = [HasNEON, HasFullFP16] in { 6853 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6854 []>; 6855 } // Predicates = [HasNEON, HasFullFP16] 6856 } 6857 6858 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6859 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6860} 6861 6862class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6863 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6864 : I<oops, iops, asm, 6865 "\t$Rd, $Rn, $Rm", cstr, pat>, 6866 Sched<[WriteV]> { 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-22} = size; 6874 let Inst{21} = 1; 6875 let Inst{20-16} = Rm; 6876 let Inst{15-11} = opcode; 6877 let Inst{10} = 0; 6878 let Inst{9-5} = Rn; 6879 let Inst{4-0} = Rd; 6880} 6881 6882let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6883multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6884 SDPatternOperator OpNode = null_frag> { 6885 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6886 (outs FPR32:$Rd), 6887 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6888 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6889 (outs FPR64:$Rd), 6890 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6891 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6892} 6893 6894let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6895multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6896 SDPatternOperator OpNode = null_frag> { 6897 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6898 (outs FPR32:$dst), 6899 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6900 asm, "$Rd = $dst", []>; 6901 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6902 (outs FPR64:$dst), 6903 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6904 asm, "$Rd = $dst", 6905 [(set (i64 FPR64:$dst), 6906 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6907} 6908 6909//---------------------------------------------------------------------------- 6910// AdvSIMD two register scalar instructions 6911//---------------------------------------------------------------------------- 6912 6913let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6914class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6915 RegisterClass regtype, RegisterClass regtype2, 6916 string asm, list<dag> pat> 6917 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6918 "\t$Rd, $Rn", "", pat>, 6919 Sched<[WriteV]> { 6920 bits<5> Rd; 6921 bits<5> Rn; 6922 let Inst{31-30} = 0b01; 6923 let Inst{29} = U; 6924 let Inst{28-24} = 0b11110; 6925 let Inst{23-22} = size; 6926 let Inst{21} = 0b1; 6927 let Inst{20-19} = size2; 6928 let Inst{18-17} = 0b00; 6929 let Inst{16-12} = opcode; 6930 let Inst{11-10} = 0b10; 6931 let Inst{9-5} = Rn; 6932 let Inst{4-0} = Rd; 6933} 6934 6935let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6936class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6937 RegisterClass regtype, RegisterClass regtype2, 6938 string asm, list<dag> pat> 6939 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6940 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6941 Sched<[WriteV]> { 6942 bits<5> Rd; 6943 bits<5> Rn; 6944 let Inst{31-30} = 0b01; 6945 let Inst{29} = U; 6946 let Inst{28-24} = 0b11110; 6947 let Inst{23-22} = size; 6948 let Inst{21-17} = 0b10000; 6949 let Inst{16-12} = opcode; 6950 let Inst{11-10} = 0b10; 6951 let Inst{9-5} = Rn; 6952 let Inst{4-0} = Rd; 6953} 6954 6955 6956let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6957class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6958 RegisterClass regtype, string asm, string zero> 6959 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6960 "\t$Rd, $Rn, #" # zero, "", []>, 6961 Sched<[WriteV]> { 6962 bits<5> Rd; 6963 bits<5> Rn; 6964 let Inst{31-30} = 0b01; 6965 let Inst{29} = U; 6966 let Inst{28-24} = 0b11110; 6967 let Inst{23-22} = size; 6968 let Inst{21} = 0b1; 6969 let Inst{20-19} = size2; 6970 let Inst{18-17} = 0b00; 6971 let Inst{16-12} = opcode; 6972 let Inst{11-10} = 0b10; 6973 let Inst{9-5} = Rn; 6974 let Inst{4-0} = Rd; 6975} 6976 6977class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 6978 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 6979 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 6980 Sched<[WriteV]> { 6981 bits<5> Rd; 6982 bits<5> Rn; 6983 let Inst{31-17} = 0b011111100110000; 6984 let Inst{16-12} = opcode; 6985 let Inst{11-10} = 0b10; 6986 let Inst{9-5} = Rn; 6987 let Inst{4-0} = Rd; 6988} 6989 6990multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 6991 SDPatternOperator OpNode> { 6992 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 6993 6994 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 6995 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6996} 6997 6998multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 6999 SDPatternOperator OpNode> { 7000 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7001 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7002 let Predicates = [HasNEON, HasFullFP16] in { 7003 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7004 } 7005 7006 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7007 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7008 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7009 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7010 let Predicates = [HasNEON, HasFullFP16] in { 7011 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7012 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7013 } 7014 7015 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7016 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7017} 7018 7019multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7020 SDPatternOperator OpNode = null_frag> { 7021 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7022 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7023 7024 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7025 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7026} 7027 7028multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 7029 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7030 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7031 let Predicates = [HasNEON, HasFullFP16] in { 7032 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7033 } 7034} 7035 7036multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7037 SDPatternOperator OpNode> { 7038 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7039 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7040 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7041 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7042 let Predicates = [HasNEON, HasFullFP16] in { 7043 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7044 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7045 } 7046} 7047 7048multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7049 SDPatternOperator OpNode = null_frag> { 7050 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7051 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7052 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7053 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7054 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7055 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7056 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7057 } 7058 7059 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7060 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7061} 7062 7063multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7064 Intrinsic OpNode> { 7065 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7066 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7067 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7068 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7069 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7070 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7071 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7072 } 7073 7074 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7075 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7076} 7077 7078 7079 7080let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7081multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7082 SDPatternOperator OpNode = null_frag> { 7083 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7084 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7085 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7086 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7087} 7088 7089//---------------------------------------------------------------------------- 7090// AdvSIMD scalar pairwise instructions 7091//---------------------------------------------------------------------------- 7092 7093let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7094class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7095 RegisterOperand regtype, RegisterOperand vectype, 7096 string asm, string kind> 7097 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7098 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7099 Sched<[WriteV]> { 7100 bits<5> Rd; 7101 bits<5> Rn; 7102 let Inst{31-30} = 0b01; 7103 let Inst{29} = U; 7104 let Inst{28-24} = 0b11110; 7105 let Inst{23-22} = size; 7106 let Inst{21-17} = 0b11000; 7107 let Inst{16-12} = opcode; 7108 let Inst{11-10} = 0b10; 7109 let Inst{9-5} = Rn; 7110 let Inst{4-0} = Rd; 7111} 7112 7113multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7114 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7115 asm, ".2d">; 7116} 7117 7118multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7119 let Predicates = [HasNEON, HasFullFP16] in { 7120 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7121 asm, ".2h">; 7122 } 7123 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7124 asm, ".2s">; 7125 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7126 asm, ".2d">; 7127} 7128 7129//---------------------------------------------------------------------------- 7130// AdvSIMD across lanes instructions 7131//---------------------------------------------------------------------------- 7132 7133let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7134class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7135 RegisterClass regtype, RegisterOperand vectype, 7136 string asm, string kind, list<dag> pattern> 7137 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7138 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7139 Sched<[WriteV]> { 7140 bits<5> Rd; 7141 bits<5> Rn; 7142 let Inst{31} = 0; 7143 let Inst{30} = Q; 7144 let Inst{29} = U; 7145 let Inst{28-24} = 0b01110; 7146 let Inst{23-22} = size; 7147 let Inst{21-17} = 0b11000; 7148 let Inst{16-12} = opcode; 7149 let Inst{11-10} = 0b10; 7150 let Inst{9-5} = Rn; 7151 let Inst{4-0} = Rd; 7152} 7153 7154multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7155 string asm> { 7156 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7157 asm, ".8b", []>; 7158 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7159 asm, ".16b", []>; 7160 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7161 asm, ".4h", []>; 7162 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7163 asm, ".8h", []>; 7164 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7165 asm, ".4s", []>; 7166} 7167 7168multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7169 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7170 asm, ".8b", []>; 7171 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7172 asm, ".16b", []>; 7173 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7174 asm, ".4h", []>; 7175 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7176 asm, ".8h", []>; 7177 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7178 asm, ".4s", []>; 7179} 7180 7181multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7182 Intrinsic intOp> { 7183 let Predicates = [HasNEON, HasFullFP16] in { 7184 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7185 asm, ".4h", 7186 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7187 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7188 asm, ".8h", 7189 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7190 } // Predicates = [HasNEON, HasFullFP16] 7191 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7192 asm, ".4s", 7193 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7194} 7195 7196//---------------------------------------------------------------------------- 7197// AdvSIMD INS/DUP instructions 7198//---------------------------------------------------------------------------- 7199 7200// FIXME: There has got to be a better way to factor these. ugh. 7201 7202class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7203 string operands, string constraints, list<dag> pattern> 7204 : I<outs, ins, asm, operands, constraints, pattern>, 7205 Sched<[WriteV]> { 7206 bits<5> Rd; 7207 bits<5> Rn; 7208 let Inst{31} = 0; 7209 let Inst{30} = Q; 7210 let Inst{29} = op; 7211 let Inst{28-21} = 0b01110000; 7212 let Inst{15} = 0; 7213 let Inst{10} = 1; 7214 let Inst{9-5} = Rn; 7215 let Inst{4-0} = Rd; 7216} 7217 7218class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7219 RegisterOperand vecreg, RegisterClass regtype> 7220 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7221 "{\t$Rd" # size # ", $Rn" # 7222 "|" # size # "\t$Rd, $Rn}", "", 7223 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7224 let Inst{20-16} = imm5; 7225 let Inst{14-11} = 0b0001; 7226} 7227 7228class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7229 ValueType vectype, ValueType insreg, 7230 RegisterOperand vecreg, Operand idxtype, 7231 ValueType elttype, SDNode OpNode> 7232 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7233 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7234 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7235 [(set (vectype vecreg:$Rd), 7236 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7237 let Inst{14-11} = 0b0000; 7238} 7239 7240class SIMDDup64FromElement 7241 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7242 VectorIndexD, i64, AArch64duplane64> { 7243 bits<1> idx; 7244 let Inst{20} = idx; 7245 let Inst{19-16} = 0b1000; 7246} 7247 7248class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7249 RegisterOperand vecreg> 7250 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7251 VectorIndexS, i64, AArch64duplane32> { 7252 bits<2> idx; 7253 let Inst{20-19} = idx; 7254 let Inst{18-16} = 0b100; 7255} 7256 7257class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7258 RegisterOperand vecreg> 7259 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7260 VectorIndexH, i64, AArch64duplane16> { 7261 bits<3> idx; 7262 let Inst{20-18} = idx; 7263 let Inst{17-16} = 0b10; 7264} 7265 7266class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7267 RegisterOperand vecreg> 7268 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7269 VectorIndexB, i64, AArch64duplane8> { 7270 bits<4> idx; 7271 let Inst{20-17} = idx; 7272 let Inst{16} = 1; 7273} 7274 7275class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7276 Operand idxtype, string asm, list<dag> pattern> 7277 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7278 "{\t$Rd, $Rn" # size # "$idx" # 7279 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7280 let Inst{14-11} = imm4; 7281} 7282 7283class SIMDSMov<bit Q, string size, RegisterClass regtype, 7284 Operand idxtype> 7285 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7286class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7287 Operand idxtype> 7288 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7289 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7290 7291class SIMDMovAlias<string asm, string size, Instruction inst, 7292 RegisterClass regtype, Operand idxtype> 7293 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7294 "|" # size # "\t$dst, $src$idx}", 7295 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7296 7297multiclass SMov { 7298 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7299 bits<4> idx; 7300 let Inst{20-17} = idx; 7301 let Inst{16} = 1; 7302 } 7303 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7304 bits<4> idx; 7305 let Inst{20-17} = idx; 7306 let Inst{16} = 1; 7307 } 7308 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7309 bits<3> idx; 7310 let Inst{20-18} = idx; 7311 let Inst{17-16} = 0b10; 7312 } 7313 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7314 bits<3> idx; 7315 let Inst{20-18} = idx; 7316 let Inst{17-16} = 0b10; 7317 } 7318 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7319 bits<2> idx; 7320 let Inst{20-19} = idx; 7321 let Inst{18-16} = 0b100; 7322 } 7323} 7324 7325multiclass UMov { 7326 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7327 bits<4> idx; 7328 let Inst{20-17} = idx; 7329 let Inst{16} = 1; 7330 } 7331 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7332 bits<3> idx; 7333 let Inst{20-18} = idx; 7334 let Inst{17-16} = 0b10; 7335 } 7336 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7337 bits<2> idx; 7338 let Inst{20-19} = idx; 7339 let Inst{18-16} = 0b100; 7340 } 7341 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7342 bits<1> idx; 7343 let Inst{20} = idx; 7344 let Inst{19-16} = 0b1000; 7345 } 7346 def : SIMDMovAlias<"mov", ".s", 7347 !cast<Instruction>(NAME#"vi32"), 7348 GPR32, VectorIndexS>; 7349 def : SIMDMovAlias<"mov", ".d", 7350 !cast<Instruction>(NAME#"vi64"), 7351 GPR64, VectorIndexD>; 7352} 7353 7354class SIMDInsFromMain<string size, ValueType vectype, 7355 RegisterClass regtype, Operand idxtype> 7356 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7357 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7358 "{\t$Rd" # size # "$idx, $Rn" # 7359 "|" # size # "\t$Rd$idx, $Rn}", 7360 "$Rd = $dst", 7361 [(set V128:$dst, 7362 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7363 let Inst{14-11} = 0b0011; 7364} 7365 7366class SIMDInsFromElement<string size, ValueType vectype, 7367 ValueType elttype, Operand idxtype> 7368 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7369 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7370 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7371 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7372 "$Rd = $dst", 7373 [(set V128:$dst, 7374 (vector_insert 7375 (vectype V128:$Rd), 7376 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7377 idxtype:$idx))]>; 7378 7379class SIMDInsMainMovAlias<string size, Instruction inst, 7380 RegisterClass regtype, Operand idxtype> 7381 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7382 "|" # size #"\t$dst$idx, $src}", 7383 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7384class SIMDInsElementMovAlias<string size, Instruction inst, 7385 Operand idxtype> 7386 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7387 # "|" # size #"\t$dst$idx, $src$idx2}", 7388 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7389 7390 7391multiclass SIMDIns { 7392 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7393 bits<4> idx; 7394 let Inst{20-17} = idx; 7395 let Inst{16} = 1; 7396 } 7397 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7398 bits<3> idx; 7399 let Inst{20-18} = idx; 7400 let Inst{17-16} = 0b10; 7401 } 7402 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7403 bits<2> idx; 7404 let Inst{20-19} = idx; 7405 let Inst{18-16} = 0b100; 7406 } 7407 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7408 bits<1> idx; 7409 let Inst{20} = idx; 7410 let Inst{19-16} = 0b1000; 7411 } 7412 7413 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7414 bits<4> idx; 7415 bits<4> idx2; 7416 let Inst{20-17} = idx; 7417 let Inst{16} = 1; 7418 let Inst{14-11} = idx2; 7419 } 7420 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7421 bits<3> idx; 7422 bits<3> idx2; 7423 let Inst{20-18} = idx; 7424 let Inst{17-16} = 0b10; 7425 let Inst{14-12} = idx2; 7426 let Inst{11} = {?}; 7427 } 7428 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7429 bits<2> idx; 7430 bits<2> idx2; 7431 let Inst{20-19} = idx; 7432 let Inst{18-16} = 0b100; 7433 let Inst{14-13} = idx2; 7434 let Inst{12-11} = {?,?}; 7435 } 7436 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7437 bits<1> idx; 7438 bits<1> idx2; 7439 let Inst{20} = idx; 7440 let Inst{19-16} = 0b1000; 7441 let Inst{14} = idx2; 7442 let Inst{13-11} = {?,?,?}; 7443 } 7444 7445 // For all forms of the INS instruction, the "mov" mnemonic is the 7446 // preferred alias. Why they didn't just call the instruction "mov" in 7447 // the first place is a very good question indeed... 7448 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7449 GPR32, VectorIndexB>; 7450 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7451 GPR32, VectorIndexH>; 7452 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7453 GPR32, VectorIndexS>; 7454 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7455 GPR64, VectorIndexD>; 7456 7457 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7458 VectorIndexB>; 7459 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7460 VectorIndexH>; 7461 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7462 VectorIndexS>; 7463 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7464 VectorIndexD>; 7465} 7466 7467//---------------------------------------------------------------------------- 7468// AdvSIMD TBL/TBX 7469//---------------------------------------------------------------------------- 7470 7471let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7472class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7473 RegisterOperand listtype, string asm, string kind> 7474 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7475 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7476 Sched<[WriteV]> { 7477 bits<5> Vd; 7478 bits<5> Vn; 7479 bits<5> Vm; 7480 let Inst{31} = 0; 7481 let Inst{30} = Q; 7482 let Inst{29-21} = 0b001110000; 7483 let Inst{20-16} = Vm; 7484 let Inst{15} = 0; 7485 let Inst{14-13} = len; 7486 let Inst{12} = op; 7487 let Inst{11-10} = 0b00; 7488 let Inst{9-5} = Vn; 7489 let Inst{4-0} = Vd; 7490} 7491 7492let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7493class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7494 RegisterOperand listtype, string asm, string kind> 7495 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7496 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7497 Sched<[WriteV]> { 7498 bits<5> Vd; 7499 bits<5> Vn; 7500 bits<5> Vm; 7501 let Inst{31} = 0; 7502 let Inst{30} = Q; 7503 let Inst{29-21} = 0b001110000; 7504 let Inst{20-16} = Vm; 7505 let Inst{15} = 0; 7506 let Inst{14-13} = len; 7507 let Inst{12} = op; 7508 let Inst{11-10} = 0b00; 7509 let Inst{9-5} = Vn; 7510 let Inst{4-0} = Vd; 7511} 7512 7513class SIMDTableLookupAlias<string asm, Instruction inst, 7514 RegisterOperand vectype, RegisterOperand listtype> 7515 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7516 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7517 7518multiclass SIMDTableLookup<bit op, string asm> { 7519 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7520 asm, ".8b">; 7521 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7522 asm, ".8b">; 7523 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7524 asm, ".8b">; 7525 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7526 asm, ".8b">; 7527 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7528 asm, ".16b">; 7529 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7530 asm, ".16b">; 7531 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7532 asm, ".16b">; 7533 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7534 asm, ".16b">; 7535 7536 def : SIMDTableLookupAlias<asm # ".8b", 7537 !cast<Instruction>(NAME#"v8i8One"), 7538 V64, VecListOne128>; 7539 def : SIMDTableLookupAlias<asm # ".8b", 7540 !cast<Instruction>(NAME#"v8i8Two"), 7541 V64, VecListTwo128>; 7542 def : SIMDTableLookupAlias<asm # ".8b", 7543 !cast<Instruction>(NAME#"v8i8Three"), 7544 V64, VecListThree128>; 7545 def : SIMDTableLookupAlias<asm # ".8b", 7546 !cast<Instruction>(NAME#"v8i8Four"), 7547 V64, VecListFour128>; 7548 def : SIMDTableLookupAlias<asm # ".16b", 7549 !cast<Instruction>(NAME#"v16i8One"), 7550 V128, VecListOne128>; 7551 def : SIMDTableLookupAlias<asm # ".16b", 7552 !cast<Instruction>(NAME#"v16i8Two"), 7553 V128, VecListTwo128>; 7554 def : SIMDTableLookupAlias<asm # ".16b", 7555 !cast<Instruction>(NAME#"v16i8Three"), 7556 V128, VecListThree128>; 7557 def : SIMDTableLookupAlias<asm # ".16b", 7558 !cast<Instruction>(NAME#"v16i8Four"), 7559 V128, VecListFour128>; 7560} 7561 7562multiclass SIMDTableLookupTied<bit op, string asm> { 7563 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7564 asm, ".8b">; 7565 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7566 asm, ".8b">; 7567 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7568 asm, ".8b">; 7569 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7570 asm, ".8b">; 7571 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7572 asm, ".16b">; 7573 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7574 asm, ".16b">; 7575 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7576 asm, ".16b">; 7577 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7578 asm, ".16b">; 7579 7580 def : SIMDTableLookupAlias<asm # ".8b", 7581 !cast<Instruction>(NAME#"v8i8One"), 7582 V64, VecListOne128>; 7583 def : SIMDTableLookupAlias<asm # ".8b", 7584 !cast<Instruction>(NAME#"v8i8Two"), 7585 V64, VecListTwo128>; 7586 def : SIMDTableLookupAlias<asm # ".8b", 7587 !cast<Instruction>(NAME#"v8i8Three"), 7588 V64, VecListThree128>; 7589 def : SIMDTableLookupAlias<asm # ".8b", 7590 !cast<Instruction>(NAME#"v8i8Four"), 7591 V64, VecListFour128>; 7592 def : SIMDTableLookupAlias<asm # ".16b", 7593 !cast<Instruction>(NAME#"v16i8One"), 7594 V128, VecListOne128>; 7595 def : SIMDTableLookupAlias<asm # ".16b", 7596 !cast<Instruction>(NAME#"v16i8Two"), 7597 V128, VecListTwo128>; 7598 def : SIMDTableLookupAlias<asm # ".16b", 7599 !cast<Instruction>(NAME#"v16i8Three"), 7600 V128, VecListThree128>; 7601 def : SIMDTableLookupAlias<asm # ".16b", 7602 !cast<Instruction>(NAME#"v16i8Four"), 7603 V128, VecListFour128>; 7604} 7605 7606 7607//---------------------------------------------------------------------------- 7608// AdvSIMD scalar CPY 7609//---------------------------------------------------------------------------- 7610let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7611class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 7612 string kind, Operand idxtype> 7613 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 7614 "{\t$dst, $src" # kind # "$idx" # 7615 "|\t$dst, $src$idx}", "", []>, 7616 Sched<[WriteV]> { 7617 bits<5> dst; 7618 bits<5> src; 7619 let Inst{31-21} = 0b01011110000; 7620 let Inst{15-10} = 0b000001; 7621 let Inst{9-5} = src; 7622 let Inst{4-0} = dst; 7623} 7624 7625class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 7626 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7627 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7628 # "|\t$dst, $src$index}", 7629 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7630 7631 7632multiclass SIMDScalarCPY<string asm> { 7633 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 7634 bits<4> idx; 7635 let Inst{20-17} = idx; 7636 let Inst{16} = 1; 7637 } 7638 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 7639 bits<3> idx; 7640 let Inst{20-18} = idx; 7641 let Inst{17-16} = 0b10; 7642 } 7643 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 7644 bits<2> idx; 7645 let Inst{20-19} = idx; 7646 let Inst{18-16} = 0b100; 7647 } 7648 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 7649 bits<1> idx; 7650 let Inst{20} = idx; 7651 let Inst{19-16} = 0b1000; 7652 } 7653 7654 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7655 VectorIndexD:$idx)))), 7656 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7657 7658 // 'DUP' mnemonic aliases. 7659 def : SIMDScalarCPYAlias<"dup", ".b", 7660 !cast<Instruction>(NAME#"i8"), 7661 FPR8, V128, VectorIndexB>; 7662 def : SIMDScalarCPYAlias<"dup", ".h", 7663 !cast<Instruction>(NAME#"i16"), 7664 FPR16, V128, VectorIndexH>; 7665 def : SIMDScalarCPYAlias<"dup", ".s", 7666 !cast<Instruction>(NAME#"i32"), 7667 FPR32, V128, VectorIndexS>; 7668 def : SIMDScalarCPYAlias<"dup", ".d", 7669 !cast<Instruction>(NAME#"i64"), 7670 FPR64, V128, VectorIndexD>; 7671} 7672 7673//---------------------------------------------------------------------------- 7674// AdvSIMD modified immediate instructions 7675//---------------------------------------------------------------------------- 7676 7677class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7678 string asm, string op_string, 7679 string cstr, list<dag> pattern> 7680 : I<oops, iops, asm, op_string, cstr, pattern>, 7681 Sched<[WriteV]> { 7682 bits<5> Rd; 7683 bits<8> imm8; 7684 let Inst{31} = 0; 7685 let Inst{30} = Q; 7686 let Inst{29} = op; 7687 let Inst{28-19} = 0b0111100000; 7688 let Inst{18-16} = imm8{7-5}; 7689 let Inst{11} = op2; 7690 let Inst{10} = 1; 7691 let Inst{9-5} = imm8{4-0}; 7692 let Inst{4-0} = Rd; 7693} 7694 7695class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7696 Operand immtype, dag opt_shift_iop, 7697 string opt_shift, string asm, string kind, 7698 list<dag> pattern> 7699 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7700 !con((ins immtype:$imm8), opt_shift_iop), asm, 7701 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7702 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7703 "", pattern> { 7704 let DecoderMethod = "DecodeModImmInstruction"; 7705} 7706 7707class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7708 Operand immtype, dag opt_shift_iop, 7709 string opt_shift, string asm, string kind, 7710 list<dag> pattern> 7711 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7712 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7713 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7714 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7715 "$Rd = $dst", pattern> { 7716 let DecoderMethod = "DecodeModImmTiedInstruction"; 7717} 7718 7719class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7720 RegisterOperand vectype, string asm, 7721 string kind, list<dag> pattern> 7722 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7723 (ins logical_vec_shift:$shift), 7724 "$shift", asm, kind, pattern> { 7725 bits<2> shift; 7726 let Inst{15} = b15_b12{1}; 7727 let Inst{14-13} = shift; 7728 let Inst{12} = b15_b12{0}; 7729} 7730 7731class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7732 RegisterOperand vectype, string asm, 7733 string kind, list<dag> pattern> 7734 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7735 (ins logical_vec_shift:$shift), 7736 "$shift", asm, kind, pattern> { 7737 bits<2> shift; 7738 let Inst{15} = b15_b12{1}; 7739 let Inst{14-13} = shift; 7740 let Inst{12} = b15_b12{0}; 7741} 7742 7743 7744class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7745 RegisterOperand vectype, string asm, 7746 string kind, list<dag> pattern> 7747 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7748 (ins logical_vec_hw_shift:$shift), 7749 "$shift", asm, kind, pattern> { 7750 bits<2> shift; 7751 let Inst{15} = b15_b12{1}; 7752 let Inst{14} = 0; 7753 let Inst{13} = shift{0}; 7754 let Inst{12} = b15_b12{0}; 7755} 7756 7757class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7758 RegisterOperand vectype, string asm, 7759 string kind, list<dag> pattern> 7760 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7761 (ins logical_vec_hw_shift:$shift), 7762 "$shift", asm, kind, pattern> { 7763 bits<2> shift; 7764 let Inst{15} = b15_b12{1}; 7765 let Inst{14} = 0; 7766 let Inst{13} = shift{0}; 7767 let Inst{12} = b15_b12{0}; 7768} 7769 7770multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7771 string asm> { 7772 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7773 asm, ".4h", []>; 7774 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7775 asm, ".8h", []>; 7776 7777 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7778 asm, ".2s", []>; 7779 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7780 asm, ".4s", []>; 7781} 7782 7783multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7784 bits<2> w_cmode, string asm, 7785 SDNode OpNode> { 7786 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7787 asm, ".4h", 7788 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7789 imm0_255:$imm8, 7790 (i32 imm:$shift)))]>; 7791 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7792 asm, ".8h", 7793 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7794 imm0_255:$imm8, 7795 (i32 imm:$shift)))]>; 7796 7797 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7798 asm, ".2s", 7799 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7800 imm0_255:$imm8, 7801 (i32 imm:$shift)))]>; 7802 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7803 asm, ".4s", 7804 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7805 imm0_255:$imm8, 7806 (i32 imm:$shift)))]>; 7807} 7808 7809class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7810 RegisterOperand vectype, string asm, 7811 string kind, list<dag> pattern> 7812 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7813 (ins move_vec_shift:$shift), 7814 "$shift", asm, kind, pattern> { 7815 bits<1> shift; 7816 let Inst{15-13} = cmode{3-1}; 7817 let Inst{12} = shift; 7818} 7819 7820class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7821 RegisterOperand vectype, 7822 Operand imm_type, string asm, 7823 string kind, list<dag> pattern> 7824 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7825 asm, kind, pattern> { 7826 let Inst{15-12} = cmode; 7827} 7828 7829class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7830 list<dag> pattern> 7831 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7832 "\t$Rd, $imm8", "", pattern> { 7833 let Inst{15-12} = cmode; 7834 let DecoderMethod = "DecodeModImmInstruction"; 7835} 7836 7837//---------------------------------------------------------------------------- 7838// AdvSIMD indexed element 7839//---------------------------------------------------------------------------- 7840 7841let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7842class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7843 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7844 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7845 string apple_kind, string dst_kind, string lhs_kind, 7846 string rhs_kind, list<dag> pattern> 7847 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7848 asm, 7849 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7850 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7851 Sched<[WriteV]> { 7852 bits<5> Rd; 7853 bits<5> Rn; 7854 bits<5> Rm; 7855 7856 let Inst{31} = 0; 7857 let Inst{30} = Q; 7858 let Inst{29} = U; 7859 let Inst{28} = Scalar; 7860 let Inst{27-24} = 0b1111; 7861 let Inst{23-22} = size; 7862 // Bit 21 must be set by the derived class. 7863 let Inst{20-16} = Rm; 7864 let Inst{15-12} = opc; 7865 // Bit 11 must be set by the derived class. 7866 let Inst{10} = 0; 7867 let Inst{9-5} = Rn; 7868 let Inst{4-0} = Rd; 7869} 7870 7871let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7872class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7873 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7874 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7875 string apple_kind, string dst_kind, string lhs_kind, 7876 string rhs_kind, list<dag> pattern> 7877 : I<(outs dst_reg:$dst), 7878 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7879 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7880 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7881 Sched<[WriteV]> { 7882 bits<5> Rd; 7883 bits<5> Rn; 7884 bits<5> Rm; 7885 7886 let Inst{31} = 0; 7887 let Inst{30} = Q; 7888 let Inst{29} = U; 7889 let Inst{28} = Scalar; 7890 let Inst{27-24} = 0b1111; 7891 let Inst{23-22} = size; 7892 // Bit 21 must be set by the derived class. 7893 let Inst{20-16} = Rm; 7894 let Inst{15-12} = opc; 7895 // Bit 11 must be set by the derived class. 7896 let Inst{10} = 0; 7897 let Inst{9-5} = Rn; 7898 let Inst{4-0} = Rd; 7899} 7900 7901 7902//---------------------------------------------------------------------------- 7903// Armv8.6 BFloat16 Extension 7904//---------------------------------------------------------------------------- 7905let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 7906 7907class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 7908 string kind2, RegisterOperand RegType, 7909 ValueType AccumType, ValueType InputType> 7910 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 7911 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 7912 (InputType RegType:$Rn), 7913 (InputType RegType:$Rm)))]> { 7914 let AsmString = !strconcat(asm, 7915 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 7916 ", $Rm" # kind2 # "}"); 7917} 7918 7919multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 7920 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 7921 v2f32, v4bf16>; 7922 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 7923 v4f32, v8bf16>; 7924} 7925 7926class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 7927 string dst_kind, string lhs_kind, 7928 string rhs_kind, 7929 RegisterOperand RegType, 7930 ValueType AccumType, 7931 ValueType InputType> 7932 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 7933 RegType, RegType, V128, VectorIndexS, 7934 asm, "", dst_kind, lhs_kind, rhs_kind, 7935 [(set (AccumType RegType:$dst), 7936 (AccumType (int_aarch64_neon_bfdot 7937 (AccumType RegType:$Rd), 7938 (InputType RegType:$Rn), 7939 (InputType (bitconvert (AccumType 7940 (AArch64duplane32 (v4f32 V128:$Rm), 7941 VectorIndexS:$idx)))))))]> { 7942 7943 bits<2> idx; 7944 let Inst{21} = idx{0}; // L 7945 let Inst{11} = idx{1}; // H 7946} 7947 7948multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 7949 7950 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 7951 ".2h", V64, v2f32, v4bf16>; 7952 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 7953 ".2h", V128, v4f32, v8bf16>; 7954} 7955 7956class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 7957 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 7958 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 7959 (v8bf16 V128:$Rn), 7960 (v8bf16 V128:$Rm)))]> { 7961 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 7962} 7963 7964class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 7965 : I<(outs V128:$dst), 7966 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 7967 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 7968 [(set (v4f32 V128:$dst), 7969 (v4f32 (OpNode (v4f32 V128:$Rd), 7970 (v8bf16 V128:$Rn), 7971 (v8bf16 7972 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 7973 VectorIndexH:$idx)))))]>, 7974 Sched<[WriteV]> { 7975 bits<5> Rd; 7976 bits<5> Rn; 7977 bits<4> Rm; 7978 bits<3> idx; 7979 7980 let Inst{31} = 0; 7981 let Inst{30} = Q; 7982 let Inst{29-22} = 0b00111111; 7983 let Inst{21-20} = idx{1-0}; 7984 let Inst{19-16} = Rm; 7985 let Inst{15-12} = 0b1111; 7986 let Inst{11} = idx{2}; // H 7987 let Inst{10} = 0; 7988 let Inst{9-5} = Rn; 7989 let Inst{4-0} = Rd; 7990} 7991 7992class SIMDThreeSameVectorBF16MatrixMul<string asm> 7993 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 7994 V128, asm, ".4s", 7995 [(set (v4f32 V128:$dst), 7996 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 7997 (v8bf16 V128:$Rn), 7998 (v8bf16 V128:$Rm)))]> { 7999 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8000 ", $Rm", ".8h", "}"); 8001} 8002 8003class SIMD_BFCVTN 8004 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8005 "bfcvtn", ".4h", ".4s", 8006 [(set (v8bf16 V128:$Rd), 8007 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8008 8009class SIMD_BFCVTN2 8010 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8011 "bfcvtn2", ".8h", ".4s", 8012 [(set (v8bf16 V128:$dst), 8013 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8014 8015class BF16ToSinglePrecision<string asm> 8016 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8017 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8018 Sched<[WriteFCvt]> { 8019 bits<5> Rd; 8020 bits<5> Rn; 8021 let Inst{31-10} = 0b0001111001100011010000; 8022 let Inst{9-5} = Rn; 8023 let Inst{4-0} = Rd; 8024} 8025} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8026 8027//---------------------------------------------------------------------------- 8028// Armv8.6 Matrix Multiply Extension 8029//---------------------------------------------------------------------------- 8030 8031class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8032 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8033 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8034 (v16i8 V128:$Rn), 8035 (v16i8 V128:$Rm)))]> { 8036 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8037} 8038 8039//---------------------------------------------------------------------------- 8040// ARMv8.2-A Dot Product Instructions (Indexed) 8041class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8042 string dst_kind, string lhs_kind, string rhs_kind, 8043 RegisterOperand RegType, 8044 ValueType AccumType, ValueType InputType, 8045 SDPatternOperator OpNode> : 8046 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8047 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8048 [(set (AccumType RegType:$dst), 8049 (AccumType (OpNode (AccumType RegType:$Rd), 8050 (InputType RegType:$Rn), 8051 (InputType (bitconvert (AccumType 8052 (AArch64duplane32 (v4i32 V128:$Rm), 8053 VectorIndexS:$idx)))))))]> { 8054 bits<2> idx; 8055 let Inst{21} = idx{0}; // L 8056 let Inst{11} = idx{1}; // H 8057} 8058 8059multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8060 SDPatternOperator OpNode> { 8061 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8062 V64, v2i32, v8i8, OpNode>; 8063 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8064 V128, v4i32, v16i8, OpNode>; 8065} 8066 8067// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8068class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8069 string dst_kind, string lhs_kind, 8070 string rhs_kind, RegisterOperand RegType, 8071 ValueType AccumType, ValueType InputType, 8072 SDPatternOperator OpNode> : 8073 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8074 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8075 [(set (AccumType RegType:$dst), 8076 (AccumType (OpNode (AccumType RegType:$Rd), 8077 (InputType RegType:$Rn), 8078 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8079 VectorIndexH:$idx)))))]> { 8080 // idx = H:L:M 8081 bits<3> idx; 8082 let Inst{11} = idx{2}; // H 8083 let Inst{21} = idx{1}; // L 8084 let Inst{20} = idx{0}; // M 8085} 8086 8087multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8088 SDPatternOperator OpNode> { 8089 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8090 V64, v2f32, v4f16, OpNode>; 8091 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8092 V128, v4f32, v8f16, OpNode>; 8093} 8094 8095multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8096 SDPatternOperator OpNode> { 8097 let Predicates = [HasNEON, HasFullFP16] in { 8098 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8099 V64, V64, 8100 V128_lo, VectorIndexH, 8101 asm, ".4h", ".4h", ".4h", ".h", 8102 [(set (v4f16 V64:$Rd), 8103 (OpNode (v4f16 V64:$Rn), 8104 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8105 bits<3> idx; 8106 let Inst{11} = idx{2}; 8107 let Inst{21} = idx{1}; 8108 let Inst{20} = idx{0}; 8109 } 8110 8111 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8112 V128, V128, 8113 V128_lo, VectorIndexH, 8114 asm, ".8h", ".8h", ".8h", ".h", 8115 [(set (v8f16 V128:$Rd), 8116 (OpNode (v8f16 V128:$Rn), 8117 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8118 bits<3> idx; 8119 let Inst{11} = idx{2}; 8120 let Inst{21} = idx{1}; 8121 let Inst{20} = idx{0}; 8122 } 8123 } // Predicates = [HasNEON, HasFullFP16] 8124 8125 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8126 V64, V64, 8127 V128, VectorIndexS, 8128 asm, ".2s", ".2s", ".2s", ".s", 8129 [(set (v2f32 V64:$Rd), 8130 (OpNode (v2f32 V64:$Rn), 8131 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8132 bits<2> idx; 8133 let Inst{11} = idx{1}; 8134 let Inst{21} = idx{0}; 8135 } 8136 8137 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8138 V128, V128, 8139 V128, VectorIndexS, 8140 asm, ".4s", ".4s", ".4s", ".s", 8141 [(set (v4f32 V128:$Rd), 8142 (OpNode (v4f32 V128:$Rn), 8143 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8144 bits<2> idx; 8145 let Inst{11} = idx{1}; 8146 let Inst{21} = idx{0}; 8147 } 8148 8149 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8150 V128, V128, 8151 V128, VectorIndexD, 8152 asm, ".2d", ".2d", ".2d", ".d", 8153 [(set (v2f64 V128:$Rd), 8154 (OpNode (v2f64 V128:$Rn), 8155 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8156 bits<1> idx; 8157 let Inst{11} = idx{0}; 8158 let Inst{21} = 0; 8159 } 8160 8161 let Predicates = [HasNEON, HasFullFP16] in { 8162 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8163 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8164 asm, ".h", "", "", ".h", 8165 [(set (f16 FPR16Op:$Rd), 8166 (OpNode (f16 FPR16Op:$Rn), 8167 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8168 VectorIndexH:$idx))))]> { 8169 bits<3> idx; 8170 let Inst{11} = idx{2}; 8171 let Inst{21} = idx{1}; 8172 let Inst{20} = idx{0}; 8173 } 8174 } // Predicates = [HasNEON, HasFullFP16] 8175 8176 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8177 FPR32Op, FPR32Op, V128, VectorIndexS, 8178 asm, ".s", "", "", ".s", 8179 [(set (f32 FPR32Op:$Rd), 8180 (OpNode (f32 FPR32Op:$Rn), 8181 (f32 (vector_extract (v4f32 V128:$Rm), 8182 VectorIndexS:$idx))))]> { 8183 bits<2> idx; 8184 let Inst{11} = idx{1}; 8185 let Inst{21} = idx{0}; 8186 } 8187 8188 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8189 FPR64Op, FPR64Op, V128, VectorIndexD, 8190 asm, ".d", "", "", ".d", 8191 [(set (f64 FPR64Op:$Rd), 8192 (OpNode (f64 FPR64Op:$Rn), 8193 (f64 (vector_extract (v2f64 V128:$Rm), 8194 VectorIndexD:$idx))))]> { 8195 bits<1> idx; 8196 let Inst{11} = idx{0}; 8197 let Inst{21} = 0; 8198 } 8199} 8200 8201multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8202 let Predicates = [HasNEON, HasFullFP16] in { 8203 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8204 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8205 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8206 VectorIndexH:$idx))), 8207 (!cast<Instruction>(INST # "v8i16_indexed") 8208 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8209 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8210 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8211 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8212 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8213 8214 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8215 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8216 VectorIndexH:$idx))), 8217 (!cast<Instruction>(INST # "v4i16_indexed") 8218 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8219 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8220 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8221 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8222 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8223 8224 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8225 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8226 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8227 V128_lo:$Rm, VectorIndexH:$idx)>; 8228 } // Predicates = [HasNEON, HasFullFP16] 8229 8230 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8231 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8232 (AArch64duplane32 (v4f32 V128:$Rm), 8233 VectorIndexS:$idx))), 8234 (!cast<Instruction>(INST # v2i32_indexed) 8235 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8236 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8237 (AArch64dup (f32 FPR32Op:$Rm)))), 8238 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8239 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8240 8241 8242 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8243 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8244 (AArch64duplane32 (v4f32 V128:$Rm), 8245 VectorIndexS:$idx))), 8246 (!cast<Instruction>(INST # "v4i32_indexed") 8247 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8248 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8249 (AArch64dup (f32 FPR32Op:$Rm)))), 8250 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8251 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8252 8253 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8254 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8255 (AArch64duplane64 (v2f64 V128:$Rm), 8256 VectorIndexD:$idx))), 8257 (!cast<Instruction>(INST # "v2i64_indexed") 8258 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8259 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8260 (AArch64dup (f64 FPR64Op:$Rm)))), 8261 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8262 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8263 8264 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8265 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8266 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8267 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8268 V128:$Rm, VectorIndexS:$idx)>; 8269 8270 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8271 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8272 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8273 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8274 V128:$Rm, VectorIndexD:$idx)>; 8275} 8276 8277multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8278 let Predicates = [HasNEON, HasFullFP16] in { 8279 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8280 V128_lo, VectorIndexH, 8281 asm, ".4h", ".4h", ".4h", ".h", []> { 8282 bits<3> idx; 8283 let Inst{11} = idx{2}; 8284 let Inst{21} = idx{1}; 8285 let Inst{20} = idx{0}; 8286 } 8287 8288 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8289 V128, V128, 8290 V128_lo, VectorIndexH, 8291 asm, ".8h", ".8h", ".8h", ".h", []> { 8292 bits<3> idx; 8293 let Inst{11} = idx{2}; 8294 let Inst{21} = idx{1}; 8295 let Inst{20} = idx{0}; 8296 } 8297 } // Predicates = [HasNEON, HasFullFP16] 8298 8299 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8300 V128, VectorIndexS, 8301 asm, ".2s", ".2s", ".2s", ".s", []> { 8302 bits<2> idx; 8303 let Inst{11} = idx{1}; 8304 let Inst{21} = idx{0}; 8305 } 8306 8307 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8308 V128, V128, 8309 V128, VectorIndexS, 8310 asm, ".4s", ".4s", ".4s", ".s", []> { 8311 bits<2> idx; 8312 let Inst{11} = idx{1}; 8313 let Inst{21} = idx{0}; 8314 } 8315 8316 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8317 V128, V128, 8318 V128, VectorIndexD, 8319 asm, ".2d", ".2d", ".2d", ".d", []> { 8320 bits<1> idx; 8321 let Inst{11} = idx{0}; 8322 let Inst{21} = 0; 8323 } 8324 8325 let Predicates = [HasNEON, HasFullFP16] in { 8326 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8327 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8328 asm, ".h", "", "", ".h", []> { 8329 bits<3> idx; 8330 let Inst{11} = idx{2}; 8331 let Inst{21} = idx{1}; 8332 let Inst{20} = idx{0}; 8333 } 8334 } // Predicates = [HasNEON, HasFullFP16] 8335 8336 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8337 FPR32Op, FPR32Op, V128, VectorIndexS, 8338 asm, ".s", "", "", ".s", []> { 8339 bits<2> idx; 8340 let Inst{11} = idx{1}; 8341 let Inst{21} = idx{0}; 8342 } 8343 8344 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8345 FPR64Op, FPR64Op, V128, VectorIndexD, 8346 asm, ".d", "", "", ".d", []> { 8347 bits<1> idx; 8348 let Inst{11} = idx{0}; 8349 let Inst{21} = 0; 8350 } 8351} 8352 8353multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8354 SDPatternOperator OpNodeLaneQ> { 8355 8356 def : Pat<(v4i16 (OpNodeLane 8357 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8358 VectorIndexS32b:$idx)), 8359 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8360 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8361 (UImmS1XForm $idx))>; 8362 8363 def : Pat<(v4i16 (OpNodeLaneQ 8364 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8365 VectorIndexH32b:$idx)), 8366 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8367 (UImmS1XForm $idx))>; 8368 8369 def : Pat<(v8i16 (OpNodeLane 8370 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8371 VectorIndexS32b:$idx)), 8372 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8373 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8374 (UImmS1XForm $idx))>; 8375 8376 def : Pat<(v8i16 (OpNodeLaneQ 8377 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8378 VectorIndexH32b:$idx)), 8379 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8380 (UImmS1XForm $idx))>; 8381 8382 def : Pat<(v2i32 (OpNodeLane 8383 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8384 VectorIndexD32b:$idx)), 8385 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8386 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8387 (UImmS1XForm $idx))>; 8388 8389 def : Pat<(v2i32 (OpNodeLaneQ 8390 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8391 VectorIndexS32b:$idx)), 8392 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8393 (UImmS1XForm $idx))>; 8394 8395 def : Pat<(v4i32 (OpNodeLane 8396 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8397 VectorIndexD32b:$idx)), 8398 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8399 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8400 (UImmS1XForm $idx))>; 8401 8402 def : Pat<(v4i32 (OpNodeLaneQ 8403 (v4i32 V128:$Rn), 8404 (v4i32 V128:$Rm), 8405 VectorIndexS32b:$idx)), 8406 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8407 (UImmS1XForm $idx))>; 8408 8409} 8410 8411multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8412 SDPatternOperator OpNode> { 8413 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8414 V128_lo, VectorIndexH, 8415 asm, ".4h", ".4h", ".4h", ".h", 8416 [(set (v4i16 V64:$Rd), 8417 (OpNode (v4i16 V64:$Rn), 8418 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8419 bits<3> idx; 8420 let Inst{11} = idx{2}; 8421 let Inst{21} = idx{1}; 8422 let Inst{20} = idx{0}; 8423 } 8424 8425 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8426 V128, V128, 8427 V128_lo, VectorIndexH, 8428 asm, ".8h", ".8h", ".8h", ".h", 8429 [(set (v8i16 V128:$Rd), 8430 (OpNode (v8i16 V128:$Rn), 8431 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8432 bits<3> idx; 8433 let Inst{11} = idx{2}; 8434 let Inst{21} = idx{1}; 8435 let Inst{20} = idx{0}; 8436 } 8437 8438 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8439 V64, V64, 8440 V128, VectorIndexS, 8441 asm, ".2s", ".2s", ".2s", ".s", 8442 [(set (v2i32 V64:$Rd), 8443 (OpNode (v2i32 V64:$Rn), 8444 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8445 bits<2> idx; 8446 let Inst{11} = idx{1}; 8447 let Inst{21} = idx{0}; 8448 } 8449 8450 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8451 V128, V128, 8452 V128, VectorIndexS, 8453 asm, ".4s", ".4s", ".4s", ".s", 8454 [(set (v4i32 V128:$Rd), 8455 (OpNode (v4i32 V128:$Rn), 8456 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8457 bits<2> idx; 8458 let Inst{11} = idx{1}; 8459 let Inst{21} = idx{0}; 8460 } 8461 8462 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8463 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8464 asm, ".h", "", "", ".h", []> { 8465 bits<3> idx; 8466 let Inst{11} = idx{2}; 8467 let Inst{21} = idx{1}; 8468 let Inst{20} = idx{0}; 8469 } 8470 8471 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8472 FPR32Op, FPR32Op, V128, VectorIndexS, 8473 asm, ".s", "", "", ".s", 8474 [(set (i32 FPR32Op:$Rd), 8475 (OpNode FPR32Op:$Rn, 8476 (i32 (vector_extract (v4i32 V128:$Rm), 8477 VectorIndexS:$idx))))]> { 8478 bits<2> idx; 8479 let Inst{11} = idx{1}; 8480 let Inst{21} = idx{0}; 8481 } 8482} 8483 8484multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8485 SDPatternOperator OpNode> { 8486 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8487 V64, V64, 8488 V128_lo, VectorIndexH, 8489 asm, ".4h", ".4h", ".4h", ".h", 8490 [(set (v4i16 V64:$Rd), 8491 (OpNode (v4i16 V64:$Rn), 8492 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8493 bits<3> idx; 8494 let Inst{11} = idx{2}; 8495 let Inst{21} = idx{1}; 8496 let Inst{20} = idx{0}; 8497 } 8498 8499 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8500 V128, V128, 8501 V128_lo, VectorIndexH, 8502 asm, ".8h", ".8h", ".8h", ".h", 8503 [(set (v8i16 V128:$Rd), 8504 (OpNode (v8i16 V128:$Rn), 8505 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8506 bits<3> idx; 8507 let Inst{11} = idx{2}; 8508 let Inst{21} = idx{1}; 8509 let Inst{20} = idx{0}; 8510 } 8511 8512 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8513 V64, V64, 8514 V128, VectorIndexS, 8515 asm, ".2s", ".2s", ".2s", ".s", 8516 [(set (v2i32 V64:$Rd), 8517 (OpNode (v2i32 V64:$Rn), 8518 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8519 bits<2> idx; 8520 let Inst{11} = idx{1}; 8521 let Inst{21} = idx{0}; 8522 } 8523 8524 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8525 V128, V128, 8526 V128, VectorIndexS, 8527 asm, ".4s", ".4s", ".4s", ".s", 8528 [(set (v4i32 V128:$Rd), 8529 (OpNode (v4i32 V128:$Rn), 8530 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8531 bits<2> idx; 8532 let Inst{11} = idx{1}; 8533 let Inst{21} = idx{0}; 8534 } 8535} 8536 8537multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8538 SDPatternOperator OpNode> { 8539 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8540 V128_lo, VectorIndexH, 8541 asm, ".4h", ".4h", ".4h", ".h", 8542 [(set (v4i16 V64:$dst), 8543 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8544 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8545 bits<3> idx; 8546 let Inst{11} = idx{2}; 8547 let Inst{21} = idx{1}; 8548 let Inst{20} = idx{0}; 8549 } 8550 8551 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8552 V128, V128, 8553 V128_lo, VectorIndexH, 8554 asm, ".8h", ".8h", ".8h", ".h", 8555 [(set (v8i16 V128:$dst), 8556 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8557 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8558 bits<3> idx; 8559 let Inst{11} = idx{2}; 8560 let Inst{21} = idx{1}; 8561 let Inst{20} = idx{0}; 8562 } 8563 8564 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8565 V64, V64, 8566 V128, VectorIndexS, 8567 asm, ".2s", ".2s", ".2s", ".s", 8568 [(set (v2i32 V64:$dst), 8569 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8570 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8571 bits<2> idx; 8572 let Inst{11} = idx{1}; 8573 let Inst{21} = idx{0}; 8574 } 8575 8576 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8577 V128, V128, 8578 V128, VectorIndexS, 8579 asm, ".4s", ".4s", ".4s", ".s", 8580 [(set (v4i32 V128:$dst), 8581 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8582 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8583 bits<2> idx; 8584 let Inst{11} = idx{1}; 8585 let Inst{21} = idx{0}; 8586 } 8587} 8588 8589multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8590 SDPatternOperator OpNode> { 8591 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8592 V128, V64, 8593 V128_lo, VectorIndexH, 8594 asm, ".4s", ".4s", ".4h", ".h", 8595 [(set (v4i32 V128:$Rd), 8596 (OpNode (v4i16 V64:$Rn), 8597 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8598 bits<3> idx; 8599 let Inst{11} = idx{2}; 8600 let Inst{21} = idx{1}; 8601 let Inst{20} = idx{0}; 8602 } 8603 8604 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8605 V128, V128, 8606 V128_lo, VectorIndexH, 8607 asm#"2", ".4s", ".4s", ".8h", ".h", 8608 [(set (v4i32 V128:$Rd), 8609 (OpNode (extract_high_v8i16 V128:$Rn), 8610 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8611 VectorIndexH:$idx))))]> { 8612 8613 bits<3> idx; 8614 let Inst{11} = idx{2}; 8615 let Inst{21} = idx{1}; 8616 let Inst{20} = idx{0}; 8617 } 8618 8619 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8620 V128, V64, 8621 V128, VectorIndexS, 8622 asm, ".2d", ".2d", ".2s", ".s", 8623 [(set (v2i64 V128:$Rd), 8624 (OpNode (v2i32 V64:$Rn), 8625 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8626 bits<2> idx; 8627 let Inst{11} = idx{1}; 8628 let Inst{21} = idx{0}; 8629 } 8630 8631 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8632 V128, V128, 8633 V128, VectorIndexS, 8634 asm#"2", ".2d", ".2d", ".4s", ".s", 8635 [(set (v2i64 V128:$Rd), 8636 (OpNode (extract_high_v4i32 V128:$Rn), 8637 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8638 VectorIndexS:$idx))))]> { 8639 bits<2> idx; 8640 let Inst{11} = idx{1}; 8641 let Inst{21} = idx{0}; 8642 } 8643 8644 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8645 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8646 asm, ".h", "", "", ".h", []> { 8647 bits<3> idx; 8648 let Inst{11} = idx{2}; 8649 let Inst{21} = idx{1}; 8650 let Inst{20} = idx{0}; 8651 } 8652 8653 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8654 FPR64Op, FPR32Op, V128, VectorIndexS, 8655 asm, ".s", "", "", ".s", []> { 8656 bits<2> idx; 8657 let Inst{11} = idx{1}; 8658 let Inst{21} = idx{0}; 8659 } 8660} 8661 8662multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8663 SDPatternOperator Accum> { 8664 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8665 V128, V64, 8666 V128_lo, VectorIndexH, 8667 asm, ".4s", ".4s", ".4h", ".h", 8668 [(set (v4i32 V128:$dst), 8669 (Accum (v4i32 V128:$Rd), 8670 (v4i32 (int_aarch64_neon_sqdmull 8671 (v4i16 V64:$Rn), 8672 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8673 VectorIndexH:$idx))))))]> { 8674 bits<3> idx; 8675 let Inst{11} = idx{2}; 8676 let Inst{21} = idx{1}; 8677 let Inst{20} = idx{0}; 8678 } 8679 8680 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8681 // intermediate EXTRACT_SUBREG would be untyped. 8682 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8683 (i32 (vector_extract (v4i32 8684 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8685 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8686 VectorIndexH:$idx)))), 8687 (i64 0))))), 8688 (EXTRACT_SUBREG 8689 (!cast<Instruction>(NAME # v4i16_indexed) 8690 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8691 V128_lo:$Rm, VectorIndexH:$idx), 8692 ssub)>; 8693 8694 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8695 V128, V128, 8696 V128_lo, VectorIndexH, 8697 asm#"2", ".4s", ".4s", ".8h", ".h", 8698 [(set (v4i32 V128:$dst), 8699 (Accum (v4i32 V128:$Rd), 8700 (v4i32 (int_aarch64_neon_sqdmull 8701 (extract_high_v8i16 V128:$Rn), 8702 (extract_high_v8i16 8703 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8704 VectorIndexH:$idx))))))]> { 8705 bits<3> idx; 8706 let Inst{11} = idx{2}; 8707 let Inst{21} = idx{1}; 8708 let Inst{20} = idx{0}; 8709 } 8710 8711 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8712 V128, V64, 8713 V128, VectorIndexS, 8714 asm, ".2d", ".2d", ".2s", ".s", 8715 [(set (v2i64 V128:$dst), 8716 (Accum (v2i64 V128:$Rd), 8717 (v2i64 (int_aarch64_neon_sqdmull 8718 (v2i32 V64:$Rn), 8719 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8720 VectorIndexS:$idx))))))]> { 8721 bits<2> idx; 8722 let Inst{11} = idx{1}; 8723 let Inst{21} = idx{0}; 8724 } 8725 8726 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8727 V128, V128, 8728 V128, VectorIndexS, 8729 asm#"2", ".2d", ".2d", ".4s", ".s", 8730 [(set (v2i64 V128:$dst), 8731 (Accum (v2i64 V128:$Rd), 8732 (v2i64 (int_aarch64_neon_sqdmull 8733 (extract_high_v4i32 V128:$Rn), 8734 (extract_high_v4i32 8735 (AArch64duplane32 (v4i32 V128:$Rm), 8736 VectorIndexS:$idx))))))]> { 8737 bits<2> idx; 8738 let Inst{11} = idx{1}; 8739 let Inst{21} = idx{0}; 8740 } 8741 8742 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8743 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8744 asm, ".h", "", "", ".h", []> { 8745 bits<3> idx; 8746 let Inst{11} = idx{2}; 8747 let Inst{21} = idx{1}; 8748 let Inst{20} = idx{0}; 8749 } 8750 8751 8752 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8753 FPR64Op, FPR32Op, V128, VectorIndexS, 8754 asm, ".s", "", "", ".s", 8755 [(set (i64 FPR64Op:$dst), 8756 (Accum (i64 FPR64Op:$Rd), 8757 (i64 (int_aarch64_neon_sqdmulls_scalar 8758 (i32 FPR32Op:$Rn), 8759 (i32 (vector_extract (v4i32 V128:$Rm), 8760 VectorIndexS:$idx))))))]> { 8761 8762 bits<2> idx; 8763 let Inst{11} = idx{1}; 8764 let Inst{21} = idx{0}; 8765 } 8766} 8767 8768multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8769 SDPatternOperator OpNode> { 8770 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8771 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8772 V128, V64, 8773 V128_lo, VectorIndexH, 8774 asm, ".4s", ".4s", ".4h", ".h", 8775 [(set (v4i32 V128:$Rd), 8776 (OpNode (v4i16 V64:$Rn), 8777 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8778 bits<3> idx; 8779 let Inst{11} = idx{2}; 8780 let Inst{21} = idx{1}; 8781 let Inst{20} = idx{0}; 8782 } 8783 8784 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8785 V128, V128, 8786 V128_lo, VectorIndexH, 8787 asm#"2", ".4s", ".4s", ".8h", ".h", 8788 [(set (v4i32 V128:$Rd), 8789 (OpNode (extract_high_v8i16 V128:$Rn), 8790 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8791 VectorIndexH:$idx))))]> { 8792 8793 bits<3> idx; 8794 let Inst{11} = idx{2}; 8795 let Inst{21} = idx{1}; 8796 let Inst{20} = idx{0}; 8797 } 8798 8799 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8800 V128, V64, 8801 V128, VectorIndexS, 8802 asm, ".2d", ".2d", ".2s", ".s", 8803 [(set (v2i64 V128:$Rd), 8804 (OpNode (v2i32 V64:$Rn), 8805 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8806 bits<2> idx; 8807 let Inst{11} = idx{1}; 8808 let Inst{21} = idx{0}; 8809 } 8810 8811 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8812 V128, V128, 8813 V128, VectorIndexS, 8814 asm#"2", ".2d", ".2d", ".4s", ".s", 8815 [(set (v2i64 V128:$Rd), 8816 (OpNode (extract_high_v4i32 V128:$Rn), 8817 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8818 VectorIndexS:$idx))))]> { 8819 bits<2> idx; 8820 let Inst{11} = idx{1}; 8821 let Inst{21} = idx{0}; 8822 } 8823 } 8824} 8825 8826multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8827 SDPatternOperator OpNode> { 8828 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8829 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8830 V128, V64, 8831 V128_lo, VectorIndexH, 8832 asm, ".4s", ".4s", ".4h", ".h", 8833 [(set (v4i32 V128:$dst), 8834 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8835 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8836 bits<3> idx; 8837 let Inst{11} = idx{2}; 8838 let Inst{21} = idx{1}; 8839 let Inst{20} = idx{0}; 8840 } 8841 8842 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8843 V128, V128, 8844 V128_lo, VectorIndexH, 8845 asm#"2", ".4s", ".4s", ".8h", ".h", 8846 [(set (v4i32 V128:$dst), 8847 (OpNode (v4i32 V128:$Rd), 8848 (extract_high_v8i16 V128:$Rn), 8849 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8850 VectorIndexH:$idx))))]> { 8851 bits<3> idx; 8852 let Inst{11} = idx{2}; 8853 let Inst{21} = idx{1}; 8854 let Inst{20} = idx{0}; 8855 } 8856 8857 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8858 V128, V64, 8859 V128, VectorIndexS, 8860 asm, ".2d", ".2d", ".2s", ".s", 8861 [(set (v2i64 V128:$dst), 8862 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8863 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8864 bits<2> idx; 8865 let Inst{11} = idx{1}; 8866 let Inst{21} = idx{0}; 8867 } 8868 8869 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8870 V128, V128, 8871 V128, VectorIndexS, 8872 asm#"2", ".2d", ".2d", ".4s", ".s", 8873 [(set (v2i64 V128:$dst), 8874 (OpNode (v2i64 V128:$Rd), 8875 (extract_high_v4i32 V128:$Rn), 8876 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8877 VectorIndexS:$idx))))]> { 8878 bits<2> idx; 8879 let Inst{11} = idx{1}; 8880 let Inst{21} = idx{0}; 8881 } 8882 } 8883} 8884 8885//---------------------------------------------------------------------------- 8886// AdvSIMD scalar shift by immediate 8887//---------------------------------------------------------------------------- 8888 8889let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8890class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8891 RegisterClass regtype1, RegisterClass regtype2, 8892 Operand immtype, string asm, list<dag> pattern> 8893 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8894 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8895 Sched<[WriteV]> { 8896 bits<5> Rd; 8897 bits<5> Rn; 8898 bits<7> imm; 8899 let Inst{31-30} = 0b01; 8900 let Inst{29} = U; 8901 let Inst{28-23} = 0b111110; 8902 let Inst{22-16} = fixed_imm; 8903 let Inst{15-11} = opc; 8904 let Inst{10} = 1; 8905 let Inst{9-5} = Rn; 8906 let Inst{4-0} = Rd; 8907} 8908 8909let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8910class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 8911 RegisterClass regtype1, RegisterClass regtype2, 8912 Operand immtype, string asm, list<dag> pattern> 8913 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 8914 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 8915 Sched<[WriteV]> { 8916 bits<5> Rd; 8917 bits<5> Rn; 8918 bits<7> imm; 8919 let Inst{31-30} = 0b01; 8920 let Inst{29} = U; 8921 let Inst{28-23} = 0b111110; 8922 let Inst{22-16} = fixed_imm; 8923 let Inst{15-11} = opc; 8924 let Inst{10} = 1; 8925 let Inst{9-5} = Rn; 8926 let Inst{4-0} = Rd; 8927} 8928 8929 8930multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 8931 let Predicates = [HasNEON, HasFullFP16] in { 8932 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8933 FPR16, FPR16, vecshiftR16, asm, []> { 8934 let Inst{19-16} = imm{3-0}; 8935 } 8936 } // Predicates = [HasNEON, HasFullFP16] 8937 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8938 FPR32, FPR32, vecshiftR32, asm, []> { 8939 let Inst{20-16} = imm{4-0}; 8940 } 8941 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8942 FPR64, FPR64, vecshiftR64, asm, []> { 8943 let Inst{21-16} = imm{5-0}; 8944 } 8945} 8946 8947multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 8948 SDPatternOperator OpNode> { 8949 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8950 FPR64, FPR64, vecshiftR64, asm, 8951 [(set (i64 FPR64:$Rd), 8952 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 8953 let Inst{21-16} = imm{5-0}; 8954 } 8955 8956 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 8957 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 8958} 8959 8960multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 8961 SDPatternOperator OpNode = null_frag> { 8962 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8963 FPR64, FPR64, vecshiftR64, asm, 8964 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 8965 (i32 vecshiftR64:$imm)))]> { 8966 let Inst{21-16} = imm{5-0}; 8967 } 8968 8969 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 8970 (i32 vecshiftR64:$imm))), 8971 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 8972 vecshiftR64:$imm)>; 8973} 8974 8975multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 8976 SDPatternOperator OpNode> { 8977 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8978 FPR64, FPR64, vecshiftL64, asm, 8979 [(set (i64 FPR64:$Rd), 8980 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8981 let Inst{21-16} = imm{5-0}; 8982 } 8983 8984 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 8985 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 8986} 8987 8988let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8989multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 8990 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8991 FPR64, FPR64, vecshiftL64, asm, []> { 8992 let Inst{21-16} = imm{5-0}; 8993 } 8994} 8995 8996let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8997multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 8998 SDPatternOperator OpNode = null_frag> { 8999 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9000 FPR8, FPR16, vecshiftR8, asm, []> { 9001 let Inst{18-16} = imm{2-0}; 9002 } 9003 9004 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9005 FPR16, FPR32, vecshiftR16, asm, []> { 9006 let Inst{19-16} = imm{3-0}; 9007 } 9008 9009 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9010 FPR32, FPR64, vecshiftR32, asm, 9011 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9012 let Inst{20-16} = imm{4-0}; 9013 } 9014} 9015 9016multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9017 SDPatternOperator OpNode> { 9018 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9019 FPR8, FPR8, vecshiftL8, asm, []> { 9020 let Inst{18-16} = imm{2-0}; 9021 } 9022 9023 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9024 FPR16, FPR16, vecshiftL16, asm, []> { 9025 let Inst{19-16} = imm{3-0}; 9026 } 9027 9028 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9029 FPR32, FPR32, vecshiftL32, asm, 9030 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9031 let Inst{20-16} = imm{4-0}; 9032 } 9033 9034 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9035 FPR64, FPR64, vecshiftL64, asm, 9036 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9037 let Inst{21-16} = imm{5-0}; 9038 } 9039 9040 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9041 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9042} 9043 9044multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9045 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9046 FPR8, FPR8, vecshiftR8, asm, []> { 9047 let Inst{18-16} = imm{2-0}; 9048 } 9049 9050 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9051 FPR16, FPR16, vecshiftR16, asm, []> { 9052 let Inst{19-16} = imm{3-0}; 9053 } 9054 9055 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9056 FPR32, FPR32, vecshiftR32, asm, []> { 9057 let Inst{20-16} = imm{4-0}; 9058 } 9059 9060 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9061 FPR64, FPR64, vecshiftR64, asm, []> { 9062 let Inst{21-16} = imm{5-0}; 9063 } 9064} 9065 9066//---------------------------------------------------------------------------- 9067// AdvSIMD vector x indexed element 9068//---------------------------------------------------------------------------- 9069 9070let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9071class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9072 RegisterOperand dst_reg, RegisterOperand src_reg, 9073 Operand immtype, 9074 string asm, string dst_kind, string src_kind, 9075 list<dag> pattern> 9076 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9077 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9078 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9079 Sched<[WriteV]> { 9080 bits<5> Rd; 9081 bits<5> Rn; 9082 let Inst{31} = 0; 9083 let Inst{30} = Q; 9084 let Inst{29} = U; 9085 let Inst{28-23} = 0b011110; 9086 let Inst{22-16} = fixed_imm; 9087 let Inst{15-11} = opc; 9088 let Inst{10} = 1; 9089 let Inst{9-5} = Rn; 9090 let Inst{4-0} = Rd; 9091} 9092 9093let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9094class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9095 RegisterOperand vectype1, RegisterOperand vectype2, 9096 Operand immtype, 9097 string asm, string dst_kind, string src_kind, 9098 list<dag> pattern> 9099 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9100 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9101 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9102 Sched<[WriteV]> { 9103 bits<5> Rd; 9104 bits<5> Rn; 9105 let Inst{31} = 0; 9106 let Inst{30} = Q; 9107 let Inst{29} = U; 9108 let Inst{28-23} = 0b011110; 9109 let Inst{22-16} = fixed_imm; 9110 let Inst{15-11} = opc; 9111 let Inst{10} = 1; 9112 let Inst{9-5} = Rn; 9113 let Inst{4-0} = Rd; 9114} 9115 9116multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9117 Intrinsic OpNode> { 9118 let Predicates = [HasNEON, HasFullFP16] in { 9119 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9120 V64, V64, vecshiftR16, 9121 asm, ".4h", ".4h", 9122 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9123 bits<4> imm; 9124 let Inst{19-16} = imm; 9125 } 9126 9127 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9128 V128, V128, vecshiftR16, 9129 asm, ".8h", ".8h", 9130 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9131 bits<4> imm; 9132 let Inst{19-16} = imm; 9133 } 9134 } // Predicates = [HasNEON, HasFullFP16] 9135 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9136 V64, V64, vecshiftR32, 9137 asm, ".2s", ".2s", 9138 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9139 bits<5> imm; 9140 let Inst{20-16} = imm; 9141 } 9142 9143 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9144 V128, V128, vecshiftR32, 9145 asm, ".4s", ".4s", 9146 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9147 bits<5> imm; 9148 let Inst{20-16} = imm; 9149 } 9150 9151 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9152 V128, V128, vecshiftR64, 9153 asm, ".2d", ".2d", 9154 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9155 bits<6> imm; 9156 let Inst{21-16} = imm; 9157 } 9158} 9159 9160multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9161 Intrinsic OpNode> { 9162 let Predicates = [HasNEON, HasFullFP16] in { 9163 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9164 V64, V64, vecshiftR16, 9165 asm, ".4h", ".4h", 9166 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9167 bits<4> imm; 9168 let Inst{19-16} = imm; 9169 } 9170 9171 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9172 V128, V128, vecshiftR16, 9173 asm, ".8h", ".8h", 9174 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9175 bits<4> imm; 9176 let Inst{19-16} = imm; 9177 } 9178 } // Predicates = [HasNEON, HasFullFP16] 9179 9180 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9181 V64, V64, vecshiftR32, 9182 asm, ".2s", ".2s", 9183 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9184 bits<5> imm; 9185 let Inst{20-16} = imm; 9186 } 9187 9188 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9189 V128, V128, vecshiftR32, 9190 asm, ".4s", ".4s", 9191 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9192 bits<5> imm; 9193 let Inst{20-16} = imm; 9194 } 9195 9196 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9197 V128, V128, vecshiftR64, 9198 asm, ".2d", ".2d", 9199 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9200 bits<6> imm; 9201 let Inst{21-16} = imm; 9202 } 9203} 9204 9205multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9206 SDPatternOperator OpNode> { 9207 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9208 V64, V128, vecshiftR16Narrow, 9209 asm, ".8b", ".8h", 9210 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9211 bits<3> imm; 9212 let Inst{18-16} = imm; 9213 } 9214 9215 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9216 V128, V128, vecshiftR16Narrow, 9217 asm#"2", ".16b", ".8h", []> { 9218 bits<3> imm; 9219 let Inst{18-16} = imm; 9220 let hasSideEffects = 0; 9221 } 9222 9223 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9224 V64, V128, vecshiftR32Narrow, 9225 asm, ".4h", ".4s", 9226 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9227 bits<4> imm; 9228 let Inst{19-16} = imm; 9229 } 9230 9231 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9232 V128, V128, vecshiftR32Narrow, 9233 asm#"2", ".8h", ".4s", []> { 9234 bits<4> imm; 9235 let Inst{19-16} = imm; 9236 let hasSideEffects = 0; 9237 } 9238 9239 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9240 V64, V128, vecshiftR64Narrow, 9241 asm, ".2s", ".2d", 9242 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9243 bits<5> imm; 9244 let Inst{20-16} = imm; 9245 } 9246 9247 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9248 V128, V128, vecshiftR64Narrow, 9249 asm#"2", ".4s", ".2d", []> { 9250 bits<5> imm; 9251 let Inst{20-16} = imm; 9252 let hasSideEffects = 0; 9253 } 9254 9255 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9256 // themselves, so put them here instead. 9257 9258 // Patterns involving what's effectively an insert high and a normal 9259 // intrinsic, represented by CONCAT_VECTORS. 9260 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9261 vecshiftR16Narrow:$imm)), 9262 (!cast<Instruction>(NAME # "v16i8_shift") 9263 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9264 V128:$Rn, vecshiftR16Narrow:$imm)>; 9265 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9266 vecshiftR32Narrow:$imm)), 9267 (!cast<Instruction>(NAME # "v8i16_shift") 9268 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9269 V128:$Rn, vecshiftR32Narrow:$imm)>; 9270 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9271 vecshiftR64Narrow:$imm)), 9272 (!cast<Instruction>(NAME # "v4i32_shift") 9273 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9274 V128:$Rn, vecshiftR64Narrow:$imm)>; 9275} 9276 9277multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9278 SDPatternOperator OpNode> { 9279 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9280 V64, V64, vecshiftL8, 9281 asm, ".8b", ".8b", 9282 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9283 (i32 vecshiftL8:$imm)))]> { 9284 bits<3> imm; 9285 let Inst{18-16} = imm; 9286 } 9287 9288 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9289 V128, V128, vecshiftL8, 9290 asm, ".16b", ".16b", 9291 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9292 (i32 vecshiftL8:$imm)))]> { 9293 bits<3> imm; 9294 let Inst{18-16} = imm; 9295 } 9296 9297 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9298 V64, V64, vecshiftL16, 9299 asm, ".4h", ".4h", 9300 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9301 (i32 vecshiftL16:$imm)))]> { 9302 bits<4> imm; 9303 let Inst{19-16} = imm; 9304 } 9305 9306 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9307 V128, V128, vecshiftL16, 9308 asm, ".8h", ".8h", 9309 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9310 (i32 vecshiftL16:$imm)))]> { 9311 bits<4> imm; 9312 let Inst{19-16} = imm; 9313 } 9314 9315 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9316 V64, V64, vecshiftL32, 9317 asm, ".2s", ".2s", 9318 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9319 (i32 vecshiftL32:$imm)))]> { 9320 bits<5> imm; 9321 let Inst{20-16} = imm; 9322 } 9323 9324 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9325 V128, V128, vecshiftL32, 9326 asm, ".4s", ".4s", 9327 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9328 (i32 vecshiftL32:$imm)))]> { 9329 bits<5> imm; 9330 let Inst{20-16} = imm; 9331 } 9332 9333 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9334 V128, V128, vecshiftL64, 9335 asm, ".2d", ".2d", 9336 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9337 (i32 vecshiftL64:$imm)))]> { 9338 bits<6> imm; 9339 let Inst{21-16} = imm; 9340 } 9341} 9342 9343multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9344 SDPatternOperator OpNode> { 9345 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9346 V64, V64, vecshiftR8, 9347 asm, ".8b", ".8b", 9348 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9349 (i32 vecshiftR8:$imm)))]> { 9350 bits<3> imm; 9351 let Inst{18-16} = imm; 9352 } 9353 9354 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9355 V128, V128, vecshiftR8, 9356 asm, ".16b", ".16b", 9357 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9358 (i32 vecshiftR8:$imm)))]> { 9359 bits<3> imm; 9360 let Inst{18-16} = imm; 9361 } 9362 9363 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9364 V64, V64, vecshiftR16, 9365 asm, ".4h", ".4h", 9366 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9367 (i32 vecshiftR16:$imm)))]> { 9368 bits<4> imm; 9369 let Inst{19-16} = imm; 9370 } 9371 9372 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9373 V128, V128, vecshiftR16, 9374 asm, ".8h", ".8h", 9375 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9376 (i32 vecshiftR16:$imm)))]> { 9377 bits<4> imm; 9378 let Inst{19-16} = imm; 9379 } 9380 9381 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9382 V64, V64, vecshiftR32, 9383 asm, ".2s", ".2s", 9384 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9385 (i32 vecshiftR32:$imm)))]> { 9386 bits<5> imm; 9387 let Inst{20-16} = imm; 9388 } 9389 9390 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9391 V128, V128, vecshiftR32, 9392 asm, ".4s", ".4s", 9393 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9394 (i32 vecshiftR32:$imm)))]> { 9395 bits<5> imm; 9396 let Inst{20-16} = imm; 9397 } 9398 9399 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9400 V128, V128, vecshiftR64, 9401 asm, ".2d", ".2d", 9402 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9403 (i32 vecshiftR64:$imm)))]> { 9404 bits<6> imm; 9405 let Inst{21-16} = imm; 9406 } 9407} 9408 9409let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9410multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9411 SDPatternOperator OpNode = null_frag> { 9412 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9413 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9414 [(set (v8i8 V64:$dst), 9415 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9416 (i32 vecshiftR8:$imm)))]> { 9417 bits<3> imm; 9418 let Inst{18-16} = imm; 9419 } 9420 9421 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9422 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9423 [(set (v16i8 V128:$dst), 9424 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9425 (i32 vecshiftR8:$imm)))]> { 9426 bits<3> imm; 9427 let Inst{18-16} = imm; 9428 } 9429 9430 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9431 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9432 [(set (v4i16 V64:$dst), 9433 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9434 (i32 vecshiftR16:$imm)))]> { 9435 bits<4> imm; 9436 let Inst{19-16} = imm; 9437 } 9438 9439 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9440 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9441 [(set (v8i16 V128:$dst), 9442 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9443 (i32 vecshiftR16:$imm)))]> { 9444 bits<4> imm; 9445 let Inst{19-16} = imm; 9446 } 9447 9448 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9449 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9450 [(set (v2i32 V64:$dst), 9451 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9452 (i32 vecshiftR32:$imm)))]> { 9453 bits<5> imm; 9454 let Inst{20-16} = imm; 9455 } 9456 9457 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9458 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9459 [(set (v4i32 V128:$dst), 9460 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9461 (i32 vecshiftR32:$imm)))]> { 9462 bits<5> imm; 9463 let Inst{20-16} = imm; 9464 } 9465 9466 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9467 V128, V128, vecshiftR64, 9468 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9469 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9470 (i32 vecshiftR64:$imm)))]> { 9471 bits<6> imm; 9472 let Inst{21-16} = imm; 9473 } 9474} 9475 9476multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9477 SDPatternOperator OpNode = null_frag> { 9478 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9479 V64, V64, vecshiftL8, 9480 asm, ".8b", ".8b", 9481 [(set (v8i8 V64:$dst), 9482 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9483 (i32 vecshiftL8:$imm)))]> { 9484 bits<3> imm; 9485 let Inst{18-16} = imm; 9486 } 9487 9488 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9489 V128, V128, vecshiftL8, 9490 asm, ".16b", ".16b", 9491 [(set (v16i8 V128:$dst), 9492 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9493 (i32 vecshiftL8:$imm)))]> { 9494 bits<3> imm; 9495 let Inst{18-16} = imm; 9496 } 9497 9498 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9499 V64, V64, vecshiftL16, 9500 asm, ".4h", ".4h", 9501 [(set (v4i16 V64:$dst), 9502 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9503 (i32 vecshiftL16:$imm)))]> { 9504 bits<4> imm; 9505 let Inst{19-16} = imm; 9506 } 9507 9508 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9509 V128, V128, vecshiftL16, 9510 asm, ".8h", ".8h", 9511 [(set (v8i16 V128:$dst), 9512 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9513 (i32 vecshiftL16:$imm)))]> { 9514 bits<4> imm; 9515 let Inst{19-16} = imm; 9516 } 9517 9518 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9519 V64, V64, vecshiftL32, 9520 asm, ".2s", ".2s", 9521 [(set (v2i32 V64:$dst), 9522 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9523 (i32 vecshiftL32:$imm)))]> { 9524 bits<5> imm; 9525 let Inst{20-16} = imm; 9526 } 9527 9528 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9529 V128, V128, vecshiftL32, 9530 asm, ".4s", ".4s", 9531 [(set (v4i32 V128:$dst), 9532 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9533 (i32 vecshiftL32:$imm)))]> { 9534 bits<5> imm; 9535 let Inst{20-16} = imm; 9536 } 9537 9538 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9539 V128, V128, vecshiftL64, 9540 asm, ".2d", ".2d", 9541 [(set (v2i64 V128:$dst), 9542 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9543 (i32 vecshiftL64:$imm)))]> { 9544 bits<6> imm; 9545 let Inst{21-16} = imm; 9546 } 9547} 9548 9549multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9550 SDPatternOperator OpNode> { 9551 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9552 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9553 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9554 bits<3> imm; 9555 let Inst{18-16} = imm; 9556 } 9557 9558 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9559 V128, V128, vecshiftL8, 9560 asm#"2", ".8h", ".16b", 9561 [(set (v8i16 V128:$Rd), 9562 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 9563 bits<3> imm; 9564 let Inst{18-16} = imm; 9565 } 9566 9567 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9568 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9569 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9570 bits<4> imm; 9571 let Inst{19-16} = imm; 9572 } 9573 9574 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9575 V128, V128, vecshiftL16, 9576 asm#"2", ".4s", ".8h", 9577 [(set (v4i32 V128:$Rd), 9578 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 9579 9580 bits<4> imm; 9581 let Inst{19-16} = imm; 9582 } 9583 9584 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9585 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9586 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9587 bits<5> imm; 9588 let Inst{20-16} = imm; 9589 } 9590 9591 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9592 V128, V128, vecshiftL32, 9593 asm#"2", ".2d", ".4s", 9594 [(set (v2i64 V128:$Rd), 9595 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9596 bits<5> imm; 9597 let Inst{20-16} = imm; 9598 } 9599} 9600 9601 9602//--- 9603// Vector load/store 9604//--- 9605// SIMD ldX/stX no-index memory references don't allow the optional 9606// ", #0" constant and handle post-indexing explicitly, so we use 9607// a more specialized parse method for them. Otherwise, it's the same as 9608// the general GPR64sp handling. 9609 9610class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9611 string asm, dag oops, dag iops, list<dag> pattern> 9612 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9613 bits<5> Vt; 9614 bits<5> Rn; 9615 let Inst{31} = 0; 9616 let Inst{30} = Q; 9617 let Inst{29-23} = 0b0011000; 9618 let Inst{22} = L; 9619 let Inst{21-16} = 0b000000; 9620 let Inst{15-12} = opcode; 9621 let Inst{11-10} = size; 9622 let Inst{9-5} = Rn; 9623 let Inst{4-0} = Vt; 9624} 9625 9626class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9627 string asm, dag oops, dag iops> 9628 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9629 bits<5> Vt; 9630 bits<5> Rn; 9631 bits<5> Xm; 9632 let Inst{31} = 0; 9633 let Inst{30} = Q; 9634 let Inst{29-23} = 0b0011001; 9635 let Inst{22} = L; 9636 let Inst{21} = 0; 9637 let Inst{20-16} = Xm; 9638 let Inst{15-12} = opcode; 9639 let Inst{11-10} = size; 9640 let Inst{9-5} = Rn; 9641 let Inst{4-0} = Vt; 9642} 9643 9644// The immediate form of AdvSIMD post-indexed addressing is encoded with 9645// register post-index addressing from the zero register. 9646multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9647 int Offset, int Size> { 9648 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9649 // "ld1\t$Vt, [$Rn], #16" 9650 // may get mapped to 9651 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9652 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9653 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9654 GPR64sp:$Rn, 9655 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9656 XZR), 1>; 9657 9658 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9659 // "ld1.8b\t$Vt, [$Rn], #16" 9660 // may get mapped to 9661 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9662 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9663 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9664 GPR64sp:$Rn, 9665 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9666 XZR), 0>; 9667 9668 // E.g. "ld1.8b { v0, v1 }, [x1]" 9669 // "ld1\t$Vt, [$Rn]" 9670 // may get mapped to 9671 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9672 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9673 (!cast<Instruction>(BaseName # Count # "v" # layout) 9674 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9675 GPR64sp:$Rn), 0>; 9676 9677 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9678 // "ld1\t$Vt, [$Rn], $Xm" 9679 // may get mapped to 9680 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9681 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9682 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9683 GPR64sp:$Rn, 9684 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9685 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9686} 9687 9688multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9689 int Offset128, int Offset64, bits<4> opcode> { 9690 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9691 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9692 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9693 (ins GPR64sp:$Rn), []>; 9694 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9695 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9696 (ins GPR64sp:$Rn), []>; 9697 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9698 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9699 (ins GPR64sp:$Rn), []>; 9700 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9701 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9702 (ins GPR64sp:$Rn), []>; 9703 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9704 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9705 (ins GPR64sp:$Rn), []>; 9706 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9707 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9708 (ins GPR64sp:$Rn), []>; 9709 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9710 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9711 (ins GPR64sp:$Rn), []>; 9712 9713 9714 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9715 (outs GPR64sp:$wback, 9716 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9717 (ins GPR64sp:$Rn, 9718 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9719 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9720 (outs GPR64sp:$wback, 9721 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9722 (ins GPR64sp:$Rn, 9723 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9724 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9725 (outs GPR64sp:$wback, 9726 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9727 (ins GPR64sp:$Rn, 9728 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9729 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9730 (outs GPR64sp:$wback, 9731 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9732 (ins GPR64sp:$Rn, 9733 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9734 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9735 (outs GPR64sp:$wback, 9736 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9737 (ins GPR64sp:$Rn, 9738 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9739 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9740 (outs GPR64sp:$wback, 9741 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9742 (ins GPR64sp:$Rn, 9743 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9744 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9745 (outs GPR64sp:$wback, 9746 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9747 (ins GPR64sp:$Rn, 9748 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9749 } 9750 9751 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9752 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9753 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9754 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9755 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9756 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9757 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9758} 9759 9760// Only ld1/st1 has a v1d version. 9761multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9762 int Offset128, int Offset64, bits<4> opcode> { 9763 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9764 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9765 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9766 GPR64sp:$Rn), []>; 9767 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9768 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9769 GPR64sp:$Rn), []>; 9770 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9771 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9772 GPR64sp:$Rn), []>; 9773 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9774 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9775 GPR64sp:$Rn), []>; 9776 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9777 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9778 GPR64sp:$Rn), []>; 9779 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9780 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9781 GPR64sp:$Rn), []>; 9782 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9783 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9784 GPR64sp:$Rn), []>; 9785 9786 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9787 (outs GPR64sp:$wback), 9788 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9789 GPR64sp:$Rn, 9790 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9791 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9792 (outs GPR64sp:$wback), 9793 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9794 GPR64sp:$Rn, 9795 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9796 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9797 (outs GPR64sp:$wback), 9798 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9799 GPR64sp:$Rn, 9800 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9801 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9802 (outs GPR64sp:$wback), 9803 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9804 GPR64sp:$Rn, 9805 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9806 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9807 (outs GPR64sp:$wback), 9808 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9809 GPR64sp:$Rn, 9810 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9811 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9812 (outs GPR64sp:$wback), 9813 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9814 GPR64sp:$Rn, 9815 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9816 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9817 (outs GPR64sp:$wback), 9818 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9819 GPR64sp:$Rn, 9820 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9821 } 9822 9823 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9824 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9825 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9826 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9827 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9828 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9829 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9830} 9831 9832multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9833 int Offset128, int Offset64, bits<4> opcode> 9834 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9835 9836 // LD1 instructions have extra "1d" variants. 9837 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9838 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9839 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9840 (ins GPR64sp:$Rn), []>; 9841 9842 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9843 (outs GPR64sp:$wback, 9844 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9845 (ins GPR64sp:$Rn, 9846 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9847 } 9848 9849 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9850} 9851 9852multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9853 int Offset128, int Offset64, bits<4> opcode> 9854 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9855 9856 // ST1 instructions have extra "1d" variants. 9857 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9858 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9859 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9860 GPR64sp:$Rn), []>; 9861 9862 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9863 (outs GPR64sp:$wback), 9864 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9865 GPR64sp:$Rn, 9866 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9867 } 9868 9869 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9870} 9871 9872multiclass SIMDLd1Multiple<string asm> { 9873 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9874 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9875 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9876 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9877} 9878 9879multiclass SIMDSt1Multiple<string asm> { 9880 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9881 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9882 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9883 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9884} 9885 9886multiclass SIMDLd2Multiple<string asm> { 9887 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9888} 9889 9890multiclass SIMDSt2Multiple<string asm> { 9891 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9892} 9893 9894multiclass SIMDLd3Multiple<string asm> { 9895 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9896} 9897 9898multiclass SIMDSt3Multiple<string asm> { 9899 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9900} 9901 9902multiclass SIMDLd4Multiple<string asm> { 9903 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9904} 9905 9906multiclass SIMDSt4Multiple<string asm> { 9907 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9908} 9909 9910//--- 9911// AdvSIMD Load/store single-element 9912//--- 9913 9914class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 9915 string asm, string operands, string cst, 9916 dag oops, dag iops, list<dag> pattern> 9917 : I<oops, iops, asm, operands, cst, pattern> { 9918 bits<5> Vt; 9919 bits<5> Rn; 9920 let Inst{31} = 0; 9921 let Inst{29-24} = 0b001101; 9922 let Inst{22} = L; 9923 let Inst{21} = R; 9924 let Inst{15-13} = opcode; 9925 let Inst{9-5} = Rn; 9926 let Inst{4-0} = Vt; 9927} 9928 9929class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 9930 string asm, string operands, string cst, 9931 dag oops, dag iops, list<dag> pattern> 9932 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 9933 bits<5> Vt; 9934 bits<5> Rn; 9935 let Inst{31} = 0; 9936 let Inst{29-24} = 0b001101; 9937 let Inst{22} = L; 9938 let Inst{21} = R; 9939 let Inst{15-13} = opcode; 9940 let Inst{9-5} = Rn; 9941 let Inst{4-0} = Vt; 9942} 9943 9944 9945let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9946class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 9947 DAGOperand listtype> 9948 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 9949 (outs listtype:$Vt), (ins GPR64sp:$Rn), 9950 []> { 9951 let Inst{30} = Q; 9952 let Inst{23} = 0; 9953 let Inst{20-16} = 0b00000; 9954 let Inst{12} = S; 9955 let Inst{11-10} = size; 9956} 9957let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9958class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 9959 string asm, DAGOperand listtype, DAGOperand GPR64pi> 9960 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 9961 "$Rn = $wback", 9962 (outs GPR64sp:$wback, listtype:$Vt), 9963 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 9964 bits<5> Xm; 9965 let Inst{30} = Q; 9966 let Inst{23} = 1; 9967 let Inst{20-16} = Xm; 9968 let Inst{12} = S; 9969 let Inst{11-10} = size; 9970} 9971 9972multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 9973 int Offset, int Size> { 9974 // E.g. "ld1r { v0.8b }, [x1], #1" 9975 // "ld1r.8b\t$Vt, [$Rn], #1" 9976 // may get mapped to 9977 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9978 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9979 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9980 GPR64sp:$Rn, 9981 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9982 XZR), 1>; 9983 9984 // E.g. "ld1r.8b { v0 }, [x1], #1" 9985 // "ld1r.8b\t$Vt, [$Rn], #1" 9986 // may get mapped to 9987 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9988 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9989 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9990 GPR64sp:$Rn, 9991 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9992 XZR), 0>; 9993 9994 // E.g. "ld1r.8b { v0 }, [x1]" 9995 // "ld1r.8b\t$Vt, [$Rn]" 9996 // may get mapped to 9997 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9998 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9999 (!cast<Instruction>(BaseName # "v" # layout) 10000 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10001 GPR64sp:$Rn), 0>; 10002 10003 // E.g. "ld1r.8b { v0 }, [x1], x2" 10004 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10005 // may get mapped to 10006 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10007 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10008 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10009 GPR64sp:$Rn, 10010 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10011 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10012} 10013 10014multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10015 int Offset1, int Offset2, int Offset4, int Offset8> { 10016 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10017 !cast<DAGOperand>("VecList" # Count # "8b")>; 10018 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10019 !cast<DAGOperand>("VecList" # Count #"16b")>; 10020 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10021 !cast<DAGOperand>("VecList" # Count #"4h")>; 10022 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10023 !cast<DAGOperand>("VecList" # Count #"8h")>; 10024 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10025 !cast<DAGOperand>("VecList" # Count #"2s")>; 10026 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10027 !cast<DAGOperand>("VecList" # Count #"4s")>; 10028 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10029 !cast<DAGOperand>("VecList" # Count #"1d")>; 10030 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10031 !cast<DAGOperand>("VecList" # Count #"2d")>; 10032 10033 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10034 !cast<DAGOperand>("VecList" # Count # "8b"), 10035 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10036 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10037 !cast<DAGOperand>("VecList" # Count # "16b"), 10038 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10039 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10040 !cast<DAGOperand>("VecList" # Count # "4h"), 10041 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10042 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10043 !cast<DAGOperand>("VecList" # Count # "8h"), 10044 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10045 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10046 !cast<DAGOperand>("VecList" # Count # "2s"), 10047 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10048 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10049 !cast<DAGOperand>("VecList" # Count # "4s"), 10050 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10051 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10052 !cast<DAGOperand>("VecList" # Count # "1d"), 10053 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10054 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10055 !cast<DAGOperand>("VecList" # Count # "2d"), 10056 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10057 10058 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10059 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10060 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10061 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10062 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10063 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10064 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10065 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10066} 10067 10068class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10069 dag oops, dag iops, list<dag> pattern> 10070 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10071 pattern> { 10072 // idx encoded in Q:S:size fields. 10073 bits<4> idx; 10074 let Inst{30} = idx{3}; 10075 let Inst{23} = 0; 10076 let Inst{20-16} = 0b00000; 10077 let Inst{12} = idx{2}; 10078 let Inst{11-10} = idx{1-0}; 10079} 10080class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10081 dag oops, dag iops, list<dag> pattern> 10082 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10083 oops, iops, pattern> { 10084 // idx encoded in Q:S:size fields. 10085 bits<4> idx; 10086 let Inst{30} = idx{3}; 10087 let Inst{23} = 0; 10088 let Inst{20-16} = 0b00000; 10089 let Inst{12} = idx{2}; 10090 let Inst{11-10} = idx{1-0}; 10091} 10092class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10093 dag oops, dag iops> 10094 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10095 "$Rn = $wback", oops, iops, []> { 10096 // idx encoded in Q:S:size fields. 10097 bits<4> idx; 10098 bits<5> Xm; 10099 let Inst{30} = idx{3}; 10100 let Inst{23} = 1; 10101 let Inst{20-16} = Xm; 10102 let Inst{12} = idx{2}; 10103 let Inst{11-10} = idx{1-0}; 10104} 10105class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10106 dag oops, dag iops> 10107 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10108 "$Rn = $wback", oops, iops, []> { 10109 // idx encoded in Q:S:size fields. 10110 bits<4> idx; 10111 bits<5> Xm; 10112 let Inst{30} = idx{3}; 10113 let Inst{23} = 1; 10114 let Inst{20-16} = Xm; 10115 let Inst{12} = idx{2}; 10116 let Inst{11-10} = idx{1-0}; 10117} 10118 10119class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10120 dag oops, dag iops, list<dag> pattern> 10121 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10122 pattern> { 10123 // idx encoded in Q:S:size<1> fields. 10124 bits<3> idx; 10125 let Inst{30} = idx{2}; 10126 let Inst{23} = 0; 10127 let Inst{20-16} = 0b00000; 10128 let Inst{12} = idx{1}; 10129 let Inst{11} = idx{0}; 10130 let Inst{10} = size; 10131} 10132class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10133 dag oops, dag iops, list<dag> pattern> 10134 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10135 oops, iops, pattern> { 10136 // idx encoded in Q:S:size<1> fields. 10137 bits<3> idx; 10138 let Inst{30} = idx{2}; 10139 let Inst{23} = 0; 10140 let Inst{20-16} = 0b00000; 10141 let Inst{12} = idx{1}; 10142 let Inst{11} = idx{0}; 10143 let Inst{10} = size; 10144} 10145 10146class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10147 dag oops, dag iops> 10148 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10149 "$Rn = $wback", oops, iops, []> { 10150 // idx encoded in Q:S:size<1> fields. 10151 bits<3> idx; 10152 bits<5> Xm; 10153 let Inst{30} = idx{2}; 10154 let Inst{23} = 1; 10155 let Inst{20-16} = Xm; 10156 let Inst{12} = idx{1}; 10157 let Inst{11} = idx{0}; 10158 let Inst{10} = size; 10159} 10160class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10161 dag oops, dag iops> 10162 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10163 "$Rn = $wback", oops, iops, []> { 10164 // idx encoded in Q:S:size<1> fields. 10165 bits<3> idx; 10166 bits<5> Xm; 10167 let Inst{30} = idx{2}; 10168 let Inst{23} = 1; 10169 let Inst{20-16} = Xm; 10170 let Inst{12} = idx{1}; 10171 let Inst{11} = idx{0}; 10172 let Inst{10} = size; 10173} 10174class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10175 dag oops, dag iops, list<dag> pattern> 10176 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10177 pattern> { 10178 // idx encoded in Q:S fields. 10179 bits<2> idx; 10180 let Inst{30} = idx{1}; 10181 let Inst{23} = 0; 10182 let Inst{20-16} = 0b00000; 10183 let Inst{12} = idx{0}; 10184 let Inst{11-10} = size; 10185} 10186class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10187 dag oops, dag iops, list<dag> pattern> 10188 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10189 oops, iops, pattern> { 10190 // idx encoded in Q:S fields. 10191 bits<2> idx; 10192 let Inst{30} = idx{1}; 10193 let Inst{23} = 0; 10194 let Inst{20-16} = 0b00000; 10195 let Inst{12} = idx{0}; 10196 let Inst{11-10} = size; 10197} 10198class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10199 string asm, dag oops, dag iops> 10200 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10201 "$Rn = $wback", oops, iops, []> { 10202 // idx encoded in Q:S fields. 10203 bits<2> idx; 10204 bits<5> Xm; 10205 let Inst{30} = idx{1}; 10206 let Inst{23} = 1; 10207 let Inst{20-16} = Xm; 10208 let Inst{12} = idx{0}; 10209 let Inst{11-10} = size; 10210} 10211class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10212 string asm, dag oops, dag iops> 10213 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10214 "$Rn = $wback", oops, iops, []> { 10215 // idx encoded in Q:S fields. 10216 bits<2> idx; 10217 bits<5> Xm; 10218 let Inst{30} = idx{1}; 10219 let Inst{23} = 1; 10220 let Inst{20-16} = Xm; 10221 let Inst{12} = idx{0}; 10222 let Inst{11-10} = size; 10223} 10224class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10225 dag oops, dag iops, list<dag> pattern> 10226 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10227 pattern> { 10228 // idx encoded in Q field. 10229 bits<1> idx; 10230 let Inst{30} = idx; 10231 let Inst{23} = 0; 10232 let Inst{20-16} = 0b00000; 10233 let Inst{12} = 0; 10234 let Inst{11-10} = size; 10235} 10236class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10237 dag oops, dag iops, list<dag> pattern> 10238 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10239 oops, iops, pattern> { 10240 // idx encoded in Q field. 10241 bits<1> idx; 10242 let Inst{30} = idx; 10243 let Inst{23} = 0; 10244 let Inst{20-16} = 0b00000; 10245 let Inst{12} = 0; 10246 let Inst{11-10} = size; 10247} 10248class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10249 string asm, dag oops, dag iops> 10250 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10251 "$Rn = $wback", oops, iops, []> { 10252 // idx encoded in Q field. 10253 bits<1> idx; 10254 bits<5> Xm; 10255 let Inst{30} = idx; 10256 let Inst{23} = 1; 10257 let Inst{20-16} = Xm; 10258 let Inst{12} = 0; 10259 let Inst{11-10} = size; 10260} 10261class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10262 string asm, dag oops, dag iops> 10263 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10264 "$Rn = $wback", oops, iops, []> { 10265 // idx encoded in Q field. 10266 bits<1> idx; 10267 bits<5> Xm; 10268 let Inst{30} = idx; 10269 let Inst{23} = 1; 10270 let Inst{20-16} = Xm; 10271 let Inst{12} = 0; 10272 let Inst{11-10} = size; 10273} 10274 10275let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10276multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10277 RegisterOperand listtype, 10278 RegisterOperand GPR64pi> { 10279 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10280 (outs listtype:$dst), 10281 (ins listtype:$Vt, VectorIndexB:$idx, 10282 GPR64sp:$Rn), []>; 10283 10284 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10285 (outs GPR64sp:$wback, listtype:$dst), 10286 (ins listtype:$Vt, VectorIndexB:$idx, 10287 GPR64sp:$Rn, GPR64pi:$Xm)>; 10288} 10289let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10290multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10291 RegisterOperand listtype, 10292 RegisterOperand GPR64pi> { 10293 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10294 (outs listtype:$dst), 10295 (ins listtype:$Vt, VectorIndexH:$idx, 10296 GPR64sp:$Rn), []>; 10297 10298 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10299 (outs GPR64sp:$wback, listtype:$dst), 10300 (ins listtype:$Vt, VectorIndexH:$idx, 10301 GPR64sp:$Rn, GPR64pi:$Xm)>; 10302} 10303let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10304multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10305 RegisterOperand listtype, 10306 RegisterOperand GPR64pi> { 10307 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10308 (outs listtype:$dst), 10309 (ins listtype:$Vt, VectorIndexS:$idx, 10310 GPR64sp:$Rn), []>; 10311 10312 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10313 (outs GPR64sp:$wback, listtype:$dst), 10314 (ins listtype:$Vt, VectorIndexS:$idx, 10315 GPR64sp:$Rn, GPR64pi:$Xm)>; 10316} 10317let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10318multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10319 RegisterOperand listtype, RegisterOperand GPR64pi> { 10320 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10321 (outs listtype:$dst), 10322 (ins listtype:$Vt, VectorIndexD:$idx, 10323 GPR64sp:$Rn), []>; 10324 10325 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10326 (outs GPR64sp:$wback, listtype:$dst), 10327 (ins listtype:$Vt, VectorIndexD:$idx, 10328 GPR64sp:$Rn, GPR64pi:$Xm)>; 10329} 10330let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10331multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10332 RegisterOperand listtype, RegisterOperand GPR64pi> { 10333 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10334 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10335 GPR64sp:$Rn), []>; 10336 10337 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10338 (outs GPR64sp:$wback), 10339 (ins listtype:$Vt, VectorIndexB:$idx, 10340 GPR64sp:$Rn, GPR64pi:$Xm)>; 10341} 10342let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10343multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10344 RegisterOperand listtype, RegisterOperand GPR64pi> { 10345 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10346 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10347 GPR64sp:$Rn), []>; 10348 10349 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10350 (outs GPR64sp:$wback), 10351 (ins listtype:$Vt, VectorIndexH:$idx, 10352 GPR64sp:$Rn, GPR64pi:$Xm)>; 10353} 10354let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10355multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10356 RegisterOperand listtype, RegisterOperand GPR64pi> { 10357 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10358 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10359 GPR64sp:$Rn), []>; 10360 10361 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10362 (outs GPR64sp:$wback), 10363 (ins listtype:$Vt, VectorIndexS:$idx, 10364 GPR64sp:$Rn, GPR64pi:$Xm)>; 10365} 10366let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10367multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10368 RegisterOperand listtype, RegisterOperand GPR64pi> { 10369 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10370 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10371 GPR64sp:$Rn), []>; 10372 10373 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10374 (outs GPR64sp:$wback), 10375 (ins listtype:$Vt, VectorIndexD:$idx, 10376 GPR64sp:$Rn, GPR64pi:$Xm)>; 10377} 10378 10379multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10380 string Count, int Offset, Operand idxtype> { 10381 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10382 // "ld1\t$Vt, [$Rn], #1" 10383 // may get mapped to 10384 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10385 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10386 (!cast<Instruction>(NAME # Type # "_POST") 10387 GPR64sp:$Rn, 10388 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10389 idxtype:$idx, XZR), 1>; 10390 10391 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10392 // "ld1.8b\t$Vt, [$Rn], #1" 10393 // may get mapped to 10394 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10395 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10396 (!cast<Instruction>(NAME # Type # "_POST") 10397 GPR64sp:$Rn, 10398 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10399 idxtype:$idx, XZR), 0>; 10400 10401 // E.g. "ld1.8b { v0 }[0], [x1]" 10402 // "ld1.8b\t$Vt, [$Rn]" 10403 // may get mapped to 10404 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10405 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10406 (!cast<Instruction>(NAME # Type) 10407 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10408 idxtype:$idx, GPR64sp:$Rn), 0>; 10409 10410 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10411 // "ld1.8b\t$Vt, [$Rn], $Xm" 10412 // may get mapped to 10413 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10414 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10415 (!cast<Instruction>(NAME # Type # "_POST") 10416 GPR64sp:$Rn, 10417 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10418 idxtype:$idx, 10419 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10420} 10421 10422multiclass SIMDLdSt1SingleAliases<string asm> { 10423 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10424 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10425 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10426 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10427} 10428 10429multiclass SIMDLdSt2SingleAliases<string asm> { 10430 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10431 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10432 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10433 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10434} 10435 10436multiclass SIMDLdSt3SingleAliases<string asm> { 10437 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10438 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10439 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10440 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10441} 10442 10443multiclass SIMDLdSt4SingleAliases<string asm> { 10444 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10445 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10446 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10447 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10448} 10449} // end of 'let Predicates = [HasNEON]' 10450 10451//---------------------------------------------------------------------------- 10452// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10453//---------------------------------------------------------------------------- 10454 10455let Predicates = [HasNEON, HasRDM] in { 10456 10457class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10458 RegisterOperand regtype, string asm, 10459 string kind, list<dag> pattern> 10460 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10461 pattern> { 10462} 10463multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10464 SDPatternOperator Accum> { 10465 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10466 [(set (v4i16 V64:$dst), 10467 (Accum (v4i16 V64:$Rd), 10468 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 10469 (v4i16 V64:$Rm)))))]>; 10470 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10471 [(set (v8i16 V128:$dst), 10472 (Accum (v8i16 V128:$Rd), 10473 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 10474 (v8i16 V128:$Rm)))))]>; 10475 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10476 [(set (v2i32 V64:$dst), 10477 (Accum (v2i32 V64:$Rd), 10478 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 10479 (v2i32 V64:$Rm)))))]>; 10480 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10481 [(set (v4i32 V128:$dst), 10482 (Accum (v4i32 V128:$Rd), 10483 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 10484 (v4i32 V128:$Rm)))))]>; 10485} 10486 10487multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10488 SDPatternOperator Accum> { 10489 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10490 V64, V64, V128_lo, VectorIndexH, 10491 asm, ".4h", ".4h", ".4h", ".h", 10492 [(set (v4i16 V64:$dst), 10493 (Accum (v4i16 V64:$Rd), 10494 (v4i16 (int_aarch64_neon_sqrdmulh 10495 (v4i16 V64:$Rn), 10496 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10497 VectorIndexH:$idx))))))]> { 10498 bits<3> idx; 10499 let Inst{11} = idx{2}; 10500 let Inst{21} = idx{1}; 10501 let Inst{20} = idx{0}; 10502 } 10503 10504 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10505 V128, V128, V128_lo, VectorIndexH, 10506 asm, ".8h", ".8h", ".8h", ".h", 10507 [(set (v8i16 V128:$dst), 10508 (Accum (v8i16 V128:$Rd), 10509 (v8i16 (int_aarch64_neon_sqrdmulh 10510 (v8i16 V128:$Rn), 10511 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10512 VectorIndexH:$idx))))))]> { 10513 bits<3> idx; 10514 let Inst{11} = idx{2}; 10515 let Inst{21} = idx{1}; 10516 let Inst{20} = idx{0}; 10517 } 10518 10519 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10520 V64, V64, V128, VectorIndexS, 10521 asm, ".2s", ".2s", ".2s", ".s", 10522 [(set (v2i32 V64:$dst), 10523 (Accum (v2i32 V64:$Rd), 10524 (v2i32 (int_aarch64_neon_sqrdmulh 10525 (v2i32 V64:$Rn), 10526 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10527 VectorIndexS:$idx))))))]> { 10528 bits<2> idx; 10529 let Inst{11} = idx{1}; 10530 let Inst{21} = idx{0}; 10531 } 10532 10533 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10534 // an intermediate EXTRACT_SUBREG would be untyped. 10535 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 10536 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 10537 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10538 (i32 (vector_extract 10539 (v4i32 (insert_subvector 10540 (undef), 10541 (v2i32 (int_aarch64_neon_sqrdmulh 10542 (v2i32 V64:$Rn), 10543 (v2i32 (AArch64duplane32 10544 (v4i32 V128:$Rm), 10545 VectorIndexS:$idx)))), 10546 (i64 0))), 10547 (i64 0))))), 10548 (EXTRACT_SUBREG 10549 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 10550 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 10551 FPR32Op:$Rd, 10552 ssub)), 10553 V64:$Rn, 10554 V128:$Rm, 10555 VectorIndexS:$idx)), 10556 ssub)>; 10557 10558 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10559 V128, V128, V128, VectorIndexS, 10560 asm, ".4s", ".4s", ".4s", ".s", 10561 [(set (v4i32 V128:$dst), 10562 (Accum (v4i32 V128:$Rd), 10563 (v4i32 (int_aarch64_neon_sqrdmulh 10564 (v4i32 V128:$Rn), 10565 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10566 VectorIndexS:$idx))))))]> { 10567 bits<2> idx; 10568 let Inst{11} = idx{1}; 10569 let Inst{21} = idx{0}; 10570 } 10571 10572 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10573 // an intermediate EXTRACT_SUBREG would be untyped. 10574 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10575 (i32 (vector_extract 10576 (v4i32 (int_aarch64_neon_sqrdmulh 10577 (v4i32 V128:$Rn), 10578 (v4i32 (AArch64duplane32 10579 (v4i32 V128:$Rm), 10580 VectorIndexS:$idx)))), 10581 (i64 0))))), 10582 (EXTRACT_SUBREG 10583 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 10584 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 10585 FPR32Op:$Rd, 10586 ssub)), 10587 V128:$Rn, 10588 V128:$Rm, 10589 VectorIndexS:$idx)), 10590 ssub)>; 10591 10592 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10593 FPR16Op, FPR16Op, V128_lo, 10594 VectorIndexH, asm, ".h", "", "", ".h", 10595 []> { 10596 bits<3> idx; 10597 let Inst{11} = idx{2}; 10598 let Inst{21} = idx{1}; 10599 let Inst{20} = idx{0}; 10600 } 10601 10602 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10603 FPR32Op, FPR32Op, V128, VectorIndexS, 10604 asm, ".s", "", "", ".s", 10605 [(set (i32 FPR32Op:$dst), 10606 (Accum (i32 FPR32Op:$Rd), 10607 (i32 (int_aarch64_neon_sqrdmulh 10608 (i32 FPR32Op:$Rn), 10609 (i32 (vector_extract (v4i32 V128:$Rm), 10610 VectorIndexS:$idx))))))]> { 10611 bits<2> idx; 10612 let Inst{11} = idx{1}; 10613 let Inst{21} = idx{0}; 10614 } 10615} 10616} // let Predicates = [HasNeon, HasRDM] 10617 10618//---------------------------------------------------------------------------- 10619// ARMv8.3 Complex ADD/MLA instructions 10620//---------------------------------------------------------------------------- 10621 10622class ComplexRotationOperand<int Angle, int Remainder, string Type> 10623 : AsmOperandClass { 10624 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10625 let DiagnosticType = "InvalidComplexRotation" # Type; 10626 let Name = "ComplexRotation" # Type; 10627} 10628def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10629 SDNodeXForm<imm, [{ 10630 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10631}]>> { 10632 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10633 let PrintMethod = "printComplexRotationOp<90, 0>"; 10634} 10635def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10636 SDNodeXForm<imm, [{ 10637 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10638}]>> { 10639 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10640 let PrintMethod = "printComplexRotationOp<180, 90>"; 10641} 10642let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10643class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10644 RegisterOperand regtype, Operand rottype, 10645 string asm, string kind, list<dag> pattern> 10646 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10647 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10648 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10649 Sched<[WriteV]> { 10650 bits<5> Rd; 10651 bits<5> Rn; 10652 bits<5> Rm; 10653 bits<1> rot; 10654 let Inst{31} = 0; 10655 let Inst{30} = Q; 10656 let Inst{29} = U; 10657 let Inst{28-24} = 0b01110; 10658 let Inst{23-22} = size; 10659 let Inst{21} = 0; 10660 let Inst{20-16} = Rm; 10661 let Inst{15-13} = opcode; 10662 // Non-tied version (FCADD) only has one rotation bit 10663 let Inst{12} = rot; 10664 let Inst{11} = 0; 10665 let Inst{10} = 1; 10666 let Inst{9-5} = Rn; 10667 let Inst{4-0} = Rd; 10668} 10669 10670//8.3 CompNum - Floating-point complex number support 10671multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10672 string asm, SDPatternOperator OpNode>{ 10673 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10674 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10675 asm, ".4h", 10676 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10677 (v4f16 V64:$Rn), 10678 (v4f16 V64:$Rm), 10679 (i32 rottype:$rot)))]>; 10680 10681 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10682 asm, ".8h", 10683 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10684 (v8f16 V128:$Rn), 10685 (v8f16 V128:$Rm), 10686 (i32 rottype:$rot)))]>; 10687 } 10688 10689 let Predicates = [HasComplxNum, HasNEON] in { 10690 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10691 asm, ".2s", 10692 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10693 (v2f32 V64:$Rn), 10694 (v2f32 V64:$Rm), 10695 (i32 rottype:$rot)))]>; 10696 10697 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10698 asm, ".4s", 10699 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10700 (v4f32 V128:$Rn), 10701 (v4f32 V128:$Rm), 10702 (i32 rottype:$rot)))]>; 10703 10704 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10705 asm, ".2d", 10706 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10707 (v2f64 V128:$Rn), 10708 (v2f64 V128:$Rm), 10709 (i32 rottype:$rot)))]>; 10710 } 10711} 10712 10713let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10714class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10715 bits<3> opcode, 10716 RegisterOperand regtype, 10717 Operand rottype, string asm, 10718 string kind, list<dag> pattern> 10719 : I<(outs regtype:$dst), 10720 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10721 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10722 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10723 Sched<[WriteV]> { 10724 bits<5> Rd; 10725 bits<5> Rn; 10726 bits<5> Rm; 10727 bits<2> rot; 10728 let Inst{31} = 0; 10729 let Inst{30} = Q; 10730 let Inst{29} = U; 10731 let Inst{28-24} = 0b01110; 10732 let Inst{23-22} = size; 10733 let Inst{21} = 0; 10734 let Inst{20-16} = Rm; 10735 let Inst{15-13} = opcode; 10736 let Inst{12-11} = rot; 10737 let Inst{10} = 1; 10738 let Inst{9-5} = Rn; 10739 let Inst{4-0} = Rd; 10740} 10741 10742multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10743 Operand rottype, string asm, 10744 SDPatternOperator OpNode> { 10745 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10746 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10747 rottype, asm, ".4h", 10748 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10749 (v4f16 V64:$Rn), 10750 (v4f16 V64:$Rm), 10751 (i32 rottype:$rot)))]>; 10752 10753 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10754 rottype, asm, ".8h", 10755 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10756 (v8f16 V128:$Rn), 10757 (v8f16 V128:$Rm), 10758 (i32 rottype:$rot)))]>; 10759 } 10760 10761 let Predicates = [HasComplxNum, HasNEON] in { 10762 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10763 rottype, asm, ".2s", 10764 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10765 (v2f32 V64:$Rn), 10766 (v2f32 V64:$Rm), 10767 (i32 rottype:$rot)))]>; 10768 10769 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10770 rottype, asm, ".4s", 10771 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10772 (v4f32 V128:$Rn), 10773 (v4f32 V128:$Rm), 10774 (i32 rottype:$rot)))]>; 10775 10776 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10777 rottype, asm, ".2d", 10778 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10779 (v2f64 V128:$Rn), 10780 (v2f64 V128:$Rm), 10781 (i32 rottype:$rot)))]>; 10782 } 10783} 10784 10785let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10786class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10787 bit opc1, bit opc2, RegisterOperand dst_reg, 10788 RegisterOperand lhs_reg, 10789 RegisterOperand rhs_reg, Operand vec_idx, 10790 Operand rottype, string asm, string apple_kind, 10791 string dst_kind, string lhs_kind, 10792 string rhs_kind, list<dag> pattern> 10793 : I<(outs dst_reg:$dst), 10794 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10795 asm, 10796 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10797 "$idx, $rot" # "|" # apple_kind # 10798 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10799 Sched<[WriteV]> { 10800 bits<5> Rd; 10801 bits<5> Rn; 10802 bits<5> Rm; 10803 bits<2> rot; 10804 10805 let Inst{31} = 0; 10806 let Inst{30} = Q; 10807 let Inst{29} = U; 10808 let Inst{28} = Scalar; 10809 let Inst{27-24} = 0b1111; 10810 let Inst{23-22} = size; 10811 // Bit 21 must be set by the derived class. 10812 let Inst{20-16} = Rm; 10813 let Inst{15} = opc1; 10814 let Inst{14-13} = rot; 10815 let Inst{12} = opc2; 10816 // Bit 11 must be set by the derived class. 10817 let Inst{10} = 0; 10818 let Inst{9-5} = Rn; 10819 let Inst{4-0} = Rd; 10820} 10821 10822// The complex instructions index by pairs of elements, so the VectorIndexes 10823// don't match the lane types, and the index bits are different to the other 10824// classes. 10825multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype, 10826 string asm, SDPatternOperator OpNode> { 10827 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10828 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10829 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10830 ".4h", ".h", []> { 10831 bits<1> idx; 10832 let Inst{11} = 0; 10833 let Inst{21} = idx{0}; 10834 } 10835 10836 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10837 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10838 ".8h", ".8h", ".h", []> { 10839 bits<2> idx; 10840 let Inst{11} = idx{1}; 10841 let Inst{21} = idx{0}; 10842 } 10843 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10844 10845 let Predicates = [HasComplxNum, HasNEON] in { 10846 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10847 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10848 ".4s", ".4s", ".s", []> { 10849 bits<1> idx; 10850 let Inst{11} = idx{0}; 10851 let Inst{21} = 0; 10852 } 10853 } // Predicates = [HasComplxNum, HasNEON] 10854} 10855 10856//---------------------------------------------------------------------------- 10857// Crypto extensions 10858//---------------------------------------------------------------------------- 10859 10860let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10861class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10862 list<dag> pat> 10863 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10864 Sched<[WriteV]>{ 10865 bits<5> Rd; 10866 bits<5> Rn; 10867 let Inst{31-16} = 0b0100111000101000; 10868 let Inst{15-12} = opc; 10869 let Inst{11-10} = 0b10; 10870 let Inst{9-5} = Rn; 10871 let Inst{4-0} = Rd; 10872} 10873 10874class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10875 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10876 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10877 10878class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10879 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10880 "$Rd = $dst", 10881 [(set (v16i8 V128:$dst), 10882 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10883 10884let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10885class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10886 dag oops, dag iops, list<dag> pat> 10887 : I<oops, iops, asm, 10888 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10889 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10890 Sched<[WriteV]>{ 10891 bits<5> Rd; 10892 bits<5> Rn; 10893 bits<5> Rm; 10894 let Inst{31-21} = 0b01011110000; 10895 let Inst{20-16} = Rm; 10896 let Inst{15} = 0; 10897 let Inst{14-12} = opc; 10898 let Inst{11-10} = 0b00; 10899 let Inst{9-5} = Rn; 10900 let Inst{4-0} = Rd; 10901} 10902 10903class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10904 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10905 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10906 [(set (v4i32 FPR128:$dst), 10907 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10908 (v4i32 V128:$Rm)))]>; 10909 10910class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10911 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10912 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10913 [(set (v4i32 V128:$dst), 10914 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10915 (v4i32 V128:$Rm)))]>; 10916 10917class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10918 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10919 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10920 [(set (v4i32 FPR128:$dst), 10921 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10922 (v4i32 V128:$Rm)))]>; 10923 10924let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10925class SHA2OpInst<bits<4> opc, string asm, string kind, 10926 string cstr, dag oops, dag iops, 10927 list<dag> pat> 10928 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10929 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10930 Sched<[WriteV]>{ 10931 bits<5> Rd; 10932 bits<5> Rn; 10933 let Inst{31-16} = 0b0101111000101000; 10934 let Inst{15-12} = opc; 10935 let Inst{11-10} = 0b10; 10936 let Inst{9-5} = Rn; 10937 let Inst{4-0} = Rd; 10938} 10939 10940class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10941 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10942 (ins V128:$Rd, V128:$Rn), 10943 [(set (v4i32 V128:$dst), 10944 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10945 10946class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10947 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10948 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10949 10950// Armv8.2-A Crypto extensions 10951class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10952 list<dag> pattern> 10953 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> { 10954 bits<5> Vd; 10955 bits<5> Vn; 10956 let Inst{31-25} = 0b1100111; 10957 let Inst{9-5} = Vn; 10958 let Inst{4-0} = Vd; 10959} 10960 10961class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10962 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 10963 "$Vd = $Vdst", []> { 10964 let Inst{31-25} = 0b1100111; 10965 let Inst{24-21} = 0b0110; 10966 let Inst{20-15} = 0b000001; 10967 let Inst{14} = op0; 10968 let Inst{13-12} = 0b00; 10969 let Inst{11-10} = op1; 10970} 10971class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 10972 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 10973class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 10974 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 10975 10976class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 10977 string asmops, string cst> 10978 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 10979 bits<5> Vm; 10980 let Inst{24-21} = 0b0011; 10981 let Inst{20-16} = Vm; 10982 let Inst{15} = 0b1; 10983 let Inst{14} = op0; 10984 let Inst{13-12} = 0b00; 10985 let Inst{11-10} = op1; 10986} 10987class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 10988 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10989 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 10990class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 10991 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10992 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10993class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 10994 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10995 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 10996class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 10997 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10998 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10999class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11000 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11001 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11002 11003class CryptoRRRR<bits<2>op0, string asm, string asmops> 11004 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11005 asmops, "", []> { 11006 bits<5> Vm; 11007 bits<5> Va; 11008 let Inst{24-23} = 0b00; 11009 let Inst{22-21} = op0; 11010 let Inst{20-16} = Vm; 11011 let Inst{15} = 0b0; 11012 let Inst{14-10} = Va; 11013} 11014class CryptoRRRR_16B<bits<2>op0, string asm> 11015 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11016 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11017} 11018class CryptoRRRR_4S<bits<2>op0, string asm> 11019 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11020 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11021} 11022 11023class CryptoRRRi6<string asm> 11024 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11025 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11026 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11027 bits<6> imm; 11028 bits<5> Vm; 11029 let Inst{24-21} = 0b0100; 11030 let Inst{20-16} = Vm; 11031 let Inst{15-10} = imm; 11032 let Inst{9-5} = Vn; 11033 let Inst{4-0} = Vd; 11034} 11035 11036class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11037 : BaseCryptoV82<(outs V128:$Vdst), 11038 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11039 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11040 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11041 bits<2> imm; 11042 bits<5> Vm; 11043 let Inst{24-21} = 0b0010; 11044 let Inst{20-16} = Vm; 11045 let Inst{15} = 0b1; 11046 let Inst{14} = op0; 11047 let Inst{13-12} = imm; 11048 let Inst{11-10} = op1; 11049} 11050 11051//---------------------------------------------------------------------------- 11052// v8.1 atomic instructions extension: 11053// * CAS 11054// * CASP 11055// * SWP 11056// * LDOPregister<OP>, and aliases STOPregister<OP> 11057 11058// Instruction encodings: 11059// 11060// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11061// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11062// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11063// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11064// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11065// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11066 11067// Instruction syntax: 11068// 11069// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11070// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11071// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11072// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11073// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11074// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11075// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11076// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11077// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11078// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11079 11080let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11081class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11082 string cstr, list<dag> pattern> 11083 : I<oops, iops, asm, operands, cstr, pattern> { 11084 bits<2> Sz; 11085 bit NP; 11086 bit Acq; 11087 bit Rel; 11088 bits<5> Rs; 11089 bits<5> Rn; 11090 bits<5> Rt; 11091 let Inst{31-30} = Sz; 11092 let Inst{29-24} = 0b001000; 11093 let Inst{23} = NP; 11094 let Inst{22} = Acq; 11095 let Inst{21} = 0b1; 11096 let Inst{20-16} = Rs; 11097 let Inst{15} = Rel; 11098 let Inst{14-10} = 0b11111; 11099 let Inst{9-5} = Rn; 11100 let Inst{4-0} = Rt; 11101 let Predicates = [HasLSE]; 11102} 11103 11104class BaseCAS<string order, string size, RegisterClass RC> 11105 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11106 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11107 "$out = $Rs",[]>, 11108 Sched<[WriteAtomic]> { 11109 let NP = 1; 11110} 11111 11112multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11113 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11114 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11115 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11116 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11117} 11118 11119class BaseCASP<string order, string size, RegisterOperand RC> 11120 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11121 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11122 "$out = $Rs",[]>, 11123 Sched<[WriteAtomic]> { 11124 let NP = 0; 11125} 11126 11127multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11128 let Sz = 0b00, Acq = Acq, Rel = Rel in 11129 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11130 let Sz = 0b01, Acq = Acq, Rel = Rel in 11131 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11132} 11133 11134let Predicates = [HasLSE] in 11135class BaseSWP<string order, string size, RegisterClass RC> 11136 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11137 "\t$Rs, $Rt, [$Rn]","",[]>, 11138 Sched<[WriteAtomic]> { 11139 bits<2> Sz; 11140 bit Acq; 11141 bit Rel; 11142 bits<5> Rs; 11143 bits<3> opc = 0b000; 11144 bits<5> Rn; 11145 bits<5> Rt; 11146 let Inst{31-30} = Sz; 11147 let Inst{29-24} = 0b111000; 11148 let Inst{23} = Acq; 11149 let Inst{22} = Rel; 11150 let Inst{21} = 0b1; 11151 let Inst{20-16} = Rs; 11152 let Inst{15} = 0b1; 11153 let Inst{14-12} = opc; 11154 let Inst{11-10} = 0b00; 11155 let Inst{9-5} = Rn; 11156 let Inst{4-0} = Rt; 11157 let Predicates = [HasLSE]; 11158} 11159 11160multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11161 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11162 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11163 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11164 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11165} 11166 11167let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11168class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11169 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11170 "\t$Rs, $Rt, [$Rn]","",[]>, 11171 Sched<[WriteAtomic]> { 11172 bits<2> Sz; 11173 bit Acq; 11174 bit Rel; 11175 bits<5> Rs; 11176 bits<3> opc; 11177 bits<5> Rn; 11178 bits<5> Rt; 11179 let Inst{31-30} = Sz; 11180 let Inst{29-24} = 0b111000; 11181 let Inst{23} = Acq; 11182 let Inst{22} = Rel; 11183 let Inst{21} = 0b1; 11184 let Inst{20-16} = Rs; 11185 let Inst{15} = 0b0; 11186 let Inst{14-12} = opc; 11187 let Inst{11-10} = 0b00; 11188 let Inst{9-5} = Rn; 11189 let Inst{4-0} = Rt; 11190 let Predicates = [HasLSE]; 11191} 11192 11193multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11194 string order> { 11195 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11196 def B : BaseLDOPregister<op, order, "b", GPR32>; 11197 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11198 def H : BaseLDOPregister<op, order, "h", GPR32>; 11199 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11200 def W : BaseLDOPregister<op, order, "", GPR32>; 11201 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11202 def X : BaseLDOPregister<op, order, "", GPR64>; 11203} 11204 11205// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11206// complex DAG for DstRHS. 11207let Predicates = [HasLSE] in 11208multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11209 string size, dag SrcRHS, dag DstRHS> { 11210 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11211 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11212 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11213 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11214 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11215 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11216 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11217 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11218 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11219 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11220} 11221 11222multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11223 string size, dag RHS> { 11224 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11225} 11226 11227multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11228 string size, dag LHS, dag RHS> { 11229 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11230} 11231 11232multiclass LDOPregister_patterns<string inst, string op> { 11233 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11234 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11235 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11236 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11237} 11238 11239multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11240 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11241 (i64 GPR64:$Rm), 11242 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11243 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11244 (i32 GPR32:$Rm), 11245 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11246 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11247 (i32 GPR32:$Rm), 11248 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11249 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11250 (i32 GPR32:$Rm), 11251 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11252} 11253 11254let Predicates = [HasLSE] in 11255multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11256 string size, dag OLD, dag NEW> { 11257 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11258 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11259 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11260 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11261 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11262 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11263 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11264 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11265 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11266 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11267} 11268 11269multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11270 string size, dag OLD, dag NEW> { 11271 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11272} 11273 11274multiclass CASregister_patterns<string inst, string op> { 11275 defm : CASregister_patterns_ord<inst, "X", op, "64", 11276 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11277 defm : CASregister_patterns_ord<inst, "W", op, "32", 11278 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11279 defm : CASregister_patterns_ord<inst, "H", op, "16", 11280 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11281 defm : CASregister_patterns_ord<inst, "B", op, "8", 11282 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11283} 11284 11285let Predicates = [HasLSE] in 11286class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11287 Instruction inst> : 11288 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11289 11290multiclass STOPregister<string asm, string instr> { 11291 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11292 !cast<Instruction>(instr # "LB")>; 11293 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11294 !cast<Instruction>(instr # "LH")>; 11295 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11296 !cast<Instruction>(instr # "LW")>; 11297 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11298 !cast<Instruction>(instr # "LX")>; 11299 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11300 !cast<Instruction>(instr # "B")>; 11301 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11302 !cast<Instruction>(instr # "H")>; 11303 def : BaseSTOPregister<asm, GPR32, WZR, 11304 !cast<Instruction>(instr # "W")>; 11305 def : BaseSTOPregister<asm, GPR64, XZR, 11306 !cast<Instruction>(instr # "X")>; 11307} 11308 11309class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11310 dag iops, dag oops, list<dag> pat> 11311 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11312 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11313 bits<5> Rt; 11314 bits<5> Rn; 11315 let Inst{31-21} = 0b11111000001; 11316 let Inst{15} = 1; 11317 let Inst{14-12} = opc; 11318 let Inst{11-10} = 0b00; 11319 let Inst{9-5} = Rn; 11320 let Inst{4-0} = Rt; 11321 11322 let Predicates = [HasV8_7a]; 11323} 11324 11325class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11326 list<dag> pat = []> 11327 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11328 let Inst{20-16} = 0b11111; 11329} 11330 11331class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11332 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11333 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11334 bits<5> Rs; 11335 let Inst{20-16} = Rs; 11336} 11337 11338//---------------------------------------------------------------------------- 11339// Allow the size specifier tokens to be upper case, not just lower. 11340def : TokenAlias<".4B", ".4b">; // Add dot product 11341def : TokenAlias<".8B", ".8b">; 11342def : TokenAlias<".4H", ".4h">; 11343def : TokenAlias<".2S", ".2s">; 11344def : TokenAlias<".1D", ".1d">; 11345def : TokenAlias<".16B", ".16b">; 11346def : TokenAlias<".8H", ".8h">; 11347def : TokenAlias<".4S", ".4s">; 11348def : TokenAlias<".2D", ".2d">; 11349def : TokenAlias<".1Q", ".1q">; 11350def : TokenAlias<".2H", ".2h">; 11351def : TokenAlias<".B", ".b">; 11352def : TokenAlias<".H", ".h">; 11353def : TokenAlias<".S", ".s">; 11354def : TokenAlias<".D", ".d">; 11355def : TokenAlias<".Q", ".q">; 11356