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<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>; 391 392def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>; 393def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>; 394def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>; 395def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>; 396def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>; 397 398def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>; 399def am_indexeds9s128 : ComplexPattern<iPTR, 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_0Operand : AsmImmRange<0, 0>; 725def Imm0_1Operand : AsmImmRange<0, 1>; 726def Imm0_3Operand : AsmImmRange<0, 3>; 727def Imm0_7Operand : AsmImmRange<0, 7>; 728def Imm0_15Operand : AsmImmRange<0, 15>; 729def Imm0_31Operand : AsmImmRange<0, 31>; 730def Imm0_63Operand : AsmImmRange<0, 63>; 731 732def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 733 return (((uint32_t)Imm) < 8); 734}]> { 735 let EncoderMethod = "getVecShiftL8OpValue"; 736 let DecoderMethod = "DecodeVecShiftL8Imm"; 737 let ParserMatchClass = Imm0_7Operand; 738} 739def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 740 return (((uint32_t)Imm) < 16); 741}]> { 742 let EncoderMethod = "getVecShiftL16OpValue"; 743 let DecoderMethod = "DecodeVecShiftL16Imm"; 744 let ParserMatchClass = Imm0_15Operand; 745} 746def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 747 return (((uint32_t)Imm) < 32); 748}]> { 749 let EncoderMethod = "getVecShiftL32OpValue"; 750 let DecoderMethod = "DecodeVecShiftL32Imm"; 751 let ParserMatchClass = Imm0_31Operand; 752} 753def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 754 return (((uint32_t)Imm) < 64); 755}]> { 756 let EncoderMethod = "getVecShiftL64OpValue"; 757 let DecoderMethod = "DecodeVecShiftL64Imm"; 758 let ParserMatchClass = Imm0_63Operand; 759} 760 761// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 762// (ImmLeaf) 763def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 764 return (((uint32_t)Imm) < 8); 765}]> { 766 let EncoderMethod = "getVecShiftL8OpValue"; 767 let DecoderMethod = "DecodeVecShiftL8Imm"; 768 let ParserMatchClass = Imm0_7Operand; 769} 770def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 771 return (((uint32_t)Imm) < 16); 772}]> { 773 let EncoderMethod = "getVecShiftL16OpValue"; 774 let DecoderMethod = "DecodeVecShiftL16Imm"; 775 let ParserMatchClass = Imm0_15Operand; 776} 777def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 778 return (((uint32_t)Imm) < 32); 779}]> { 780 let EncoderMethod = "getVecShiftL32OpValue"; 781 let DecoderMethod = "DecodeVecShiftL32Imm"; 782 let ParserMatchClass = Imm0_31Operand; 783} 784def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 785 return (((uint32_t)Imm) < 64); 786}]> { 787 let EncoderMethod = "getVecShiftL64OpValue"; 788 let DecoderMethod = "DecodeVecShiftL64Imm"; 789 let ParserMatchClass = Imm0_63Operand; 790} 791 792// Crazy immediate formats used by 32-bit and 64-bit logical immediate 793// instructions for splatting repeating bit patterns across the immediate. 794def logical_imm32_XFORM : SDNodeXForm<imm, [{ 795 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 796 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 797}]>; 798def logical_imm64_XFORM : SDNodeXForm<imm, [{ 799 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 800 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 801}]>; 802 803def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 804 GISDNodeXFormEquiv<logical_imm32_XFORM>; 805def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 806 GISDNodeXFormEquiv<logical_imm64_XFORM>; 807 808let DiagnosticType = "LogicalSecondSource" in { 809 def LogicalImm32Operand : AsmOperandClass { 810 let Name = "LogicalImm32"; 811 let PredicateMethod = "isLogicalImm<int32_t>"; 812 let RenderMethod = "addLogicalImmOperands<int32_t>"; 813 } 814 def LogicalImm64Operand : AsmOperandClass { 815 let Name = "LogicalImm64"; 816 let PredicateMethod = "isLogicalImm<int64_t>"; 817 let RenderMethod = "addLogicalImmOperands<int64_t>"; 818 } 819 def LogicalImm32NotOperand : AsmOperandClass { 820 let Name = "LogicalImm32Not"; 821 let PredicateMethod = "isLogicalImm<int32_t>"; 822 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 823 } 824 def LogicalImm64NotOperand : AsmOperandClass { 825 let Name = "LogicalImm64Not"; 826 let PredicateMethod = "isLogicalImm<int64_t>"; 827 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 828 } 829} 830def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 831 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 832}], logical_imm32_XFORM> { 833 let PrintMethod = "printLogicalImm<int32_t>"; 834 let ParserMatchClass = LogicalImm32Operand; 835} 836def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 837 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 838}], logical_imm64_XFORM> { 839 let PrintMethod = "printLogicalImm<int64_t>"; 840 let ParserMatchClass = LogicalImm64Operand; 841} 842def logical_imm32_not : Operand<i32> { 843 let ParserMatchClass = LogicalImm32NotOperand; 844} 845def logical_imm64_not : Operand<i64> { 846 let ParserMatchClass = LogicalImm64NotOperand; 847} 848 849// immXX_0_65535 predicates - True if the immediate is in the range [0,65535]. 850let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 851def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{ 852 return ((uint32_t)Imm) < 65536; 853}]>; 854 855def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{ 856 return ((uint64_t)Imm) < 65536; 857}]>; 858} 859 860// imm0_255 predicate - True if the immediate is in the range [0,255]. 861def Imm0_255Operand : AsmImmRange<0,255>; 862 863def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 864 return ((uint32_t)Imm) < 256; 865}]> { 866 let ParserMatchClass = Imm0_255Operand; 867 let PrintMethod = "printImm"; 868} 869 870// imm0_127 predicate - True if the immediate is in the range [0,127] 871def Imm0_127Operand : AsmImmRange<0, 127>; 872def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 873 return ((uint32_t)Imm) < 128; 874}]> { 875 let ParserMatchClass = Imm0_127Operand; 876 let PrintMethod = "printImm"; 877} 878 879def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 880 return ((uint64_t)Imm) < 128; 881}]> { 882 let ParserMatchClass = Imm0_127Operand; 883 let PrintMethod = "printImm"; 884} 885 886// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 887// for all shift-amounts. 888 889// imm0_63 predicate - True if the immediate is in the range [0,63] 890def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 891 return ((uint64_t)Imm) < 64; 892}]> { 893 let ParserMatchClass = Imm0_63Operand; 894} 895 896def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 897 return ((uint64_t)Imm) < 64; 898}]> { 899 let ParserMatchClass = Imm0_63Operand; 900} 901 902// imm0_31 predicate - True if the immediate is in the range [0,31] 903def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 904 return ((uint64_t)Imm) < 32; 905}]> { 906 let ParserMatchClass = Imm0_31Operand; 907} 908 909// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 910// instead of Constant (ImmLeaf) 911def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 912 return ((uint64_t)Imm) < 32; 913}]> { 914 let ParserMatchClass = Imm0_31Operand; 915} 916 917// True if the 32-bit immediate is in the range [0,31] 918def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 919 return ((uint64_t)Imm) < 32; 920}]> { 921 let ParserMatchClass = Imm0_31Operand; 922} 923 924// imm0_1 predicate - True if the immediate is in the range [0,1] 925def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 926 return ((uint64_t)Imm) < 2; 927}]> { 928 let ParserMatchClass = Imm0_1Operand; 929} 930 931// timm0_1 - as above, but use TargetConstant (TImmLeaf) 932def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 933 return ((uint64_t)Imm) < 2; 934}]> { 935 let ParserMatchClass = Imm0_1Operand; 936} 937 938// imm0_15 predicate - True if the immediate is in the range [0,15] 939def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 940 return ((uint64_t)Imm) < 16; 941}]> { 942 let ParserMatchClass = Imm0_15Operand; 943} 944 945// imm0_7 predicate - True if the immediate is in the range [0,7] 946def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 947 return ((uint64_t)Imm) < 8; 948}]> { 949 let ParserMatchClass = Imm0_7Operand; 950} 951 952// imm0_3 predicate - True if the immediate is in the range [0,3] 953def imm0_3 : Operand<i64>, ImmLeaf<i64, [{ 954 return ((uint64_t)Imm) < 4; 955}]> { 956 let ParserMatchClass = Imm0_3Operand; 957} 958 959// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 960def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 961 return ((uint32_t)Imm) < 8; 962}]> { 963 let ParserMatchClass = Imm0_7Operand; 964} 965 966// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 967def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 968 return ((uint32_t)Imm) < 16; 969}]> { 970 let ParserMatchClass = Imm0_15Operand; 971} 972 973// An arithmetic shifter operand: 974// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 975// {5-0} - imm6 976class arith_shift<ValueType Ty, int width> : Operand<Ty> { 977 let PrintMethod = "printShifter"; 978 let ParserMatchClass = !cast<AsmOperandClass>( 979 "ArithmeticShifterOperand" # width); 980} 981 982def arith_shift32 : arith_shift<i32, 32>; 983def arith_shift64 : arith_shift<i64, 64>; 984 985class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 986 : Operand<Ty>, 987 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 988 let PrintMethod = "printShiftedRegister"; 989 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 990} 991 992def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 993def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 994 995def gi_arith_shifted_reg32 : 996 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 997 GIComplexPatternEquiv<arith_shifted_reg32>; 998 999def gi_arith_shifted_reg64 : 1000 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 1001 GIComplexPatternEquiv<arith_shifted_reg64>; 1002 1003// An arithmetic shifter operand: 1004// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 1005// {5-0} - imm6 1006class logical_shift<int width> : Operand<i32> { 1007 let PrintMethod = "printShifter"; 1008 let ParserMatchClass = !cast<AsmOperandClass>( 1009 "LogicalShifterOperand" # width); 1010} 1011 1012def logical_shift32 : logical_shift<32>; 1013def logical_shift64 : logical_shift<64>; 1014 1015class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1016 : Operand<Ty>, 1017 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1018 let PrintMethod = "printShiftedRegister"; 1019 let MIOperandInfo = (ops regclass, shiftop); 1020} 1021 1022def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1023def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1024 1025def gi_logical_shifted_reg32 : 1026 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1027 GIComplexPatternEquiv<logical_shifted_reg32>; 1028 1029def gi_logical_shifted_reg64 : 1030 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1031 GIComplexPatternEquiv<logical_shifted_reg64>; 1032 1033// A logical vector shifter operand: 1034// {7-6} - shift type: 00 = lsl 1035// {5-0} - imm6: #0, #8, #16, or #24 1036def logical_vec_shift : Operand<i32> { 1037 let PrintMethod = "printShifter"; 1038 let EncoderMethod = "getVecShifterOpValue"; 1039 let ParserMatchClass = LogicalVecShifterOperand; 1040} 1041 1042// A logical vector half-word shifter operand: 1043// {7-6} - shift type: 00 = lsl 1044// {5-0} - imm6: #0 or #8 1045def logical_vec_hw_shift : Operand<i32> { 1046 let PrintMethod = "printShifter"; 1047 let EncoderMethod = "getVecShifterOpValue"; 1048 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1049} 1050 1051// A vector move shifter operand: 1052// {0} - imm1: #8 or #16 1053def move_vec_shift : Operand<i32> { 1054 let PrintMethod = "printShifter"; 1055 let EncoderMethod = "getMoveVecShifterOpValue"; 1056 let ParserMatchClass = MoveVecShifterOperand; 1057} 1058 1059let DiagnosticType = "AddSubSecondSource" in { 1060 def AddSubImmOperand : AsmOperandClass { 1061 let Name = "AddSubImm"; 1062 let ParserMethod = "tryParseImmWithOptionalShift"; 1063 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1064 } 1065 def AddSubImmNegOperand : AsmOperandClass { 1066 let Name = "AddSubImmNeg"; 1067 let ParserMethod = "tryParseImmWithOptionalShift"; 1068 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1069 } 1070} 1071// An ADD/SUB immediate shifter operand: 1072// second operand: 1073// {7-6} - shift type: 00 = lsl 1074// {5-0} - imm6: #0 or #12 1075class addsub_shifted_imm<ValueType Ty> 1076 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1077 let PrintMethod = "printAddSubImm"; 1078 let EncoderMethod = "getAddSubImmOpValue"; 1079 let ParserMatchClass = AddSubImmOperand; 1080 let MIOperandInfo = (ops i32imm, i32imm); 1081} 1082 1083class addsub_shifted_imm_neg<ValueType Ty> 1084 : Operand<Ty> { 1085 let EncoderMethod = "getAddSubImmOpValue"; 1086 let ParserMatchClass = AddSubImmNegOperand; 1087 let MIOperandInfo = (ops i32imm, i32imm); 1088} 1089 1090def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1091def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1092def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1093def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1094 1095def gi_addsub_shifted_imm32 : 1096 GIComplexOperandMatcher<s32, "selectArithImmed">, 1097 GIComplexPatternEquiv<addsub_shifted_imm32>; 1098 1099def gi_addsub_shifted_imm64 : 1100 GIComplexOperandMatcher<s64, "selectArithImmed">, 1101 GIComplexPatternEquiv<addsub_shifted_imm64>; 1102 1103class neg_addsub_shifted_imm<ValueType Ty> 1104 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1105 let PrintMethod = "printAddSubImm"; 1106 let EncoderMethod = "getAddSubImmOpValue"; 1107 let ParserMatchClass = AddSubImmOperand; 1108 let MIOperandInfo = (ops i32imm, i32imm); 1109} 1110 1111def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1112def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1113 1114def gi_neg_addsub_shifted_imm32 : 1115 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1116 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1117 1118def gi_neg_addsub_shifted_imm64 : 1119 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1120 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1121 1122// An extend operand: 1123// {5-3} - extend type 1124// {2-0} - imm3 1125def arith_extend : Operand<i32> { 1126 let PrintMethod = "printArithExtend"; 1127 let ParserMatchClass = ExtendOperand; 1128} 1129def arith_extend64 : Operand<i32> { 1130 let PrintMethod = "printArithExtend"; 1131 let ParserMatchClass = ExtendOperand64; 1132} 1133 1134// 'extend' that's a lsl of a 64-bit register. 1135def arith_extendlsl64 : Operand<i32> { 1136 let PrintMethod = "printArithExtend"; 1137 let ParserMatchClass = ExtendOperandLSL64; 1138} 1139 1140class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1141 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1142 let PrintMethod = "printExtendedRegister"; 1143 let MIOperandInfo = (ops GPR32, arith_extend); 1144} 1145 1146class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1147 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1148 let PrintMethod = "printExtendedRegister"; 1149 let MIOperandInfo = (ops GPR32, arith_extend64); 1150} 1151 1152def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1153def gi_arith_extended_reg32_i32 : 1154 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1155 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1156 1157def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1158def gi_arith_extended_reg32_i64 : 1159 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1160 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1161 1162def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1163def gi_arith_extended_reg32to64_i64 : 1164 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1165 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1166 1167// Floating-point immediate. 1168 1169def fpimm16XForm : SDNodeXForm<fpimm, [{ 1170 APFloat InVal = N->getValueAPF(); 1171 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1172 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1173 }]>; 1174 1175def fpimm32XForm : SDNodeXForm<fpimm, [{ 1176 APFloat InVal = N->getValueAPF(); 1177 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1178 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1179 }]>; 1180 1181def fpimm64XForm : SDNodeXForm<fpimm, [{ 1182 APFloat InVal = N->getValueAPF(); 1183 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1184 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1185 }]>; 1186 1187def fpimm16 : Operand<f16>, 1188 FPImmLeaf<f16, [{ 1189 return AArch64_AM::getFP16Imm(Imm) != -1; 1190 }], fpimm16XForm> { 1191 let ParserMatchClass = FPImmOperand; 1192 let PrintMethod = "printFPImmOperand"; 1193} 1194 1195def fpimm32 : Operand<f32>, 1196 FPImmLeaf<f32, [{ 1197 return AArch64_AM::getFP32Imm(Imm) != -1; 1198 }], fpimm32XForm> { 1199 let ParserMatchClass = FPImmOperand; 1200 let PrintMethod = "printFPImmOperand"; 1201} 1202def fpimm64 : Operand<f64>, 1203 FPImmLeaf<f64, [{ 1204 return AArch64_AM::getFP64Imm(Imm) != -1; 1205 }], fpimm64XForm> { 1206 let ParserMatchClass = FPImmOperand; 1207 let PrintMethod = "printFPImmOperand"; 1208} 1209 1210def fpimm8 : Operand<i32> { 1211 let ParserMatchClass = FPImmOperand; 1212 let PrintMethod = "printFPImmOperand"; 1213} 1214 1215def fpimm0 : FPImmLeaf<fAny, [{ 1216 return Imm.isExactlyValue(+0.0); 1217}]>; 1218 1219def fpimm_half : FPImmLeaf<fAny, [{ 1220 return Imm.isExactlyValue(+0.5); 1221}]>; 1222 1223def fpimm_one : FPImmLeaf<fAny, [{ 1224 return Imm.isExactlyValue(+1.0); 1225}]>; 1226 1227def fpimm_two : FPImmLeaf<fAny, [{ 1228 return Imm.isExactlyValue(+2.0); 1229}]>; 1230 1231def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1232 GISDNodeXFormEquiv<fpimm16XForm>; 1233def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1234 GISDNodeXFormEquiv<fpimm32XForm>; 1235def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1236 GISDNodeXFormEquiv<fpimm64XForm>; 1237 1238// Vector lane operands 1239class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1240 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1241 let DiagnosticType = "Invalid" # Name; 1242 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1243 let RenderMethod = "addVectorIndexOperands"; 1244} 1245 1246class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1247 : Operand<ty> { 1248 let ParserMatchClass = mc; 1249 let PrintMethod = "printVectorIndex"; 1250} 1251 1252multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1253 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1254 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1255} 1256 1257def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1258def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1259def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1260def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1261def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1262def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1263 1264defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1265 [{ return ((uint64_t)Imm) == 0; }]>; 1266defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1267 [{ return ((uint64_t)Imm) == 1; }]>; 1268defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1269 [{ return ((uint64_t)Imm) < 16; }]>; 1270defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1271 [{ return ((uint64_t)Imm) < 8; }]>; 1272defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1273 [{ return ((uint64_t)Imm) < 4; }]>; 1274defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1275 [{ return ((uint64_t)Imm) < 2; }]>; 1276 1277defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1278 [{ return ((uint64_t)Imm) == 1; }]>; 1279defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1280 [{ return ((uint64_t)Imm) < 16; }]>; 1281defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1282 [{ return ((uint64_t)Imm) < 8; }]>; 1283defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1284 [{ return ((uint64_t)Imm) < 4; }]>; 1285defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1286 [{ return ((uint64_t)Imm) < 2; }]>; 1287 1288def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1289def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1290def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1291def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1292def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1293 1294defm sve_elm_idx_extdup_b 1295 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1296 [{ return ((uint64_t)Imm) < 64; }]>; 1297defm sve_elm_idx_extdup_h 1298 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1299 [{ return ((uint64_t)Imm) < 32; }]>; 1300defm sve_elm_idx_extdup_s 1301 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1302 [{ return ((uint64_t)Imm) < 16; }]>; 1303defm sve_elm_idx_extdup_d 1304 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1305 [{ return ((uint64_t)Imm) < 8; }]>; 1306defm sve_elm_idx_extdup_q 1307 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1308 [{ return ((uint64_t)Imm) < 4; }]>; 1309 1310def sme_elm_idx0_0 : Operand<i64>, ImmLeaf<i64, [{ 1311 return ((uint64_t)Imm) == 0; 1312}]> { 1313 let ParserMatchClass = Imm0_0Operand; 1314 let PrintMethod = "printMatrixIndex"; 1315} 1316def sme_elm_idx0_1 : Operand<i64>, ImmLeaf<i64, [{ 1317 return ((uint64_t)Imm) <= 1; 1318}]> { 1319 let ParserMatchClass = Imm0_1Operand; 1320 let PrintMethod = "printMatrixIndex"; 1321} 1322def sme_elm_idx0_3 : Operand<i64>, ImmLeaf<i64, [{ 1323 return ((uint64_t)Imm) <= 3; 1324}]> { 1325 let ParserMatchClass = Imm0_3Operand; 1326 let PrintMethod = "printMatrixIndex"; 1327} 1328def sme_elm_idx0_7 : Operand<i64>, ImmLeaf<i64, [{ 1329 return ((uint64_t)Imm) <= 7; 1330}]> { 1331 let ParserMatchClass = Imm0_7Operand; 1332 let PrintMethod = "printMatrixIndex"; 1333} 1334def sme_elm_idx0_15 : Operand<i64>, ImmLeaf<i64, [{ 1335 return ((uint64_t)Imm) <= 15; 1336}]> { 1337 let ParserMatchClass = Imm0_15Operand; 1338 let PrintMethod = "printMatrixIndex"; 1339} 1340 1341// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1342// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1343// are encoded as the eight bit value 'abcdefgh'. 1344def simdimmtype10 : Operand<i32>, 1345 FPImmLeaf<f64, [{ 1346 return AArch64_AM::isAdvSIMDModImmType10( 1347 Imm.bitcastToAPInt().getZExtValue()); 1348 }], SDNodeXForm<fpimm, [{ 1349 APFloat InVal = N->getValueAPF(); 1350 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1351 .bitcastToAPInt() 1352 .getZExtValue()); 1353 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1354 }]>> { 1355 let ParserMatchClass = SIMDImmType10Operand; 1356 let PrintMethod = "printSIMDType10Operand"; 1357} 1358 1359 1360//--- 1361// System management 1362//--- 1363 1364// Base encoding for system instruction operands. 1365let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1366class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1367 list<dag> pattern = []> 1368 : I<oops, iops, asm, operands, "", pattern> { 1369 let Inst{31-22} = 0b1101010100; 1370 let Inst{21} = L; 1371} 1372 1373// System instructions which do not have an Rt register. 1374class SimpleSystemI<bit L, dag iops, string asm, string operands, 1375 list<dag> pattern = []> 1376 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1377 let Inst{4-0} = 0b11111; 1378} 1379 1380// System instructions which have an Rt register. 1381class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1382 list<dag> pattern = []> 1383 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1384 Sched<[WriteSys]> { 1385 bits<5> Rt; 1386 let Inst{4-0} = Rt; 1387} 1388 1389// System instructions for transactional memory extension 1390class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1391 string asm, string operands, list<dag> pattern> 1392 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1393 Sched<[WriteSys]> { 1394 let Inst{20-12} = 0b000110011; 1395 let Inst{11-8} = CRm; 1396 let Inst{7-5} = op2; 1397 let DecoderMethod = ""; 1398 1399 let mayLoad = 1; 1400 let mayStore = 1; 1401} 1402 1403// System instructions for transactional memory - single input operand 1404class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1405 : TMBaseSystemI<0b1, CRm, 0b011, 1406 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1407 bits<5> Rt; 1408 let Inst{4-0} = Rt; 1409} 1410 1411// System instructions that pass a register argument 1412// This class assumes the register is for input rather than output. 1413class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1414 list<dag> pattern = []> 1415 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1416 let Inst{20-12} = 0b000110001; 1417 let Inst{11-8} = CRm; 1418 let Inst{7-5} = Op2; 1419} 1420 1421// System instructions for transactional memory - no operand 1422class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1423 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1424 let Inst{4-0} = 0b11111; 1425} 1426 1427// System instructions for exit from transactions 1428class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1429 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1430 Sched<[WriteSys]> { 1431 bits<16> imm; 1432 let Inst{31-24} = 0b11010100; 1433 let Inst{23-21} = op1; 1434 let Inst{20-5} = imm; 1435 let Inst{4-0} = 0b00000; 1436} 1437 1438// Hint instructions that take both a CRm and a 3-bit immediate. 1439// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1440// model patterns with sufficiently fine granularity 1441let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1442 class HintI<string mnemonic> 1443 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1444 [(int_aarch64_hint imm0_127:$imm)]>, 1445 Sched<[WriteHint]> { 1446 bits <7> imm; 1447 let Inst{20-12} = 0b000110010; 1448 let Inst{11-5} = imm; 1449 } 1450 1451// System instructions taking a single literal operand which encodes into 1452// CRm. op2 differentiates the opcodes. 1453def BarrierAsmOperand : AsmOperandClass { 1454 let Name = "Barrier"; 1455 let ParserMethod = "tryParseBarrierOperand"; 1456} 1457def barrier_op : Operand<i32> { 1458 let PrintMethod = "printBarrierOption"; 1459 let ParserMatchClass = BarrierAsmOperand; 1460} 1461def BarriernXSAsmOperand : AsmOperandClass { 1462 let Name = "BarriernXS"; 1463 let ParserMethod = "tryParseBarriernXSOperand"; 1464} 1465def barrier_nxs_op : Operand<i32> { 1466 let PrintMethod = "printBarriernXSOption"; 1467 let ParserMatchClass = BarriernXSAsmOperand; 1468} 1469class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1470 list<dag> pattern = []> 1471 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1472 Sched<[WriteBarrier]> { 1473 bits<4> CRm; 1474 let Inst{20-12} = 0b000110011; 1475 let Inst{11-8} = CRm; 1476 let Inst{7-5} = opc; 1477} 1478 1479class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1480 : SimpleSystemI<0, (ins), asm, "", pattern>, 1481 Sched<[]> { 1482 bits<4> CRm; 1483 let CRm = 0b0011; 1484 let Inst{31-12} = 0b11010101000000110010; 1485 let Inst{11-8} = CRm; 1486 let Inst{7-5} = op2; 1487 let Inst{4-0} = 0b11111; 1488} 1489 1490// MRS/MSR system instructions. These have different operand classes because 1491// a different subset of registers can be accessed through each instruction. 1492def MRSSystemRegisterOperand : AsmOperandClass { 1493 let Name = "MRSSystemRegister"; 1494 let ParserMethod = "tryParseSysReg"; 1495 let DiagnosticType = "MRS"; 1496} 1497// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1498def mrs_sysreg_op : Operand<i32> { 1499 let ParserMatchClass = MRSSystemRegisterOperand; 1500 let DecoderMethod = "DecodeMRSSystemRegister"; 1501 let PrintMethod = "printMRSSystemRegister"; 1502} 1503 1504def MSRSystemRegisterOperand : AsmOperandClass { 1505 let Name = "MSRSystemRegister"; 1506 let ParserMethod = "tryParseSysReg"; 1507 let DiagnosticType = "MSR"; 1508} 1509def msr_sysreg_op : Operand<i32> { 1510 let ParserMatchClass = MSRSystemRegisterOperand; 1511 let DecoderMethod = "DecodeMSRSystemRegister"; 1512 let PrintMethod = "printMSRSystemRegister"; 1513} 1514 1515def PSBHintOperand : AsmOperandClass { 1516 let Name = "PSBHint"; 1517 let ParserMethod = "tryParsePSBHint"; 1518} 1519def psbhint_op : Operand<i32> { 1520 let ParserMatchClass = PSBHintOperand; 1521 let PrintMethod = "printPSBHintOp"; 1522 let MCOperandPredicate = [{ 1523 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1524 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1525 if (!MCOp.isImm()) 1526 return false; 1527 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1528 }]; 1529} 1530 1531def BTIHintOperand : AsmOperandClass { 1532 let Name = "BTIHint"; 1533 let ParserMethod = "tryParseBTIHint"; 1534} 1535def btihint_op : Operand<i32> { 1536 let ParserMatchClass = BTIHintOperand; 1537 let PrintMethod = "printBTIHintOp"; 1538 let MCOperandPredicate = [{ 1539 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1540 if (!MCOp.isImm()) 1541 return false; 1542 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1543 }]; 1544} 1545 1546class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1547 "mrs", "\t$Rt, $systemreg"> { 1548 bits<16> systemreg; 1549 let Inst{20-5} = systemreg; 1550 let DecoderNamespace = "Fallback"; 1551 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1552 // require doing this. The alternative was to explicitly model each one, but 1553 // it feels like it is unnecessary because it seems there are no negative 1554 // consequences setting these flags for all. 1555 let Defs = [NZCV]; 1556} 1557 1558// FIXME: Some of these def NZCV, others don't. Best way to model that? 1559// Explicitly modeling each of the system register as a register class 1560// would do it, but feels like overkill at this point. 1561class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1562 "msr", "\t$systemreg, $Rt"> { 1563 bits<16> systemreg; 1564 let Inst{20-5} = systemreg; 1565 let DecoderNamespace = "Fallback"; 1566} 1567 1568def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1569 let Name = "SystemPStateFieldWithImm0_15"; 1570 let ParserMethod = "tryParseSysReg"; 1571} 1572def pstatefield4_op : Operand<i32> { 1573 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1574 let PrintMethod = "printSystemPStateField"; 1575} 1576 1577// Instructions to modify PSTATE, no input reg 1578let Defs = [NZCV] in 1579class PstateWriteSimple<dag iops, string asm, string operands> 1580 : SimpleSystemI<0, iops, asm, operands> { 1581 1582 let Inst{20-19} = 0b00; 1583 let Inst{15-12} = 0b0100; 1584} 1585 1586class MSRpstateImm0_15 1587 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1588 "\t$pstatefield, $imm">, 1589 Sched<[WriteSys]> { 1590 1591 bits<6> pstatefield; 1592 bits<4> imm; 1593 let Inst{18-16} = pstatefield{5-3}; 1594 let Inst{11-8} = imm; 1595 let Inst{7-5} = pstatefield{2-0}; 1596 1597 let DecoderMethod = "DecodeSystemPStateInstruction"; 1598 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1599 // Fail the decoder should attempt to decode the instruction as MSRI. 1600 let hasCompleteDecoder = 0; 1601} 1602 1603def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1604 let Name = "SystemPStateFieldWithImm0_1"; 1605 let ParserMethod = "tryParseSysReg"; 1606} 1607def pstatefield1_op : Operand<i32> { 1608 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1609 let PrintMethod = "printSystemPStateField"; 1610} 1611 1612class MSRpstateImm0_1 1613 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1614 "\t$pstatefield, $imm">, 1615 Sched<[WriteSys]> { 1616 1617 bits<6> pstatefield; 1618 bit imm; 1619 let Inst{18-16} = pstatefield{5-3}; 1620 let Inst{11-9} = 0b000; 1621 let Inst{8} = imm; 1622 let Inst{7-5} = pstatefield{2-0}; 1623 1624 let DecoderMethod = "DecodeSystemPStateInstruction"; 1625 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1626 // Fail the decoder should attempt to decode the instruction as MSRI. 1627 let hasCompleteDecoder = 0; 1628} 1629 1630// SYS and SYSL generic system instructions. 1631def SysCRAsmOperand : AsmOperandClass { 1632 let Name = "SysCR"; 1633 let ParserMethod = "tryParseSysCROperand"; 1634} 1635 1636def sys_cr_op : Operand<i32> { 1637 let PrintMethod = "printSysCROperand"; 1638 let ParserMatchClass = SysCRAsmOperand; 1639} 1640 1641class SystemXtI<bit L, string asm> 1642 : RtSystemI<L, (outs), 1643 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1644 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1645 bits<3> op1; 1646 bits<4> Cn; 1647 bits<4> Cm; 1648 bits<3> op2; 1649 let Inst{20-19} = 0b01; 1650 let Inst{18-16} = op1; 1651 let Inst{15-12} = Cn; 1652 let Inst{11-8} = Cm; 1653 let Inst{7-5} = op2; 1654} 1655 1656class SystemLXtI<bit L, string asm> 1657 : RtSystemI<L, (outs), 1658 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1659 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1660 bits<3> op1; 1661 bits<4> Cn; 1662 bits<4> Cm; 1663 bits<3> op2; 1664 let Inst{20-19} = 0b01; 1665 let Inst{18-16} = op1; 1666 let Inst{15-12} = Cn; 1667 let Inst{11-8} = Cm; 1668 let Inst{7-5} = op2; 1669} 1670 1671 1672// Branch (register) instructions: 1673// 1674// case opc of 1675// 0001 blr 1676// 0000 br 1677// 0101 dret 1678// 0100 eret 1679// 0010 ret 1680// otherwise UNDEFINED 1681class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1682 string operands, list<dag> pattern> 1683 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1684 let Inst{31-25} = 0b1101011; 1685 let Inst{24-21} = opc; 1686 let Inst{20-16} = 0b11111; 1687 let Inst{15-10} = 0b000000; 1688 let Inst{4-0} = 0b00000; 1689} 1690 1691class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1692 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1693 bits<5> Rn; 1694 let Inst{9-5} = Rn; 1695} 1696 1697let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1698class SpecialReturn<bits<4> opc, string asm> 1699 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1700 let Inst{9-5} = 0b11111; 1701} 1702 1703let mayLoad = 1 in 1704class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1705 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1706 Sched<[]> { 1707 bits<5> Rn; 1708 bits<5> Rt; 1709 let Inst{31-30} = sz; 1710 let Inst{29-10} = 0b11100010111111110000; 1711 let Inst{9-5} = Rn; 1712 let Inst{4-0} = Rt; 1713} 1714 1715class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1716 list<dag> pattern> 1717 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1718 let isAuthenticated = 1; 1719 let Inst{31-25} = 0b1101011; 1720 let Inst{20-11} = 0b1111100001; 1721 let Inst{10} = M; 1722 let Inst{4-0} = 0b11111; 1723} 1724 1725class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1726 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1727 bits<5> Rn; 1728 bits<5> Rm; 1729 let Inst{24-22} = 0b100; 1730 let Inst{21} = op; 1731 let Inst{9-5} = Rn; 1732 let Inst{4-0} = Rm; 1733} 1734 1735class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1736 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1737 bits<5> Rn; 1738 let Inst{24} = 0; 1739 let Inst{23-21} = opc; 1740 let Inst{9-5} = Rn; 1741} 1742 1743let Uses = [LR,SP] in 1744class AuthReturn<bits<3> op, bits<1> M, string asm> 1745 : AuthBase<M, (outs), (ins), asm, "", []> { 1746 let Inst{24} = 0; 1747 let Inst{23-21} = op; 1748 let Inst{9-0} = 0b1111111111; 1749} 1750 1751let mayLoad = 1 in 1752class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1753 string operands, string cstr> 1754 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1755 bits<10> offset; 1756 bits<5> Rn; 1757 bits<5> Rt; 1758 let isAuthenticated = 1; 1759 let Inst{31-24} = 0b11111000; 1760 let Inst{23} = M; 1761 let Inst{22} = offset{9}; 1762 let Inst{21} = 1; 1763 let Inst{20-12} = offset{8-0}; 1764 let Inst{11} = W; 1765 let Inst{10} = 1; 1766 let Inst{9-5} = Rn; 1767 let Inst{4-0} = Rt; 1768 1769 let DecoderMethod = "DecodeAuthLoadInstruction"; 1770} 1771 1772multiclass AuthLoad<bit M, string asm, Operand opr> { 1773 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1774 (ins GPR64sp:$Rn, opr:$offset), 1775 asm, "\t$Rt, [$Rn, $offset]", "">; 1776 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1777 (ins GPR64sp:$Rn, opr:$offset), 1778 asm, "\t$Rt, [$Rn, $offset]!", 1779 "$Rn = $wback,@earlyclobber $wback">; 1780 1781 def : InstAlias<asm # "\t$Rt, [$Rn]", 1782 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1783 1784 def : InstAlias<asm # "\t$Rt, [$wback]!", 1785 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1786} 1787 1788//--- 1789// Conditional branch instruction. 1790//--- 1791 1792// Condition code. 1793// 4-bit immediate. Pretty-printed as <cc> 1794def ccode : Operand<i32> { 1795 let PrintMethod = "printCondCode"; 1796 let ParserMatchClass = CondCode; 1797} 1798def inv_ccode : Operand<i32> { 1799 // AL and NV are invalid in the aliases which use inv_ccode 1800 let PrintMethod = "printInverseCondCode"; 1801 let ParserMatchClass = CondCode; 1802 let MCOperandPredicate = [{ 1803 return MCOp.isImm() && 1804 MCOp.getImm() != AArch64CC::AL && 1805 MCOp.getImm() != AArch64CC::NV; 1806 }]; 1807} 1808 1809// Conditional branch target. 19-bit immediate. The low two bits of the target 1810// offset are implied zero and so are not part of the immediate. 1811def am_brcond : Operand<OtherVT> { 1812 let EncoderMethod = "getCondBranchTargetOpValue"; 1813 let DecoderMethod = "DecodePCRelLabel19"; 1814 let PrintMethod = "printAlignedLabel"; 1815 let ParserMatchClass = PCRelLabel19Operand; 1816 let OperandType = "OPERAND_PCREL"; 1817} 1818 1819class BranchCond<bit bit4, string mnemonic> 1820 : I<(outs), (ins ccode:$cond, am_brcond:$target), 1821 mnemonic, ".$cond\t$target", "", 1822 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 1823 let isBranch = 1; 1824 let isTerminator = 1; 1825 let Uses = [NZCV]; 1826 1827 bits<4> cond; 1828 bits<19> target; 1829 let Inst{31-24} = 0b01010100; 1830 let Inst{23-5} = target; 1831 let Inst{4} = bit4; 1832 let Inst{3-0} = cond; 1833} 1834 1835//--- 1836// Compare-and-branch instructions. 1837//--- 1838class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1839 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1840 asm, "\t$Rt, $target", "", 1841 [(node regtype:$Rt, bb:$target)]>, 1842 Sched<[WriteBr]> { 1843 let isBranch = 1; 1844 let isTerminator = 1; 1845 1846 bits<5> Rt; 1847 bits<19> target; 1848 let Inst{30-25} = 0b011010; 1849 let Inst{24} = op; 1850 let Inst{23-5} = target; 1851 let Inst{4-0} = Rt; 1852} 1853 1854multiclass CmpBranch<bit op, string asm, SDNode node> { 1855 def W : BaseCmpBranch<GPR32, op, asm, node> { 1856 let Inst{31} = 0; 1857 } 1858 def X : BaseCmpBranch<GPR64, op, asm, node> { 1859 let Inst{31} = 1; 1860 } 1861} 1862 1863//--- 1864// Test-bit-and-branch instructions. 1865//--- 1866// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1867// the target offset are implied zero and so are not part of the immediate. 1868def am_tbrcond : Operand<OtherVT> { 1869 let EncoderMethod = "getTestBranchTargetOpValue"; 1870 let PrintMethod = "printAlignedLabel"; 1871 let ParserMatchClass = BranchTarget14Operand; 1872 let OperandType = "OPERAND_PCREL"; 1873} 1874 1875// AsmOperand classes to emit (or not) special diagnostics 1876def TBZImm0_31Operand : AsmOperandClass { 1877 let Name = "TBZImm0_31"; 1878 let PredicateMethod = "isImmInRange<0,31>"; 1879 let RenderMethod = "addImmOperands"; 1880} 1881def TBZImm32_63Operand : AsmOperandClass { 1882 let Name = "Imm32_63"; 1883 let PredicateMethod = "isImmInRange<32,63>"; 1884 let DiagnosticType = "InvalidImm0_63"; 1885 let RenderMethod = "addImmOperands"; 1886} 1887 1888class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1889 return (((uint32_t)Imm) < 32); 1890}]> { 1891 let ParserMatchClass = matcher; 1892} 1893 1894def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1895def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1896 1897def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1898 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1899}]> { 1900 let ParserMatchClass = TBZImm32_63Operand; 1901} 1902 1903class BaseTestBranch<RegisterClass regtype, Operand immtype, 1904 bit op, string asm, SDNode node> 1905 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1906 asm, "\t$Rt, $bit_off, $target", "", 1907 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1908 Sched<[WriteBr]> { 1909 let isBranch = 1; 1910 let isTerminator = 1; 1911 1912 bits<5> Rt; 1913 bits<6> bit_off; 1914 bits<14> target; 1915 1916 let Inst{30-25} = 0b011011; 1917 let Inst{24} = op; 1918 let Inst{23-19} = bit_off{4-0}; 1919 let Inst{18-5} = target; 1920 let Inst{4-0} = Rt; 1921 1922 let DecoderMethod = "DecodeTestAndBranch"; 1923} 1924 1925multiclass TestBranch<bit op, string asm, SDNode node> { 1926 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1927 let Inst{31} = 0; 1928 } 1929 1930 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1931 let Inst{31} = 1; 1932 } 1933 1934 // Alias X-reg with 0-31 imm to W-Reg. 1935 def : InstAlias<asm # "\t$Rd, $imm, $target", 1936 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1937 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1938 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1939 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1940 tbz_imm0_31_diag:$imm, bb:$target)>; 1941} 1942 1943//--- 1944// Unconditional branch (immediate) instructions. 1945//--- 1946def am_b_target : Operand<OtherVT> { 1947 let EncoderMethod = "getBranchTargetOpValue"; 1948 let PrintMethod = "printAlignedLabel"; 1949 let ParserMatchClass = BranchTarget26Operand; 1950 let OperandType = "OPERAND_PCREL"; 1951} 1952def am_bl_target : Operand<i64> { 1953 let EncoderMethod = "getBranchTargetOpValue"; 1954 let PrintMethod = "printAlignedLabel"; 1955 let ParserMatchClass = BranchTarget26Operand; 1956 let OperandType = "OPERAND_PCREL"; 1957} 1958 1959class BImm<bit op, dag iops, string asm, list<dag> pattern> 1960 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1961 bits<26> addr; 1962 let Inst{31} = op; 1963 let Inst{30-26} = 0b00101; 1964 let Inst{25-0} = addr; 1965 1966 let DecoderMethod = "DecodeUnconditionalBranch"; 1967} 1968 1969class BranchImm<bit op, string asm, list<dag> pattern> 1970 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1971class CallImm<bit op, string asm, list<dag> pattern> 1972 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1973 1974//--- 1975// Basic one-operand data processing instructions. 1976//--- 1977 1978let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1979class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1980 SDPatternOperator node> 1981 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1982 [(set regtype:$Rd, (node regtype:$Rn))]>, 1983 Sched<[WriteI, ReadI]> { 1984 bits<5> Rd; 1985 bits<5> Rn; 1986 1987 let Inst{30-13} = 0b101101011000000000; 1988 let Inst{12-10} = opc; 1989 let Inst{9-5} = Rn; 1990 let Inst{4-0} = Rd; 1991} 1992 1993let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1994multiclass OneOperandData<bits<3> opc, string asm, 1995 SDPatternOperator node = null_frag> { 1996 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1997 let Inst{31} = 0; 1998 } 1999 2000 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 2001 let Inst{31} = 1; 2002 } 2003} 2004 2005class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 2006 : BaseOneOperandData<opc, GPR32, asm, node> { 2007 let Inst{31} = 0; 2008} 2009 2010class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 2011 : BaseOneOperandData<opc, GPR64, asm, node> { 2012 let Inst{31} = 1; 2013} 2014 2015class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2016 SDPatternOperator op> 2017 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2018 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2019 Sched<[WriteI, ReadI]> { 2020 bits<5> Rd; 2021 bits<5> Rn; 2022 let Inst{31-15} = 0b11011010110000010; 2023 let Inst{14-12} = opcode_prefix; 2024 let Inst{11-10} = opcode; 2025 let Inst{9-5} = Rn; 2026 let Inst{4-0} = Rd; 2027} 2028 2029class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2030 SDPatternOperator op> 2031 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2032 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2033 Sched<[]> { 2034 bits<5> Rd; 2035 let Inst{31-15} = 0b11011010110000010; 2036 let Inst{14-12} = opcode_prefix; 2037 let Inst{11-10} = opcode; 2038 let Inst{9-5} = 0b11111; 2039 let Inst{4-0} = Rd; 2040} 2041 2042class SignAuthTwoOperand<bits<4> opc, string asm, 2043 SDPatternOperator OpNode> 2044 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2045 asm, "\t$Rd, $Rn, $Rm", "", 2046 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2047 Sched<[WriteI, ReadI, ReadI]> { 2048 bits<5> Rd; 2049 bits<5> Rn; 2050 bits<5> Rm; 2051 let Inst{31-21} = 0b10011010110; 2052 let Inst{20-16} = Rm; 2053 let Inst{15-14} = 0b00; 2054 let Inst{13-10} = opc; 2055 let Inst{9-5} = Rn; 2056 let Inst{4-0} = Rd; 2057} 2058 2059class ClearAuth<bits<1> data, string asm> 2060 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2061 bits<5> Rd; 2062 let Inst{31-11} = 0b110110101100000101000; 2063 let Inst{10} = data; 2064 let Inst{9-5} = 0b11111; 2065 let Inst{4-0} = Rd; 2066} 2067 2068// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2069class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2070 : I<(outs), iops, asm, ops, "", []>, 2071 Sched<[WriteI, ReadI, ReadI]> { 2072 let Uses = [NZCV]; 2073 let Defs = [NZCV]; 2074 bits<5> Rn; 2075 let Inst{31} = sf; 2076 let Inst{30-15} = 0b0111010000000000; 2077 let Inst{14} = sz; 2078 let Inst{13-10} = 0b0010; 2079 let Inst{9-5} = Rn; 2080 let Inst{4-0} = 0b01101; 2081} 2082 2083class FlagRotate<dag iops, string asm, string ops> 2084 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2085 bits<6> imm; 2086 bits<4> mask; 2087 let Inst{20-15} = imm; 2088 let Inst{13-10} = 0b0001; 2089 let Inst{4} = 0b0; 2090 let Inst{3-0} = mask; 2091} 2092 2093//--- 2094// Basic two-operand data processing instructions. 2095//--- 2096class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2097 list<dag> pattern> 2098 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2099 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2100 Sched<[WriteI, ReadI, ReadI]> { 2101 let Uses = [NZCV]; 2102 bits<5> Rd; 2103 bits<5> Rn; 2104 bits<5> Rm; 2105 let Inst{30} = isSub; 2106 let Inst{28-21} = 0b11010000; 2107 let Inst{20-16} = Rm; 2108 let Inst{15-10} = 0; 2109 let Inst{9-5} = Rn; 2110 let Inst{4-0} = Rd; 2111} 2112 2113class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2114 SDNode OpNode> 2115 : BaseBaseAddSubCarry<isSub, regtype, asm, 2116 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2117 2118class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2119 SDNode OpNode> 2120 : BaseBaseAddSubCarry<isSub, regtype, asm, 2121 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2122 (implicit NZCV)]> { 2123 let Defs = [NZCV]; 2124} 2125 2126multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2127 SDNode OpNode, SDNode OpNode_setflags> { 2128 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2129 let Inst{31} = 0; 2130 let Inst{29} = 0; 2131 } 2132 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2133 let Inst{31} = 1; 2134 let Inst{29} = 0; 2135 } 2136 2137 // Sets flags. 2138 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2139 OpNode_setflags> { 2140 let Inst{31} = 0; 2141 let Inst{29} = 1; 2142 } 2143 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2144 OpNode_setflags> { 2145 let Inst{31} = 1; 2146 let Inst{29} = 1; 2147 } 2148} 2149 2150class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2151 SDPatternOperator OpNode, 2152 RegisterClass in1regtype = regtype, 2153 RegisterClass in2regtype = regtype> 2154 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2155 asm, "\t$Rd, $Rn, $Rm", "", 2156 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2157 bits<5> Rd; 2158 bits<5> Rn; 2159 bits<5> Rm; 2160 let Inst{30-21} = 0b0011010110; 2161 let Inst{20-16} = Rm; 2162 let Inst{15-14} = 0b00; 2163 let Inst{13-10} = opc; 2164 let Inst{9-5} = Rn; 2165 let Inst{4-0} = Rd; 2166} 2167 2168class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2169 SDPatternOperator OpNode> 2170 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2171 let Inst{10} = isSigned; 2172} 2173 2174multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2175 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2176 Sched<[WriteID32, ReadID, ReadID]> { 2177 let Inst{31} = 0; 2178 } 2179 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2180 Sched<[WriteID64, ReadID, ReadID]> { 2181 let Inst{31} = 1; 2182 } 2183} 2184 2185class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2186 SDPatternOperator OpNode = null_frag> 2187 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2188 Sched<[WriteIS, ReadI]> { 2189 let Inst{11-10} = shift_type; 2190} 2191 2192multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2193 def Wr : BaseShift<shift_type, GPR32, asm> { 2194 let Inst{31} = 0; 2195 } 2196 2197 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2198 let Inst{31} = 1; 2199 } 2200 2201 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2202 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2203 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2204 2205 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2206 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2207 2208 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2209 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2210 2211 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2212 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2213 2214 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2215 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2216 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2217 2218 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2219 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2220 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2221} 2222 2223class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2224 : InstAlias<asm#"\t$dst, $src1, $src2", 2225 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2226 2227class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2228 RegisterClass addtype, string asm, 2229 list<dag> pattern> 2230 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2231 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2232 bits<5> Rd; 2233 bits<5> Rn; 2234 bits<5> Rm; 2235 bits<5> Ra; 2236 let Inst{30-24} = 0b0011011; 2237 let Inst{23-21} = opc; 2238 let Inst{20-16} = Rm; 2239 let Inst{15} = isSub; 2240 let Inst{14-10} = Ra; 2241 let Inst{9-5} = Rn; 2242 let Inst{4-0} = Rd; 2243} 2244 2245multiclass MulAccum<bit isSub, string asm> { 2246 // MADD/MSUB generation is decided by MachineCombiner.cpp 2247 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2248 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2249 let Inst{31} = 0; 2250 } 2251 2252 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2253 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2254 let Inst{31} = 1; 2255 } 2256} 2257 2258class WideMulAccum<bit isSub, bits<3> opc, string asm, 2259 SDNode AccNode, SDNode ExtNode> 2260 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2261 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2262 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2263 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2264 let Inst{31} = 1; 2265} 2266 2267class MulHi<bits<3> opc, string asm, SDNode OpNode> 2268 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2269 asm, "\t$Rd, $Rn, $Rm", "", 2270 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2271 Sched<[WriteIM64, ReadIM, ReadIM]> { 2272 bits<5> Rd; 2273 bits<5> Rn; 2274 bits<5> Rm; 2275 let Inst{31-24} = 0b10011011; 2276 let Inst{23-21} = opc; 2277 let Inst{20-16} = Rm; 2278 let Inst{15} = 0; 2279 let Inst{9-5} = Rn; 2280 let Inst{4-0} = Rd; 2281 2282 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2283 // (i.e. all bits 1) but is ignored by the processor. 2284 let PostEncoderMethod = "fixMulHigh"; 2285} 2286 2287class MulAccumWAlias<string asm, Instruction inst> 2288 : InstAlias<asm#"\t$dst, $src1, $src2", 2289 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2290class MulAccumXAlias<string asm, Instruction inst> 2291 : InstAlias<asm#"\t$dst, $src1, $src2", 2292 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2293class WideMulAccumAlias<string asm, Instruction inst> 2294 : InstAlias<asm#"\t$dst, $src1, $src2", 2295 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2296 2297class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2298 SDPatternOperator OpNode, string asm> 2299 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2300 asm, "\t$Rd, $Rn, $Rm", "", 2301 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2302 Sched<[WriteISReg, ReadI, ReadISReg]> { 2303 bits<5> Rd; 2304 bits<5> Rn; 2305 bits<5> Rm; 2306 2307 let Inst{31} = sf; 2308 let Inst{30-21} = 0b0011010110; 2309 let Inst{20-16} = Rm; 2310 let Inst{15-13} = 0b010; 2311 let Inst{12} = C; 2312 let Inst{11-10} = sz; 2313 let Inst{9-5} = Rn; 2314 let Inst{4-0} = Rd; 2315 let Predicates = [HasCRC]; 2316} 2317 2318//--- 2319// Address generation. 2320//--- 2321 2322class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2323 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2324 pattern>, 2325 Sched<[WriteI]> { 2326 bits<5> Xd; 2327 bits<21> label; 2328 let Inst{31} = page; 2329 let Inst{30-29} = label{1-0}; 2330 let Inst{28-24} = 0b10000; 2331 let Inst{23-5} = label{20-2}; 2332 let Inst{4-0} = Xd; 2333 2334 let DecoderMethod = "DecodeAdrInstruction"; 2335} 2336 2337//--- 2338// Move immediate. 2339//--- 2340 2341def movimm32_imm : Operand<i32> { 2342 let ParserMatchClass = AsmImmRange<0, 65535>; 2343 let EncoderMethod = "getMoveWideImmOpValue"; 2344 let PrintMethod = "printImm"; 2345} 2346def movimm32_shift : Operand<i32> { 2347 let PrintMethod = "printShifter"; 2348 let ParserMatchClass = MovImm32ShifterOperand; 2349} 2350def movimm64_shift : Operand<i32> { 2351 let PrintMethod = "printShifter"; 2352 let ParserMatchClass = MovImm64ShifterOperand; 2353} 2354 2355let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2356class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2357 string asm> 2358 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2359 asm, "\t$Rd, $imm$shift", "", []>, 2360 Sched<[WriteImm]> { 2361 bits<5> Rd; 2362 bits<16> imm; 2363 bits<6> shift; 2364 let Inst{30-29} = opc; 2365 let Inst{28-23} = 0b100101; 2366 let Inst{22-21} = shift{5-4}; 2367 let Inst{20-5} = imm; 2368 let Inst{4-0} = Rd; 2369 2370 let DecoderMethod = "DecodeMoveImmInstruction"; 2371} 2372 2373multiclass MoveImmediate<bits<2> opc, string asm> { 2374 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2375 let Inst{31} = 0; 2376 } 2377 2378 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2379 let Inst{31} = 1; 2380 } 2381} 2382 2383let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2384class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2385 string asm> 2386 : I<(outs regtype:$Rd), 2387 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2388 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2389 Sched<[WriteI, ReadI]> { 2390 bits<5> Rd; 2391 bits<16> imm; 2392 bits<6> shift; 2393 let Inst{30-29} = opc; 2394 let Inst{28-23} = 0b100101; 2395 let Inst{22-21} = shift{5-4}; 2396 let Inst{20-5} = imm; 2397 let Inst{4-0} = Rd; 2398 2399 let DecoderMethod = "DecodeMoveImmInstruction"; 2400} 2401 2402multiclass InsertImmediate<bits<2> opc, string asm> { 2403 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2404 let Inst{31} = 0; 2405 } 2406 2407 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2408 let Inst{31} = 1; 2409 } 2410} 2411 2412//--- 2413// Add/Subtract 2414//--- 2415 2416class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2417 string asm_inst, string asm_ops, 2418 dag inputs, dag pattern> 2419 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2420 Sched<[WriteI, ReadI]> { 2421 bits<5> Rd; 2422 bits<5> Rn; 2423 let Inst{30} = isSub; 2424 let Inst{29} = setFlags; 2425 let Inst{28-24} = 0b10001; 2426 let Inst{9-5} = Rn; 2427 let Inst{4-0} = Rd; 2428} 2429 2430class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2431 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2432 string asm_inst, SDPatternOperator OpNode> 2433 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2434 (ins srcRegtype:$Rn, immtype:$imm), 2435 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2436 bits<14> imm; 2437 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2438 let Inst{21-10} = imm{11-0}; 2439 let DecoderMethod = "DecodeAddSubImmShift"; 2440} 2441 2442class BaseAddSubRegPseudo<RegisterClass regtype, 2443 SDPatternOperator OpNode> 2444 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2445 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2446 Sched<[WriteI, ReadI, ReadI]>; 2447 2448class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2449 arith_shifted_reg shifted_regtype, string asm, 2450 SDPatternOperator OpNode> 2451 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2452 asm, "\t$Rd, $Rn, $Rm", "", 2453 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2454 Sched<[WriteISReg, ReadI, ReadISReg]> { 2455 // The operands are in order to match the 'addr' MI operands, so we 2456 // don't need an encoder method and by-name matching. Just use the default 2457 // in-order handling. Since we're using by-order, make sure the names 2458 // do not match. 2459 bits<5> dst; 2460 bits<5> src1; 2461 bits<5> src2; 2462 bits<8> shift; 2463 let Inst{30} = isSub; 2464 let Inst{29} = setFlags; 2465 let Inst{28-24} = 0b01011; 2466 let Inst{23-22} = shift{7-6}; 2467 let Inst{21} = 0; 2468 let Inst{20-16} = src2; 2469 let Inst{15-10} = shift{5-0}; 2470 let Inst{9-5} = src1; 2471 let Inst{4-0} = dst; 2472 2473 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2474} 2475 2476class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2477 RegisterClass src1Regtype, Operand src2Regtype, 2478 string asm, SDPatternOperator OpNode> 2479 : I<(outs dstRegtype:$R1), 2480 (ins src1Regtype:$R2, src2Regtype:$R3), 2481 asm, "\t$R1, $R2, $R3", "", 2482 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2483 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2484 bits<5> Rd; 2485 bits<5> Rn; 2486 bits<5> Rm; 2487 bits<6> ext; 2488 let Inst{30} = isSub; 2489 let Inst{29} = setFlags; 2490 let Inst{28-24} = 0b01011; 2491 let Inst{23-21} = 0b001; 2492 let Inst{20-16} = Rm; 2493 let Inst{15-13} = ext{5-3}; 2494 let Inst{12-10} = ext{2-0}; 2495 let Inst{9-5} = Rn; 2496 let Inst{4-0} = Rd; 2497 2498 let DecoderMethod = "DecodeAddSubERegInstruction"; 2499} 2500 2501let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2502class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2503 RegisterClass src1Regtype, RegisterClass src2Regtype, 2504 Operand ext_op, string asm> 2505 : I<(outs dstRegtype:$Rd), 2506 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2507 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2508 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2509 bits<5> Rd; 2510 bits<5> Rn; 2511 bits<5> Rm; 2512 bits<6> ext; 2513 let Inst{30} = isSub; 2514 let Inst{29} = setFlags; 2515 let Inst{28-24} = 0b01011; 2516 let Inst{23-21} = 0b001; 2517 let Inst{20-16} = Rm; 2518 let Inst{15} = ext{5}; 2519 let Inst{12-10} = ext{2-0}; 2520 let Inst{9-5} = Rn; 2521 let Inst{4-0} = Rd; 2522 2523 let DecoderMethod = "DecodeAddSubERegInstruction"; 2524} 2525 2526// Aliases for register+register add/subtract. 2527class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2528 RegisterClass src1Regtype, RegisterClass src2Regtype, 2529 int shiftExt> 2530 : InstAlias<asm#"\t$dst, $src1, $src2", 2531 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2532 shiftExt)>; 2533 2534multiclass AddSub<bit isSub, string mnemonic, string alias, 2535 SDPatternOperator OpNode = null_frag> { 2536 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2537 // Add/Subtract immediate 2538 // Increase the weight of the immediate variant to try to match it before 2539 // the extended register variant. 2540 // We used to match the register variant before the immediate when the 2541 // register argument could be implicitly zero-extended. 2542 let AddedComplexity = 6 in 2543 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2544 mnemonic, OpNode> { 2545 let Inst{31} = 0; 2546 } 2547 let AddedComplexity = 6 in 2548 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2549 mnemonic, OpNode> { 2550 let Inst{31} = 1; 2551 } 2552 2553 // Add/Subtract register - Only used for CodeGen 2554 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2555 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2556 2557 // Add/Subtract shifted register 2558 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2559 OpNode> { 2560 let Inst{31} = 0; 2561 } 2562 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2563 OpNode> { 2564 let Inst{31} = 1; 2565 } 2566 } 2567 2568 // Add/Subtract extended register 2569 let AddedComplexity = 1, hasSideEffects = 0 in { 2570 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2571 arith_extended_reg32_i32, mnemonic, OpNode> { 2572 let Inst{31} = 0; 2573 } 2574 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2575 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2576 let Inst{31} = 1; 2577 } 2578 } 2579 2580 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2581 arith_extendlsl64, mnemonic> { 2582 // UXTX and SXTX only. 2583 let Inst{14-13} = 0b11; 2584 let Inst{31} = 1; 2585 } 2586 2587 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2588 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2589 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2590 addsub_shifted_imm32_neg:$imm), 0>; 2591 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2592 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2593 addsub_shifted_imm64_neg:$imm), 0>; 2594 2595 // Register/register aliases with no shift when SP is not used. 2596 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2597 GPR32, GPR32, GPR32, 0>; 2598 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2599 GPR64, GPR64, GPR64, 0>; 2600 2601 // Register/register aliases with no shift when either the destination or 2602 // first source register is SP. 2603 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2604 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2605 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2606 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2607 def : AddSubRegAlias<mnemonic, 2608 !cast<Instruction>(NAME#"Xrx64"), 2609 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2610 def : AddSubRegAlias<mnemonic, 2611 !cast<Instruction>(NAME#"Xrx64"), 2612 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2613} 2614 2615multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2616 string alias, string cmpAlias> { 2617 let isCompare = 1, Defs = [NZCV] in { 2618 // Add/Subtract immediate 2619 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2620 mnemonic, OpNode> { 2621 let Inst{31} = 0; 2622 } 2623 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2624 mnemonic, OpNode> { 2625 let Inst{31} = 1; 2626 } 2627 2628 // Add/Subtract register 2629 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2630 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2631 2632 // Add/Subtract shifted register 2633 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2634 OpNode> { 2635 let Inst{31} = 0; 2636 } 2637 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2638 OpNode> { 2639 let Inst{31} = 1; 2640 } 2641 2642 // Add/Subtract extended register 2643 let AddedComplexity = 1 in { 2644 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2645 arith_extended_reg32_i32, mnemonic, OpNode> { 2646 let Inst{31} = 0; 2647 } 2648 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2649 arith_extended_reg32_i64, mnemonic, OpNode> { 2650 let Inst{31} = 1; 2651 } 2652 } 2653 2654 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2655 arith_extendlsl64, mnemonic> { 2656 // UXTX and SXTX only. 2657 let Inst{14-13} = 0b11; 2658 let Inst{31} = 1; 2659 } 2660 } // Defs = [NZCV] 2661 2662 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2663 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2664 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2665 addsub_shifted_imm32_neg:$imm), 0>; 2666 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2667 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2668 addsub_shifted_imm64_neg:$imm), 0>; 2669 2670 // Compare aliases 2671 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2672 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2673 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2674 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2675 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2676 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2677 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2678 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2679 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2680 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2681 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2682 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2683 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2684 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2685 2686 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2687 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2688 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2689 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2690 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2691 2692 // Compare shorthands 2693 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2694 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2695 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2696 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2697 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2698 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2699 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2700 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2701 2702 // Register/register aliases with no shift when SP is not used. 2703 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2704 GPR32, GPR32, GPR32, 0>; 2705 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2706 GPR64, GPR64, GPR64, 0>; 2707 2708 // Register/register aliases with no shift when the first source register 2709 // is SP. 2710 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2711 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2712 def : AddSubRegAlias<mnemonic, 2713 !cast<Instruction>(NAME#"Xrx64"), 2714 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2715} 2716 2717class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2718 : BaseAddSubImm< 2719 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2720 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2721 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2722 bits<6> imm6; 2723 bits<4> imm4; 2724 let Inst{31} = 1; 2725 let Inst{23-22} = 0b10; 2726 let Inst{21-16} = imm6; 2727 let Inst{15-14} = 0b00; 2728 let Inst{13-10} = imm4; 2729 let Unpredictable{15-14} = 0b11; 2730} 2731 2732class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2733 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2734 let Inst{31} = 1; 2735 let Inst{29} = setsFlags; 2736} 2737 2738//--- 2739// Extract 2740//--- 2741def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2742 SDTCisPtrTy<3>]>; 2743def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2744 2745class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2746 list<dag> patterns> 2747 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2748 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2749 Sched<[WriteExtr, ReadExtrHi]> { 2750 bits<5> Rd; 2751 bits<5> Rn; 2752 bits<5> Rm; 2753 bits<6> imm; 2754 2755 let Inst{30-23} = 0b00100111; 2756 let Inst{21} = 0; 2757 let Inst{20-16} = Rm; 2758 let Inst{15-10} = imm; 2759 let Inst{9-5} = Rn; 2760 let Inst{4-0} = Rd; 2761} 2762 2763multiclass ExtractImm<string asm> { 2764 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2765 [(set GPR32:$Rd, 2766 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2767 let Inst{31} = 0; 2768 let Inst{22} = 0; 2769 // imm<5> must be zero. 2770 let imm{5} = 0; 2771 } 2772 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2773 [(set GPR64:$Rd, 2774 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2775 2776 let Inst{31} = 1; 2777 let Inst{22} = 1; 2778 } 2779} 2780 2781//--- 2782// Bitfield 2783//--- 2784 2785let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2786class BaseBitfieldImm<bits<2> opc, 2787 RegisterClass regtype, Operand imm_type, string asm> 2788 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2789 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2790 Sched<[WriteIS, ReadI]> { 2791 bits<5> Rd; 2792 bits<5> Rn; 2793 bits<6> immr; 2794 bits<6> imms; 2795 2796 let Inst{30-29} = opc; 2797 let Inst{28-23} = 0b100110; 2798 let Inst{21-16} = immr; 2799 let Inst{15-10} = imms; 2800 let Inst{9-5} = Rn; 2801 let Inst{4-0} = Rd; 2802} 2803 2804multiclass BitfieldImm<bits<2> opc, string asm> { 2805 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2806 let Inst{31} = 0; 2807 let Inst{22} = 0; 2808 // imms<5> and immr<5> must be zero, else ReservedValue(). 2809 let Inst{21} = 0; 2810 let Inst{15} = 0; 2811 } 2812 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2813 let Inst{31} = 1; 2814 let Inst{22} = 1; 2815 } 2816} 2817 2818let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2819class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2820 RegisterClass regtype, Operand imm_type, string asm> 2821 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2822 imm_type:$imms), 2823 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2824 Sched<[WriteIS, ReadI]> { 2825 bits<5> Rd; 2826 bits<5> Rn; 2827 bits<6> immr; 2828 bits<6> imms; 2829 2830 let Inst{30-29} = opc; 2831 let Inst{28-23} = 0b100110; 2832 let Inst{21-16} = immr; 2833 let Inst{15-10} = imms; 2834 let Inst{9-5} = Rn; 2835 let Inst{4-0} = Rd; 2836} 2837 2838multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2839 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2840 let Inst{31} = 0; 2841 let Inst{22} = 0; 2842 // imms<5> and immr<5> must be zero, else ReservedValue(). 2843 let Inst{21} = 0; 2844 let Inst{15} = 0; 2845 } 2846 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2847 let Inst{31} = 1; 2848 let Inst{22} = 1; 2849 } 2850} 2851 2852//--- 2853// Logical 2854//--- 2855 2856// Logical (immediate) 2857class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2858 RegisterClass sregtype, Operand imm_type, string asm, 2859 list<dag> pattern> 2860 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2861 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2862 Sched<[WriteI, ReadI]> { 2863 bits<5> Rd; 2864 bits<5> Rn; 2865 bits<13> imm; 2866 let Inst{30-29} = opc; 2867 let Inst{28-23} = 0b100100; 2868 let Inst{22} = imm{12}; 2869 let Inst{21-16} = imm{11-6}; 2870 let Inst{15-10} = imm{5-0}; 2871 let Inst{9-5} = Rn; 2872 let Inst{4-0} = Rd; 2873 2874 let DecoderMethod = "DecodeLogicalImmInstruction"; 2875} 2876 2877// Logical (shifted register) 2878class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2879 logical_shifted_reg shifted_regtype, string asm, 2880 list<dag> pattern> 2881 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2882 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2883 Sched<[WriteISReg, ReadI, ReadISReg]> { 2884 // The operands are in order to match the 'addr' MI operands, so we 2885 // don't need an encoder method and by-name matching. Just use the default 2886 // in-order handling. Since we're using by-order, make sure the names 2887 // do not match. 2888 bits<5> dst; 2889 bits<5> src1; 2890 bits<5> src2; 2891 bits<8> shift; 2892 let Inst{30-29} = opc; 2893 let Inst{28-24} = 0b01010; 2894 let Inst{23-22} = shift{7-6}; 2895 let Inst{21} = N; 2896 let Inst{20-16} = src2; 2897 let Inst{15-10} = shift{5-0}; 2898 let Inst{9-5} = src1; 2899 let Inst{4-0} = dst; 2900 2901 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2902} 2903 2904// Aliases for register+register logical instructions. 2905class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2906 : InstAlias<asm#"\t$dst, $src1, $src2", 2907 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2908 2909multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2910 string Alias> { 2911 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2912 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2913 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2914 logical_imm32:$imm))]> { 2915 let Inst{31} = 0; 2916 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2917 } 2918 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2919 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2920 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2921 logical_imm64:$imm))]> { 2922 let Inst{31} = 1; 2923 } 2924 2925 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2926 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2927 logical_imm32_not:$imm), 0>; 2928 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2929 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2930 logical_imm64_not:$imm), 0>; 2931} 2932 2933multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2934 string Alias> { 2935 let isCompare = 1, Defs = [NZCV] in { 2936 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2937 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2938 let Inst{31} = 0; 2939 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2940 } 2941 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2942 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2943 let Inst{31} = 1; 2944 } 2945 } // end Defs = [NZCV] 2946 2947 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2948 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2949 logical_imm32_not:$imm), 0>; 2950 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2951 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2952 logical_imm64_not:$imm), 0>; 2953} 2954 2955class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2956 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2957 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2958 Sched<[WriteI, ReadI, ReadI]>; 2959 2960// Split from LogicalImm as not all instructions have both. 2961multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2962 SDPatternOperator OpNode> { 2963 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2964 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2965 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2966 } 2967 2968 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2969 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2970 logical_shifted_reg32:$Rm))]> { 2971 let Inst{31} = 0; 2972 } 2973 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2974 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2975 logical_shifted_reg64:$Rm))]> { 2976 let Inst{31} = 1; 2977 } 2978 2979 def : LogicalRegAlias<mnemonic, 2980 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2981 def : LogicalRegAlias<mnemonic, 2982 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2983} 2984 2985// Split from LogicalReg to allow setting NZCV Defs 2986multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2987 SDPatternOperator OpNode = null_frag> { 2988 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2989 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2990 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2991 2992 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2993 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2994 let Inst{31} = 0; 2995 } 2996 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2997 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2998 let Inst{31} = 1; 2999 } 3000 } // Defs = [NZCV] 3001 3002 def : LogicalRegAlias<mnemonic, 3003 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3004 def : LogicalRegAlias<mnemonic, 3005 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3006} 3007 3008//--- 3009// Conditionally set flags 3010//--- 3011 3012let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3013class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3014 string mnemonic, SDNode OpNode> 3015 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3016 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3017 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3018 (i32 imm:$cond), NZCV))]>, 3019 Sched<[WriteI, ReadI]> { 3020 let Uses = [NZCV]; 3021 let Defs = [NZCV]; 3022 3023 bits<5> Rn; 3024 bits<5> imm; 3025 bits<4> nzcv; 3026 bits<4> cond; 3027 3028 let Inst{30} = op; 3029 let Inst{29-21} = 0b111010010; 3030 let Inst{20-16} = imm; 3031 let Inst{15-12} = cond; 3032 let Inst{11-10} = 0b10; 3033 let Inst{9-5} = Rn; 3034 let Inst{4} = 0b0; 3035 let Inst{3-0} = nzcv; 3036} 3037 3038let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3039class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3040 SDNode OpNode> 3041 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3042 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3043 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3044 (i32 imm:$cond), NZCV))]>, 3045 Sched<[WriteI, ReadI, ReadI]> { 3046 let Uses = [NZCV]; 3047 let Defs = [NZCV]; 3048 3049 bits<5> Rn; 3050 bits<5> Rm; 3051 bits<4> nzcv; 3052 bits<4> cond; 3053 3054 let Inst{30} = op; 3055 let Inst{29-21} = 0b111010010; 3056 let Inst{20-16} = Rm; 3057 let Inst{15-12} = cond; 3058 let Inst{11-10} = 0b00; 3059 let Inst{9-5} = Rn; 3060 let Inst{4} = 0b0; 3061 let Inst{3-0} = nzcv; 3062} 3063 3064multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3065 // immediate operand variants 3066 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3067 let Inst{31} = 0; 3068 } 3069 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3070 let Inst{31} = 1; 3071 } 3072 // register operand variants 3073 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3074 let Inst{31} = 0; 3075 } 3076 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3077 let Inst{31} = 1; 3078 } 3079} 3080 3081//--- 3082// Conditional select 3083//--- 3084 3085class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3086 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3087 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3088 [(set regtype:$Rd, 3089 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3090 Sched<[WriteI, ReadI, ReadI]> { 3091 let Uses = [NZCV]; 3092 3093 bits<5> Rd; 3094 bits<5> Rn; 3095 bits<5> Rm; 3096 bits<4> cond; 3097 3098 let Inst{30} = op; 3099 let Inst{29-21} = 0b011010100; 3100 let Inst{20-16} = Rm; 3101 let Inst{15-12} = cond; 3102 let Inst{11-10} = op2; 3103 let Inst{9-5} = Rn; 3104 let Inst{4-0} = Rd; 3105} 3106 3107multiclass CondSelect<bit op, bits<2> op2, string asm> { 3108 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3109 let Inst{31} = 0; 3110 } 3111 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3112 let Inst{31} = 1; 3113 } 3114} 3115 3116class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3117 PatFrag frag> 3118 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3119 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3120 [(set regtype:$Rd, 3121 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3122 (i32 imm:$cond), NZCV))]>, 3123 Sched<[WriteI, ReadI, ReadI]> { 3124 let Uses = [NZCV]; 3125 3126 bits<5> Rd; 3127 bits<5> Rn; 3128 bits<5> Rm; 3129 bits<4> cond; 3130 3131 let Inst{30} = op; 3132 let Inst{29-21} = 0b011010100; 3133 let Inst{20-16} = Rm; 3134 let Inst{15-12} = cond; 3135 let Inst{11-10} = op2; 3136 let Inst{9-5} = Rn; 3137 let Inst{4-0} = Rd; 3138} 3139 3140def inv_cond_XFORM : SDNodeXForm<imm, [{ 3141 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3142 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3143 MVT::i32); 3144}]>; 3145 3146multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3147 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3148 let Inst{31} = 0; 3149 } 3150 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3151 let Inst{31} = 1; 3152 } 3153 3154 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3155 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3156 (inv_cond_XFORM imm:$cond))>; 3157 3158 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3159 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3160 (inv_cond_XFORM imm:$cond))>; 3161} 3162 3163//--- 3164// Special Mask Value 3165//--- 3166def maski8_or_more : Operand<i32>, 3167 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3168} 3169def maski16_or_more : Operand<i32>, 3170 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3171} 3172 3173 3174//--- 3175// Load/store 3176//--- 3177 3178// (unsigned immediate) 3179// Indexed for 8-bit registers. offset is in range [0,4095]. 3180def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3181def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3182def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3183def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3184def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3185 3186// (unsigned immediate) 3187// Indexed for 8-bit registers. offset is in range [0,63]. 3188def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3189def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3190def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3191def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3192 3193def gi_am_indexed8 : 3194 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3195 GIComplexPatternEquiv<am_indexed8>; 3196def gi_am_indexed16 : 3197 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3198 GIComplexPatternEquiv<am_indexed16>; 3199def gi_am_indexed32 : 3200 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3201 GIComplexPatternEquiv<am_indexed32>; 3202def gi_am_indexed64 : 3203 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3204 GIComplexPatternEquiv<am_indexed64>; 3205def gi_am_indexed128 : 3206 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3207 GIComplexPatternEquiv<am_indexed128>; 3208 3209class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3210 let Name = "UImm12Offset" # Scale; 3211 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3212 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3213 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3214} 3215 3216def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3217def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3218def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3219def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3220def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3221 3222class uimm12_scaled<int Scale> : Operand<i64> { 3223 let ParserMatchClass 3224 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3225 let EncoderMethod 3226 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3227 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3228} 3229 3230def uimm12s1 : uimm12_scaled<1>; 3231def uimm12s2 : uimm12_scaled<2>; 3232def uimm12s4 : uimm12_scaled<4>; 3233def uimm12s8 : uimm12_scaled<8>; 3234def uimm12s16 : uimm12_scaled<16>; 3235 3236class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3237 string asm, list<dag> pattern> 3238 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3239 bits<5> Rt; 3240 3241 bits<5> Rn; 3242 bits<12> offset; 3243 3244 let Inst{31-30} = sz; 3245 let Inst{29-27} = 0b111; 3246 let Inst{26} = V; 3247 let Inst{25-24} = 0b01; 3248 let Inst{23-22} = opc; 3249 let Inst{21-10} = offset; 3250 let Inst{9-5} = Rn; 3251 let Inst{4-0} = Rt; 3252 3253 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3254} 3255 3256multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3257 Operand indextype, string asm, list<dag> pattern> { 3258 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3259 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3260 (ins GPR64sp:$Rn, indextype:$offset), 3261 asm, pattern>, 3262 Sched<[WriteLD]>; 3263 3264 def : InstAlias<asm # "\t$Rt, [$Rn]", 3265 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3266} 3267 3268multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3269 Operand indextype, string asm, list<dag> pattern> { 3270 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3271 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3272 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3273 asm, pattern>, 3274 Sched<[WriteST]>; 3275 3276 def : InstAlias<asm # "\t$Rt, [$Rn]", 3277 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3278} 3279 3280// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3281// substitute zero-registers automatically. 3282// 3283// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3284// into StoreUI. 3285multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3286 Operand indextype, string asm, list<dag> pattern> { 3287 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3288 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3289 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3290 asm, pattern>, 3291 Sched<[WriteST]>; 3292 3293 def : InstAlias<asm # "\t$Rt, [$Rn]", 3294 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3295} 3296 3297def PrefetchOperand : AsmOperandClass { 3298 let Name = "Prefetch"; 3299 let ParserMethod = "tryParsePrefetch"; 3300} 3301def prfop : Operand<i32> { 3302 let PrintMethod = "printPrefetchOp"; 3303 let ParserMatchClass = PrefetchOperand; 3304} 3305 3306let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3307class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3308 : BaseLoadStoreUI<sz, V, opc, 3309 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3310 asm, pat>, 3311 Sched<[WriteLD]>; 3312 3313//--- 3314// Load literal 3315//--- 3316 3317// Load literal address: 19-bit immediate. The low two bits of the target 3318// offset are implied zero and so are not part of the immediate. 3319def am_ldrlit : Operand<iPTR> { 3320 let EncoderMethod = "getLoadLiteralOpValue"; 3321 let DecoderMethod = "DecodePCRelLabel19"; 3322 let PrintMethod = "printAlignedLabel"; 3323 let ParserMatchClass = PCRelLabel19Operand; 3324 let OperandType = "OPERAND_PCREL"; 3325} 3326 3327let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3328class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3329 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3330 asm, "\t$Rt, $label", "", pat>, 3331 Sched<[WriteLD]> { 3332 bits<5> Rt; 3333 bits<19> label; 3334 let Inst{31-30} = opc; 3335 let Inst{29-27} = 0b011; 3336 let Inst{26} = V; 3337 let Inst{25-24} = 0b00; 3338 let Inst{23-5} = label; 3339 let Inst{4-0} = Rt; 3340} 3341 3342let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3343class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3344 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3345 asm, "\t$Rt, $label", "", pat>, 3346 Sched<[WriteLD]> { 3347 bits<5> Rt; 3348 bits<19> label; 3349 let Inst{31-30} = opc; 3350 let Inst{29-27} = 0b011; 3351 let Inst{26} = V; 3352 let Inst{25-24} = 0b00; 3353 let Inst{23-5} = label; 3354 let Inst{4-0} = Rt; 3355} 3356 3357//--- 3358// Load/store register offset 3359//--- 3360 3361def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3362def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3363def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3364def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3365def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3366 3367def gi_ro_Xindexed8 : 3368 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3369 GIComplexPatternEquiv<ro_Xindexed8>; 3370def gi_ro_Xindexed16 : 3371 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3372 GIComplexPatternEquiv<ro_Xindexed16>; 3373def gi_ro_Xindexed32 : 3374 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3375 GIComplexPatternEquiv<ro_Xindexed32>; 3376def gi_ro_Xindexed64 : 3377 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3378 GIComplexPatternEquiv<ro_Xindexed64>; 3379def gi_ro_Xindexed128 : 3380 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3381 GIComplexPatternEquiv<ro_Xindexed128>; 3382 3383def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3384def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3385def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3386def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3387def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3388 3389def gi_ro_Windexed8 : 3390 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3391 GIComplexPatternEquiv<ro_Windexed8>; 3392def gi_ro_Windexed16 : 3393 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3394 GIComplexPatternEquiv<ro_Windexed16>; 3395def gi_ro_Windexed32 : 3396 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3397 GIComplexPatternEquiv<ro_Windexed32>; 3398def gi_ro_Windexed64 : 3399 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3400 GIComplexPatternEquiv<ro_Windexed64>; 3401def gi_ro_Windexed128 : 3402 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3403 GIComplexPatternEquiv<ro_Windexed128>; 3404 3405class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3406 let Name = "Mem" # Reg # "Extend" # Width; 3407 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3408 let RenderMethod = "addMemExtendOperands"; 3409 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3410} 3411 3412def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3413 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3414 // the trivial shift. 3415 let RenderMethod = "addMemExtend8Operands"; 3416} 3417def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3418def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3419def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3420def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3421 3422def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3423 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3424 // the trivial shift. 3425 let RenderMethod = "addMemExtend8Operands"; 3426} 3427def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3428def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3429def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3430def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3431 3432class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3433 : Operand<i32> { 3434 let ParserMatchClass = ParserClass; 3435 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3436 let DecoderMethod = "DecodeMemExtend"; 3437 let EncoderMethod = "getMemExtendOpValue"; 3438 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3439} 3440 3441def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3442def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3443def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3444def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3445def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3446 3447def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3448def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3449def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3450def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3451def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3452 3453class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3454 Operand wextend, Operand xextend> { 3455 // CodeGen-level pattern covering the entire addressing mode. 3456 ComplexPattern Wpat = windex; 3457 ComplexPattern Xpat = xindex; 3458 3459 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3460 Operand Wext = wextend; 3461 Operand Xext = xextend; 3462} 3463 3464def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3465def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3466def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3467def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3468def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3469 ro_Xextend128>; 3470 3471class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3472 dag outs, list<dag> pat> 3473 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3474 bits<5> Rt; 3475 bits<5> Rn; 3476 bits<5> Rm; 3477 bits<2> extend; 3478 let Inst{31-30} = sz; 3479 let Inst{29-27} = 0b111; 3480 let Inst{26} = V; 3481 let Inst{25-24} = 0b00; 3482 let Inst{23-22} = opc; 3483 let Inst{21} = 1; 3484 let Inst{20-16} = Rm; 3485 let Inst{15} = extend{1}; // sign extend Rm? 3486 let Inst{14} = 1; 3487 let Inst{12} = extend{0}; // do shift? 3488 let Inst{11-10} = 0b10; 3489 let Inst{9-5} = Rn; 3490 let Inst{4-0} = Rt; 3491} 3492 3493class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3494 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3495 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3496 3497multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3498 string asm, ValueType Ty, SDPatternOperator loadop> { 3499 let AddedComplexity = 10 in 3500 def roW : LoadStore8RO<sz, V, opc, asm, 3501 (outs regtype:$Rt), 3502 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3503 [(set (Ty regtype:$Rt), 3504 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3505 ro_Wextend8:$extend)))]>, 3506 Sched<[WriteLDIdx, ReadAdrBase]> { 3507 let Inst{13} = 0b0; 3508 } 3509 3510 let AddedComplexity = 10 in 3511 def roX : LoadStore8RO<sz, V, opc, asm, 3512 (outs regtype:$Rt), 3513 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3514 [(set (Ty regtype:$Rt), 3515 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3516 ro_Xextend8:$extend)))]>, 3517 Sched<[WriteLDIdx, ReadAdrBase]> { 3518 let Inst{13} = 0b1; 3519 } 3520 3521 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3522} 3523 3524multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3525 string asm, ValueType Ty, SDPatternOperator storeop> { 3526 let AddedComplexity = 10 in 3527 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3528 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3529 [(storeop (Ty regtype:$Rt), 3530 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3531 ro_Wextend8:$extend))]>, 3532 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3533 let Inst{13} = 0b0; 3534 } 3535 3536 let AddedComplexity = 10 in 3537 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3538 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3539 [(storeop (Ty regtype:$Rt), 3540 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3541 ro_Xextend8:$extend))]>, 3542 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3543 let Inst{13} = 0b1; 3544 } 3545 3546 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3547} 3548 3549class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3550 dag outs, list<dag> pat> 3551 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3552 bits<5> Rt; 3553 bits<5> Rn; 3554 bits<5> Rm; 3555 bits<2> extend; 3556 let Inst{31-30} = sz; 3557 let Inst{29-27} = 0b111; 3558 let Inst{26} = V; 3559 let Inst{25-24} = 0b00; 3560 let Inst{23-22} = opc; 3561 let Inst{21} = 1; 3562 let Inst{20-16} = Rm; 3563 let Inst{15} = extend{1}; // sign extend Rm? 3564 let Inst{14} = 1; 3565 let Inst{12} = extend{0}; // do shift? 3566 let Inst{11-10} = 0b10; 3567 let Inst{9-5} = Rn; 3568 let Inst{4-0} = Rt; 3569} 3570 3571multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3572 string asm, ValueType Ty, SDPatternOperator loadop> { 3573 let AddedComplexity = 10 in 3574 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3575 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3576 [(set (Ty regtype:$Rt), 3577 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3578 ro_Wextend16:$extend)))]>, 3579 Sched<[WriteLDIdx, ReadAdrBase]> { 3580 let Inst{13} = 0b0; 3581 } 3582 3583 let AddedComplexity = 10 in 3584 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3585 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3586 [(set (Ty regtype:$Rt), 3587 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3588 ro_Xextend16:$extend)))]>, 3589 Sched<[WriteLDIdx, ReadAdrBase]> { 3590 let Inst{13} = 0b1; 3591 } 3592 3593 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3594} 3595 3596multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3597 string asm, ValueType Ty, SDPatternOperator storeop> { 3598 let AddedComplexity = 10 in 3599 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3600 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3601 [(storeop (Ty regtype:$Rt), 3602 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3603 ro_Wextend16:$extend))]>, 3604 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3605 let Inst{13} = 0b0; 3606 } 3607 3608 let AddedComplexity = 10 in 3609 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3610 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3611 [(storeop (Ty regtype:$Rt), 3612 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3613 ro_Xextend16:$extend))]>, 3614 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3615 let Inst{13} = 0b1; 3616 } 3617 3618 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3619} 3620 3621class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3622 dag outs, list<dag> pat> 3623 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3624 bits<5> Rt; 3625 bits<5> Rn; 3626 bits<5> Rm; 3627 bits<2> extend; 3628 let Inst{31-30} = sz; 3629 let Inst{29-27} = 0b111; 3630 let Inst{26} = V; 3631 let Inst{25-24} = 0b00; 3632 let Inst{23-22} = opc; 3633 let Inst{21} = 1; 3634 let Inst{20-16} = Rm; 3635 let Inst{15} = extend{1}; // sign extend Rm? 3636 let Inst{14} = 1; 3637 let Inst{12} = extend{0}; // do shift? 3638 let Inst{11-10} = 0b10; 3639 let Inst{9-5} = Rn; 3640 let Inst{4-0} = Rt; 3641} 3642 3643multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3644 string asm, ValueType Ty, SDPatternOperator loadop> { 3645 let AddedComplexity = 10 in 3646 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3647 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3648 [(set (Ty regtype:$Rt), 3649 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3650 ro_Wextend32:$extend)))]>, 3651 Sched<[WriteLDIdx, ReadAdrBase]> { 3652 let Inst{13} = 0b0; 3653 } 3654 3655 let AddedComplexity = 10 in 3656 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3657 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3658 [(set (Ty regtype:$Rt), 3659 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3660 ro_Xextend32:$extend)))]>, 3661 Sched<[WriteLDIdx, ReadAdrBase]> { 3662 let Inst{13} = 0b1; 3663 } 3664 3665 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3666} 3667 3668multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3669 string asm, ValueType Ty, SDPatternOperator storeop> { 3670 let AddedComplexity = 10 in 3671 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 3672 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3673 [(storeop (Ty regtype:$Rt), 3674 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3675 ro_Wextend32:$extend))]>, 3676 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3677 let Inst{13} = 0b0; 3678 } 3679 3680 let AddedComplexity = 10 in 3681 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 3682 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3683 [(storeop (Ty regtype:$Rt), 3684 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3685 ro_Xextend32:$extend))]>, 3686 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3687 let Inst{13} = 0b1; 3688 } 3689 3690 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3691} 3692 3693class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3694 dag outs, list<dag> pat> 3695 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3696 bits<5> Rt; 3697 bits<5> Rn; 3698 bits<5> Rm; 3699 bits<2> extend; 3700 let Inst{31-30} = sz; 3701 let Inst{29-27} = 0b111; 3702 let Inst{26} = V; 3703 let Inst{25-24} = 0b00; 3704 let Inst{23-22} = opc; 3705 let Inst{21} = 1; 3706 let Inst{20-16} = Rm; 3707 let Inst{15} = extend{1}; // sign extend Rm? 3708 let Inst{14} = 1; 3709 let Inst{12} = extend{0}; // do shift? 3710 let Inst{11-10} = 0b10; 3711 let Inst{9-5} = Rn; 3712 let Inst{4-0} = Rt; 3713} 3714 3715multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3716 string asm, ValueType Ty, SDPatternOperator loadop> { 3717 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3718 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3719 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3720 [(set (Ty regtype:$Rt), 3721 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3722 ro_Wextend64:$extend)))]>, 3723 Sched<[WriteLDIdx, ReadAdrBase]> { 3724 let Inst{13} = 0b0; 3725 } 3726 3727 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3728 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3729 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3730 [(set (Ty regtype:$Rt), 3731 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3732 ro_Xextend64:$extend)))]>, 3733 Sched<[WriteLDIdx, ReadAdrBase]> { 3734 let Inst{13} = 0b1; 3735 } 3736 3737 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3738} 3739 3740multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3741 string asm, ValueType Ty, SDPatternOperator storeop> { 3742 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3743 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 3744 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3745 [(storeop (Ty regtype:$Rt), 3746 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3747 ro_Wextend64:$extend))]>, 3748 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3749 let Inst{13} = 0b0; 3750 } 3751 3752 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3753 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 3754 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3755 [(storeop (Ty regtype:$Rt), 3756 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3757 ro_Xextend64:$extend))]>, 3758 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3759 let Inst{13} = 0b1; 3760 } 3761 3762 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3763} 3764 3765class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3766 dag outs, list<dag> pat> 3767 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3768 bits<5> Rt; 3769 bits<5> Rn; 3770 bits<5> Rm; 3771 bits<2> extend; 3772 let Inst{31-30} = sz; 3773 let Inst{29-27} = 0b111; 3774 let Inst{26} = V; 3775 let Inst{25-24} = 0b00; 3776 let Inst{23-22} = opc; 3777 let Inst{21} = 1; 3778 let Inst{20-16} = Rm; 3779 let Inst{15} = extend{1}; // sign extend Rm? 3780 let Inst{14} = 1; 3781 let Inst{12} = extend{0}; // do shift? 3782 let Inst{11-10} = 0b10; 3783 let Inst{9-5} = Rn; 3784 let Inst{4-0} = Rt; 3785} 3786 3787multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3788 string asm, ValueType Ty, SDPatternOperator loadop> { 3789 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3790 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3791 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3792 [(set (Ty regtype:$Rt), 3793 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3794 ro_Wextend128:$extend)))]>, 3795 Sched<[WriteLDIdx, ReadAdrBase]> { 3796 let Inst{13} = 0b0; 3797 } 3798 3799 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3800 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3801 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3802 [(set (Ty regtype:$Rt), 3803 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3804 ro_Xextend128:$extend)))]>, 3805 Sched<[WriteLDIdx, ReadAdrBase]> { 3806 let Inst{13} = 0b1; 3807 } 3808 3809 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3810} 3811 3812multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3813 string asm> { 3814 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3815 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 3816 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3817 []>, 3818 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3819 let Inst{13} = 0b0; 3820 } 3821 3822 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3823 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 3824 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3825 []>, 3826 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3827 let Inst{13} = 0b1; 3828 } 3829 3830 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3831} 3832 3833let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3834class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3835 string asm, list<dag> pat> 3836 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3837 Sched<[WriteLD]> { 3838 bits<5> Rt; 3839 bits<5> Rn; 3840 bits<5> Rm; 3841 bits<2> extend; 3842 let Inst{31-30} = sz; 3843 let Inst{29-27} = 0b111; 3844 let Inst{26} = V; 3845 let Inst{25-24} = 0b00; 3846 let Inst{23-22} = opc; 3847 let Inst{21} = 1; 3848 let Inst{20-16} = Rm; 3849 let Inst{15} = extend{1}; // sign extend Rm? 3850 let Inst{14} = 1; 3851 let Inst{12} = extend{0}; // do shift? 3852 let Inst{11-10} = 0b10; 3853 let Inst{9-5} = Rn; 3854 let Inst{4-0} = Rt; 3855} 3856 3857multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3858 def roW : BasePrefetchRO<sz, V, opc, (outs), 3859 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3860 asm, [(AArch64Prefetch imm:$Rt, 3861 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3862 ro_Wextend64:$extend))]> { 3863 let Inst{13} = 0b0; 3864 } 3865 3866 def roX : BasePrefetchRO<sz, V, opc, (outs), 3867 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3868 asm, [(AArch64Prefetch imm:$Rt, 3869 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3870 ro_Xextend64:$extend))]> { 3871 let Inst{13} = 0b1; 3872 } 3873 3874 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3875 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3876 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3877} 3878 3879//--- 3880// Load/store unscaled immediate 3881//--- 3882 3883def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 3884def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 3885def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 3886def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 3887def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 3888 3889def gi_am_unscaled8 : 3890 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3891 GIComplexPatternEquiv<am_unscaled8>; 3892def gi_am_unscaled16 : 3893 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3894 GIComplexPatternEquiv<am_unscaled16>; 3895def gi_am_unscaled32 : 3896 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3897 GIComplexPatternEquiv<am_unscaled32>; 3898def gi_am_unscaled64 : 3899 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3900 GIComplexPatternEquiv<am_unscaled64>; 3901def gi_am_unscaled128 : 3902 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3903 GIComplexPatternEquiv<am_unscaled128>; 3904 3905 3906class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3907 string asm, list<dag> pattern> 3908 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3909 bits<5> Rt; 3910 bits<5> Rn; 3911 bits<9> offset; 3912 let Inst{31-30} = sz; 3913 let Inst{29-27} = 0b111; 3914 let Inst{26} = V; 3915 let Inst{25-24} = 0b00; 3916 let Inst{23-22} = opc; 3917 let Inst{21} = 0; 3918 let Inst{20-12} = offset; 3919 let Inst{11-10} = 0b00; 3920 let Inst{9-5} = Rn; 3921 let Inst{4-0} = Rt; 3922 3923 let DecoderMethod = "DecodeSignedLdStInstruction"; 3924} 3925 3926// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3927multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3928 DAGOperand regtype > { 3929 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3930 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3931 Sched<[WriteST]> { 3932 let Inst{29} = 0; 3933 let Inst{24} = 1; 3934 } 3935 def : InstAlias<asm # "\t$Rt, [$Rn]", 3936 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3937} 3938 3939multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3940 DAGOperand regtype > { 3941 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3942 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3943 asm, []>, 3944 Sched<[WriteST]> { 3945 let Inst{29} = 0; 3946 let Inst{24} = 1; 3947 } 3948 def : InstAlias<asm # "\t$Rt, [$Rn]", 3949 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3950} 3951 3952multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3953 string asm, list<dag> pattern> { 3954 let AddedComplexity = 1 in // try this before LoadUI 3955 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3956 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3957 Sched<[WriteLD]>; 3958 3959 def : InstAlias<asm # "\t$Rt, [$Rn]", 3960 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3961} 3962 3963multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3964 string asm, list<dag> pattern> { 3965 let AddedComplexity = 1 in // try this before StoreUI 3966 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3967 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3968 asm, pattern>, 3969 Sched<[WriteST]>; 3970 3971 def : InstAlias<asm # "\t$Rt, [$Rn]", 3972 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3973} 3974 3975multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3976 list<dag> pat> { 3977 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3978 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3979 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3980 asm, pat>, 3981 Sched<[WriteLD]>; 3982 3983 def : InstAlias<asm # "\t$Rt, [$Rn]", 3984 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3985} 3986 3987//--- 3988// Load/store unscaled immediate, unprivileged 3989//--- 3990 3991class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3992 dag oops, dag iops, string asm> 3993 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 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} = 0b00; 4001 let Inst{23-22} = opc; 4002 let Inst{21} = 0; 4003 let Inst{20-12} = offset; 4004 let Inst{11-10} = 0b10; 4005 let Inst{9-5} = Rn; 4006 let Inst{4-0} = Rt; 4007 4008 let DecoderMethod = "DecodeSignedLdStInstruction"; 4009} 4010 4011multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4012 RegisterClass regtype, string asm> { 4013 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4014 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4015 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4016 Sched<[WriteLD]>; 4017 4018 def : InstAlias<asm # "\t$Rt, [$Rn]", 4019 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4020} 4021 4022multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4023 RegisterClass regtype, string asm> { 4024 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4025 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4026 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4027 asm>, 4028 Sched<[WriteST]>; 4029 4030 def : InstAlias<asm # "\t$Rt, [$Rn]", 4031 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4032} 4033 4034//--- 4035// Load/store pre-indexed 4036//--- 4037 4038class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4039 string asm, string cstr, list<dag> pat> 4040 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4041 bits<5> Rt; 4042 bits<5> Rn; 4043 bits<9> offset; 4044 let Inst{31-30} = sz; 4045 let Inst{29-27} = 0b111; 4046 let Inst{26} = V; 4047 let Inst{25-24} = 0; 4048 let Inst{23-22} = opc; 4049 let Inst{21} = 0; 4050 let Inst{20-12} = offset; 4051 let Inst{11-10} = 0b11; 4052 let Inst{9-5} = Rn; 4053 let Inst{4-0} = Rt; 4054 4055 let DecoderMethod = "DecodeSignedLdStInstruction"; 4056} 4057 4058let hasSideEffects = 0 in { 4059let mayStore = 0, mayLoad = 1 in 4060class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4061 string asm> 4062 : BaseLoadStorePreIdx<sz, V, opc, 4063 (outs GPR64sp:$wback, regtype:$Rt), 4064 (ins GPR64sp:$Rn, simm9:$offset), asm, 4065 "$Rn = $wback,@earlyclobber $wback", []>, 4066 Sched<[WriteAdr, WriteLD]>; 4067 4068let mayStore = 1, mayLoad = 0 in 4069class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4070 string asm, SDPatternOperator storeop, ValueType Ty> 4071 : BaseLoadStorePreIdx<sz, V, opc, 4072 (outs GPR64sp:$wback), 4073 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4074 asm, "$Rn = $wback,@earlyclobber $wback", 4075 [(set GPR64sp:$wback, 4076 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4077 Sched<[WriteAdr, WriteST]>; 4078} // hasSideEffects = 0 4079 4080//--- 4081// Load/store post-indexed 4082//--- 4083 4084class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4085 string asm, string cstr, list<dag> pat> 4086 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4087 bits<5> Rt; 4088 bits<5> Rn; 4089 bits<9> offset; 4090 let Inst{31-30} = sz; 4091 let Inst{29-27} = 0b111; 4092 let Inst{26} = V; 4093 let Inst{25-24} = 0b00; 4094 let Inst{23-22} = opc; 4095 let Inst{21} = 0b0; 4096 let Inst{20-12} = offset; 4097 let Inst{11-10} = 0b01; 4098 let Inst{9-5} = Rn; 4099 let Inst{4-0} = Rt; 4100 4101 let DecoderMethod = "DecodeSignedLdStInstruction"; 4102} 4103 4104let hasSideEffects = 0 in { 4105let mayStore = 0, mayLoad = 1 in 4106class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4107 string asm> 4108 : BaseLoadStorePostIdx<sz, V, opc, 4109 (outs GPR64sp:$wback, regtype:$Rt), 4110 (ins GPR64sp:$Rn, simm9:$offset), 4111 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4112 Sched<[WriteAdr, WriteLD]>; 4113 4114let mayStore = 1, mayLoad = 0 in 4115class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4116 string asm, SDPatternOperator storeop, ValueType Ty> 4117 : BaseLoadStorePostIdx<sz, V, opc, 4118 (outs GPR64sp:$wback), 4119 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4120 asm, "$Rn = $wback,@earlyclobber $wback", 4121 [(set GPR64sp:$wback, 4122 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4123 Sched<[WriteAdr, WriteST]>; 4124} // hasSideEffects = 0 4125 4126 4127//--- 4128// Load/store pair 4129//--- 4130 4131// (indexed, offset) 4132 4133class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4134 string asm> 4135 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4136 bits<5> Rt; 4137 bits<5> Rt2; 4138 bits<5> Rn; 4139 bits<7> offset; 4140 let Inst{31-30} = opc; 4141 let Inst{29-27} = 0b101; 4142 let Inst{26} = V; 4143 let Inst{25-23} = 0b010; 4144 let Inst{22} = L; 4145 let Inst{21-15} = offset; 4146 let Inst{14-10} = Rt2; 4147 let Inst{9-5} = Rn; 4148 let Inst{4-0} = Rt; 4149 4150 let DecoderMethod = "DecodePairLdStInstruction"; 4151} 4152 4153multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4154 Operand indextype, string asm> { 4155 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4156 def i : BaseLoadStorePairOffset<opc, V, 1, 4157 (outs regtype:$Rt, regtype:$Rt2), 4158 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4159 Sched<[WriteLD, WriteLDHi]>; 4160 4161 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4162 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4163 GPR64sp:$Rn, 0)>; 4164} 4165 4166 4167multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4168 Operand indextype, string asm> { 4169 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4170 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4171 (ins regtype:$Rt, regtype:$Rt2, 4172 GPR64sp:$Rn, indextype:$offset), 4173 asm>, 4174 Sched<[WriteSTP]>; 4175 4176 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4177 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4178 GPR64sp:$Rn, 0)>; 4179} 4180 4181// (pre-indexed) 4182class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4183 string asm> 4184 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4185 bits<5> Rt; 4186 bits<5> Rt2; 4187 bits<5> Rn; 4188 bits<7> offset; 4189 let Inst{31-30} = opc; 4190 let Inst{29-27} = 0b101; 4191 let Inst{26} = V; 4192 let Inst{25-23} = 0b011; 4193 let Inst{22} = L; 4194 let Inst{21-15} = offset; 4195 let Inst{14-10} = Rt2; 4196 let Inst{9-5} = Rn; 4197 let Inst{4-0} = Rt; 4198 4199 let DecoderMethod = "DecodePairLdStInstruction"; 4200} 4201 4202let hasSideEffects = 0 in { 4203let mayStore = 0, mayLoad = 1 in 4204class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4205 Operand indextype, string asm> 4206 : BaseLoadStorePairPreIdx<opc, V, 1, 4207 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4208 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4209 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4210 4211let mayStore = 1, mayLoad = 0 in 4212class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4213 Operand indextype, string asm> 4214 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4215 (ins regtype:$Rt, regtype:$Rt2, 4216 GPR64sp:$Rn, indextype:$offset), 4217 asm>, 4218 Sched<[WriteAdr, WriteSTP]>; 4219} // hasSideEffects = 0 4220 4221// (post-indexed) 4222 4223class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4224 string asm> 4225 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4226 bits<5> Rt; 4227 bits<5> Rt2; 4228 bits<5> Rn; 4229 bits<7> offset; 4230 let Inst{31-30} = opc; 4231 let Inst{29-27} = 0b101; 4232 let Inst{26} = V; 4233 let Inst{25-23} = 0b001; 4234 let Inst{22} = L; 4235 let Inst{21-15} = offset; 4236 let Inst{14-10} = Rt2; 4237 let Inst{9-5} = Rn; 4238 let Inst{4-0} = Rt; 4239 4240 let DecoderMethod = "DecodePairLdStInstruction"; 4241} 4242 4243let hasSideEffects = 0 in { 4244let mayStore = 0, mayLoad = 1 in 4245class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4246 Operand idxtype, string asm> 4247 : BaseLoadStorePairPostIdx<opc, V, 1, 4248 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4249 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4250 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4251 4252let mayStore = 1, mayLoad = 0 in 4253class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4254 Operand idxtype, string asm> 4255 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4256 (ins regtype:$Rt, regtype:$Rt2, 4257 GPR64sp:$Rn, idxtype:$offset), 4258 asm>, 4259 Sched<[WriteAdr, WriteSTP]>; 4260} // hasSideEffects = 0 4261 4262// (no-allocate) 4263 4264class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4265 string asm> 4266 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4267 bits<5> Rt; 4268 bits<5> Rt2; 4269 bits<5> Rn; 4270 bits<7> offset; 4271 let Inst{31-30} = opc; 4272 let Inst{29-27} = 0b101; 4273 let Inst{26} = V; 4274 let Inst{25-23} = 0b000; 4275 let Inst{22} = L; 4276 let Inst{21-15} = offset; 4277 let Inst{14-10} = Rt2; 4278 let Inst{9-5} = Rn; 4279 let Inst{4-0} = Rt; 4280 4281 let DecoderMethod = "DecodePairLdStInstruction"; 4282} 4283 4284multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4285 Operand indextype, string asm> { 4286 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4287 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4288 (outs regtype:$Rt, regtype:$Rt2), 4289 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4290 Sched<[WriteLD, WriteLDHi]>; 4291 4292 4293 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4294 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4295 GPR64sp:$Rn, 0)>; 4296} 4297 4298multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4299 Operand indextype, string asm> { 4300 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4301 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4302 (ins regtype:$Rt, regtype:$Rt2, 4303 GPR64sp:$Rn, indextype:$offset), 4304 asm>, 4305 Sched<[WriteSTP]>; 4306 4307 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4308 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4309 GPR64sp:$Rn, 0)>; 4310} 4311 4312//--- 4313// Load/store exclusive 4314//--- 4315 4316// True exclusive operations write to and/or read from the system's exclusive 4317// monitors, which as far as a compiler is concerned can be modelled as a 4318// random shared memory address. Hence LoadExclusive mayStore. 4319// 4320// Since these instructions have the undefined register bits set to 1 in 4321// their canonical form, we need a post encoder method to set those bits 4322// to 1 when encoding these instructions. We do this using the 4323// fixLoadStoreExclusive function. This function has template parameters: 4324// 4325// fixLoadStoreExclusive<int hasRs, int hasRt2> 4326// 4327// hasRs indicates that the instruction uses the Rs field, so we won't set 4328// it to 1 (and the same for Rt2). We don't need template parameters for 4329// the other register fields since Rt and Rn are always used. 4330// 4331let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4332class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4333 dag oops, dag iops, string asm, string operands> 4334 : I<oops, iops, asm, operands, "", []> { 4335 let Inst{31-30} = sz; 4336 let Inst{29-24} = 0b001000; 4337 let Inst{23} = o2; 4338 let Inst{22} = L; 4339 let Inst{21} = o1; 4340 let Inst{15} = o0; 4341 4342 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4343} 4344 4345// Neither Rs nor Rt2 operands. 4346class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4347 dag oops, dag iops, string asm, string operands> 4348 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4349 bits<5> Rt; 4350 bits<5> Rn; 4351 let Inst{20-16} = 0b11111; 4352 let Unpredictable{20-16} = 0b11111; 4353 let Inst{14-10} = 0b11111; 4354 let Unpredictable{14-10} = 0b11111; 4355 let Inst{9-5} = Rn; 4356 let Inst{4-0} = Rt; 4357 4358 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4359} 4360 4361// Simple load acquires don't set the exclusive monitor 4362let mayLoad = 1, mayStore = 0 in 4363class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4364 RegisterClass regtype, string asm> 4365 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4366 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4367 Sched<[WriteLD]>; 4368 4369class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4370 RegisterClass regtype, string asm> 4371 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4372 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4373 Sched<[WriteLD]>; 4374 4375class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4376 RegisterClass regtype, string asm> 4377 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4378 (outs regtype:$Rt, regtype:$Rt2), 4379 (ins GPR64sp0:$Rn), asm, 4380 "\t$Rt, $Rt2, [$Rn]">, 4381 Sched<[WriteLD, WriteLDHi]> { 4382 bits<5> Rt; 4383 bits<5> Rt2; 4384 bits<5> Rn; 4385 let Inst{14-10} = Rt2; 4386 let Inst{9-5} = Rn; 4387 let Inst{4-0} = Rt; 4388 4389 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4390} 4391 4392// Simple store release operations do not check the exclusive monitor. 4393let mayLoad = 0, mayStore = 1 in 4394class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4395 RegisterClass regtype, string asm> 4396 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4397 (ins regtype:$Rt, GPR64sp0:$Rn), 4398 asm, "\t$Rt, [$Rn]">, 4399 Sched<[WriteST]>; 4400 4401let mayLoad = 1, mayStore = 1 in 4402class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4403 RegisterClass regtype, string asm> 4404 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4405 (ins regtype:$Rt, GPR64sp0:$Rn), 4406 asm, "\t$Ws, $Rt, [$Rn]">, 4407 Sched<[WriteSTX]> { 4408 bits<5> Ws; 4409 bits<5> Rt; 4410 bits<5> Rn; 4411 let Inst{20-16} = Ws; 4412 let Inst{9-5} = Rn; 4413 let Inst{4-0} = Rt; 4414 4415 let Constraints = "@earlyclobber $Ws"; 4416 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4417} 4418 4419class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4420 RegisterClass regtype, string asm> 4421 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4422 (outs GPR32:$Ws), 4423 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4424 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4425 Sched<[WriteSTX]> { 4426 bits<5> Ws; 4427 bits<5> Rt; 4428 bits<5> Rt2; 4429 bits<5> Rn; 4430 let Inst{20-16} = Ws; 4431 let Inst{14-10} = Rt2; 4432 let Inst{9-5} = Rn; 4433 let Inst{4-0} = Rt; 4434 4435 let Constraints = "@earlyclobber $Ws"; 4436} 4437 4438// Armv8.5-A Memory Tagging Extension 4439class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4440 string asm_opnds, string cstr, dag oops, dag iops> 4441 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4442 Sched<[]> { 4443 bits<5> Rn; 4444 4445 let Inst{31-24} = 0b11011001; 4446 let Inst{23-22} = opc1; 4447 let Inst{21} = 1; 4448 // Inst{20-12} defined by subclass 4449 let Inst{11-10} = opc2; 4450 let Inst{9-5} = Rn; 4451 // Inst{4-0} defined by subclass 4452} 4453 4454class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4455 dag oops, dag iops> 4456 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4457 "", oops, iops> { 4458 bits<5> Rt; 4459 4460 let Inst{20-12} = 0b000000000; 4461 let Inst{4-0} = Rt; 4462 4463 let mayLoad = Load; 4464} 4465 4466class MemTagLoad<string asm_insn, string asm_opnds> 4467 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4468 (outs GPR64:$wback), 4469 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4470 bits<5> Rt; 4471 bits<9> offset; 4472 4473 let Inst{20-12} = offset; 4474 let Inst{4-0} = Rt; 4475 4476 let mayLoad = 1; 4477} 4478 4479class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4480 string asm_opnds, string cstr, dag oops, dag iops> 4481 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4482 bits<5> Rt; 4483 bits<9> offset; 4484 4485 let Inst{20-12} = offset; 4486 let Inst{4-0} = Rt; 4487 4488 let mayStore = 1; 4489} 4490 4491multiclass MemTagStore<bits<2> opc1, string insn> { 4492 def Offset : 4493 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4494 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4495 def PreIndex : 4496 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4497 "$Rn = $wback", 4498 (outs GPR64sp:$wback), 4499 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4500 def PostIndex : 4501 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4502 "$Rn = $wback", 4503 (outs GPR64sp:$wback), 4504 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4505 4506 def : InstAlias<insn # "\t$Rt, [$Rn]", 4507 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4508} 4509 4510//--- 4511// Exception generation 4512//--- 4513 4514let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4515class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4516 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", []>, 4517 Sched<[WriteSys]> { 4518 bits<16> imm; 4519 let Inst{31-24} = 0b11010100; 4520 let Inst{23-21} = op1; 4521 let Inst{20-5} = imm; 4522 let Inst{4-2} = 0b000; 4523 let Inst{1-0} = ll; 4524} 4525 4526//--- 4527// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4528//-- 4529let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4530class UDFType<bits<16> opc, string asm> 4531 : I<(outs), (ins uimm16:$imm), 4532 asm, "\t$imm", "", []>, 4533 Sched<[]> { 4534 bits<16> imm; 4535 let Inst{31-16} = opc; 4536 let Inst{15-0} = imm; 4537} 4538} 4539let Predicates = [HasFPARMv8] in { 4540 4541//--- 4542// Floating point to integer conversion 4543//--- 4544 4545class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4546 RegisterClass srcType, RegisterClass dstType, 4547 string asm, list<dag> pattern> 4548 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4549 asm, "\t$Rd, $Rn", "", pattern>, 4550 Sched<[WriteFCvt]> { 4551 bits<5> Rd; 4552 bits<5> Rn; 4553 let Inst{30-29} = 0b00; 4554 let Inst{28-24} = 0b11110; 4555 let Inst{23-22} = type; 4556 let Inst{21} = 1; 4557 let Inst{20-19} = rmode; 4558 let Inst{18-16} = opcode; 4559 let Inst{15-10} = 0; 4560 let Inst{9-5} = Rn; 4561 let Inst{4-0} = Rd; 4562} 4563 4564let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4565class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4566 RegisterClass srcType, RegisterClass dstType, 4567 Operand immType, string asm, list<dag> pattern> 4568 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4569 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4570 Sched<[WriteFCvt]> { 4571 bits<5> Rd; 4572 bits<5> Rn; 4573 bits<6> scale; 4574 let Inst{30-29} = 0b00; 4575 let Inst{28-24} = 0b11110; 4576 let Inst{23-22} = type; 4577 let Inst{21} = 0; 4578 let Inst{20-19} = rmode; 4579 let Inst{18-16} = opcode; 4580 let Inst{15-10} = scale; 4581 let Inst{9-5} = Rn; 4582 let Inst{4-0} = Rd; 4583} 4584 4585multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4586 SDPatternOperator OpN> { 4587 // Unscaled half-precision to 32-bit 4588 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4589 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4590 let Inst{31} = 0; // 32-bit GPR flag 4591 let Predicates = [HasFullFP16]; 4592 } 4593 4594 // Unscaled half-precision to 64-bit 4595 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4596 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4597 let Inst{31} = 1; // 64-bit GPR flag 4598 let Predicates = [HasFullFP16]; 4599 } 4600 4601 // Unscaled single-precision to 32-bit 4602 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4603 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4604 let Inst{31} = 0; // 32-bit GPR flag 4605 } 4606 4607 // Unscaled single-precision to 64-bit 4608 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4609 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4610 let Inst{31} = 1; // 64-bit GPR flag 4611 } 4612 4613 // Unscaled double-precision to 32-bit 4614 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4615 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4616 let Inst{31} = 0; // 32-bit GPR flag 4617 } 4618 4619 // Unscaled double-precision to 64-bit 4620 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4621 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4622 let Inst{31} = 1; // 64-bit GPR flag 4623 } 4624} 4625 4626multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4627 SDPatternOperator OpN> { 4628 // Scaled half-precision to 32-bit 4629 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4630 fixedpoint_f16_i32, asm, 4631 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4632 fixedpoint_f16_i32:$scale)))]> { 4633 let Inst{31} = 0; // 32-bit GPR flag 4634 let scale{5} = 1; 4635 let Predicates = [HasFullFP16]; 4636 } 4637 4638 // Scaled half-precision to 64-bit 4639 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4640 fixedpoint_f16_i64, asm, 4641 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4642 fixedpoint_f16_i64:$scale)))]> { 4643 let Inst{31} = 1; // 64-bit GPR flag 4644 let Predicates = [HasFullFP16]; 4645 } 4646 4647 // Scaled single-precision to 32-bit 4648 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4649 fixedpoint_f32_i32, asm, 4650 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4651 fixedpoint_f32_i32:$scale)))]> { 4652 let Inst{31} = 0; // 32-bit GPR flag 4653 let scale{5} = 1; 4654 } 4655 4656 // Scaled single-precision to 64-bit 4657 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4658 fixedpoint_f32_i64, asm, 4659 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4660 fixedpoint_f32_i64:$scale)))]> { 4661 let Inst{31} = 1; // 64-bit GPR flag 4662 } 4663 4664 // Scaled double-precision to 32-bit 4665 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4666 fixedpoint_f64_i32, asm, 4667 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4668 fixedpoint_f64_i32:$scale)))]> { 4669 let Inst{31} = 0; // 32-bit GPR flag 4670 let scale{5} = 1; 4671 } 4672 4673 // Scaled double-precision to 64-bit 4674 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4675 fixedpoint_f64_i64, asm, 4676 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4677 fixedpoint_f64_i64:$scale)))]> { 4678 let Inst{31} = 1; // 64-bit GPR flag 4679 } 4680} 4681 4682//--- 4683// Integer to floating point conversion 4684//--- 4685 4686let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4687class BaseIntegerToFP<bit isUnsigned, 4688 RegisterClass srcType, RegisterClass dstType, 4689 Operand immType, string asm, list<dag> pattern> 4690 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4691 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4692 Sched<[WriteFCvt]> { 4693 bits<5> Rd; 4694 bits<5> Rn; 4695 bits<6> scale; 4696 let Inst{30-24} = 0b0011110; 4697 let Inst{21-17} = 0b00001; 4698 let Inst{16} = isUnsigned; 4699 let Inst{15-10} = scale; 4700 let Inst{9-5} = Rn; 4701 let Inst{4-0} = Rd; 4702} 4703 4704class BaseIntegerToFPUnscaled<bit isUnsigned, 4705 RegisterClass srcType, RegisterClass dstType, 4706 ValueType dvt, string asm, SDPatternOperator node> 4707 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4708 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4709 Sched<[WriteFCvt]> { 4710 bits<5> Rd; 4711 bits<5> Rn; 4712 bits<6> scale; 4713 let Inst{30-24} = 0b0011110; 4714 let Inst{21-17} = 0b10001; 4715 let Inst{16} = isUnsigned; 4716 let Inst{15-10} = 0b000000; 4717 let Inst{9-5} = Rn; 4718 let Inst{4-0} = Rd; 4719} 4720 4721multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4722 // Unscaled 4723 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4724 let Inst{31} = 0; // 32-bit GPR flag 4725 let Inst{23-22} = 0b11; // 16-bit FPR flag 4726 let Predicates = [HasFullFP16]; 4727 } 4728 4729 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4730 let Inst{31} = 0; // 32-bit GPR flag 4731 let Inst{23-22} = 0b00; // 32-bit FPR flag 4732 } 4733 4734 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4735 let Inst{31} = 0; // 32-bit GPR flag 4736 let Inst{23-22} = 0b01; // 64-bit FPR flag 4737 } 4738 4739 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4740 let Inst{31} = 1; // 64-bit GPR flag 4741 let Inst{23-22} = 0b11; // 16-bit FPR flag 4742 let Predicates = [HasFullFP16]; 4743 } 4744 4745 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4746 let Inst{31} = 1; // 64-bit GPR flag 4747 let Inst{23-22} = 0b00; // 32-bit FPR flag 4748 } 4749 4750 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4751 let Inst{31} = 1; // 64-bit GPR flag 4752 let Inst{23-22} = 0b01; // 64-bit FPR flag 4753 } 4754 4755 // Scaled 4756 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4757 [(set (f16 FPR16:$Rd), 4758 (fdiv (node GPR32:$Rn), 4759 fixedpoint_f16_i32:$scale))]> { 4760 let Inst{31} = 0; // 32-bit GPR flag 4761 let Inst{23-22} = 0b11; // 16-bit FPR flag 4762 let scale{5} = 1; 4763 let Predicates = [HasFullFP16]; 4764 } 4765 4766 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4767 [(set FPR32:$Rd, 4768 (fdiv (node GPR32:$Rn), 4769 fixedpoint_f32_i32:$scale))]> { 4770 let Inst{31} = 0; // 32-bit GPR flag 4771 let Inst{23-22} = 0b00; // 32-bit FPR flag 4772 let scale{5} = 1; 4773 } 4774 4775 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4776 [(set FPR64:$Rd, 4777 (fdiv (node GPR32:$Rn), 4778 fixedpoint_f64_i32:$scale))]> { 4779 let Inst{31} = 0; // 32-bit GPR flag 4780 let Inst{23-22} = 0b01; // 64-bit FPR flag 4781 let scale{5} = 1; 4782 } 4783 4784 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4785 [(set (f16 FPR16:$Rd), 4786 (fdiv (node GPR64:$Rn), 4787 fixedpoint_f16_i64:$scale))]> { 4788 let Inst{31} = 1; // 64-bit GPR flag 4789 let Inst{23-22} = 0b11; // 16-bit FPR flag 4790 let Predicates = [HasFullFP16]; 4791 } 4792 4793 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4794 [(set FPR32:$Rd, 4795 (fdiv (node GPR64:$Rn), 4796 fixedpoint_f32_i64:$scale))]> { 4797 let Inst{31} = 1; // 64-bit GPR flag 4798 let Inst{23-22} = 0b00; // 32-bit FPR flag 4799 } 4800 4801 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4802 [(set FPR64:$Rd, 4803 (fdiv (node GPR64:$Rn), 4804 fixedpoint_f64_i64:$scale))]> { 4805 let Inst{31} = 1; // 64-bit GPR flag 4806 let Inst{23-22} = 0b01; // 64-bit FPR flag 4807 } 4808} 4809 4810//--- 4811// Unscaled integer <-> floating point conversion (i.e. FMOV) 4812//--- 4813 4814let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4815class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4816 RegisterClass srcType, RegisterClass dstType, 4817 string asm> 4818 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4819 // We use COPY_TO_REGCLASS for these bitconvert operations. 4820 // copyPhysReg() expands the resultant COPY instructions after 4821 // regalloc is done. This gives greater freedom for the allocator 4822 // and related passes (coalescing, copy propagation, et. al.) to 4823 // be more effective. 4824 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4825 Sched<[WriteFCopy]> { 4826 bits<5> Rd; 4827 bits<5> Rn; 4828 let Inst{30-24} = 0b0011110; 4829 let Inst{21} = 1; 4830 let Inst{20-19} = rmode; 4831 let Inst{18-16} = opcode; 4832 let Inst{15-10} = 0b000000; 4833 let Inst{9-5} = Rn; 4834 let Inst{4-0} = Rd; 4835} 4836 4837let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4838class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4839 RegisterClass srcType, RegisterOperand dstType, string asm, 4840 string kind> 4841 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4842 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4843 Sched<[WriteFCopy]> { 4844 bits<5> Rd; 4845 bits<5> Rn; 4846 let Inst{30-23} = 0b00111101; 4847 let Inst{21} = 1; 4848 let Inst{20-19} = rmode; 4849 let Inst{18-16} = opcode; 4850 let Inst{15-10} = 0b000000; 4851 let Inst{9-5} = Rn; 4852 let Inst{4-0} = Rd; 4853 4854 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4855} 4856 4857let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4858class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4859 RegisterOperand srcType, RegisterClass dstType, string asm, 4860 string kind> 4861 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4862 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4863 Sched<[WriteFCopy]> { 4864 bits<5> Rd; 4865 bits<5> Rn; 4866 let Inst{30-23} = 0b00111101; 4867 let Inst{21} = 1; 4868 let Inst{20-19} = rmode; 4869 let Inst{18-16} = opcode; 4870 let Inst{15-10} = 0b000000; 4871 let Inst{9-5} = Rn; 4872 let Inst{4-0} = Rd; 4873 4874 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4875} 4876 4877 4878multiclass UnscaledConversion<string asm> { 4879 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4880 let Inst{31} = 0; // 32-bit GPR flag 4881 let Inst{23-22} = 0b11; // 16-bit FPR flag 4882 let Predicates = [HasFullFP16]; 4883 } 4884 4885 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4886 let Inst{31} = 1; // 64-bit GPR flag 4887 let Inst{23-22} = 0b11; // 16-bit FPR flag 4888 let Predicates = [HasFullFP16]; 4889 } 4890 4891 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4892 let Inst{31} = 0; // 32-bit GPR flag 4893 let Inst{23-22} = 0b00; // 32-bit FPR flag 4894 } 4895 4896 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4897 let Inst{31} = 1; // 64-bit GPR flag 4898 let Inst{23-22} = 0b01; // 64-bit FPR flag 4899 } 4900 4901 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4902 let Inst{31} = 0; // 32-bit GPR flag 4903 let Inst{23-22} = 0b11; // 16-bit FPR flag 4904 let Predicates = [HasFullFP16]; 4905 } 4906 4907 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4908 let Inst{31} = 1; // 64-bit GPR flag 4909 let Inst{23-22} = 0b11; // 16-bit FPR flag 4910 let Predicates = [HasFullFP16]; 4911 } 4912 4913 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4914 let Inst{31} = 0; // 32-bit GPR flag 4915 let Inst{23-22} = 0b00; // 32-bit FPR flag 4916 } 4917 4918 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4919 let Inst{31} = 1; // 64-bit GPR flag 4920 let Inst{23-22} = 0b01; // 64-bit FPR flag 4921 } 4922 4923 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4924 asm, ".d"> { 4925 let Inst{31} = 1; 4926 let Inst{22} = 0; 4927 } 4928 4929 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4930 asm, ".d"> { 4931 let Inst{31} = 1; 4932 let Inst{22} = 0; 4933 } 4934} 4935 4936//--- 4937// Floating point conversion 4938//--- 4939 4940class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4941 RegisterClass srcType, string asm, list<dag> pattern> 4942 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4943 Sched<[WriteFCvt]> { 4944 bits<5> Rd; 4945 bits<5> Rn; 4946 let Inst{31-24} = 0b00011110; 4947 let Inst{23-22} = type; 4948 let Inst{21-17} = 0b10001; 4949 let Inst{16-15} = opcode; 4950 let Inst{14-10} = 0b10000; 4951 let Inst{9-5} = Rn; 4952 let Inst{4-0} = Rd; 4953} 4954 4955multiclass FPConversion<string asm> { 4956 // Double-precision to Half-precision 4957 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4958 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4959 4960 // Double-precision to Single-precision 4961 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4962 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4963 4964 // Half-precision to Double-precision 4965 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4966 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4967 4968 // Half-precision to Single-precision 4969 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4970 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4971 4972 // Single-precision to Double-precision 4973 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4974 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4975 4976 // Single-precision to Half-precision 4977 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4978 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 4979} 4980 4981//--- 4982// Single operand floating point data processing 4983//--- 4984 4985let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4986class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4987 ValueType vt, string asm, SDPatternOperator node> 4988 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4989 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4990 Sched<[WriteF]> { 4991 bits<5> Rd; 4992 bits<5> Rn; 4993 let Inst{31-24} = 0b00011110; 4994 let Inst{21} = 0b1; 4995 let Inst{20-15} = opcode; 4996 let Inst{14-10} = 0b10000; 4997 let Inst{9-5} = Rn; 4998 let Inst{4-0} = Rd; 4999} 5000 5001multiclass SingleOperandFPData<bits<4> opcode, string asm, 5002 SDPatternOperator node = null_frag> { 5003 5004 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5005 let Inst{23-22} = 0b11; // 16-bit size flag 5006 let Predicates = [HasFullFP16]; 5007 } 5008 5009 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5010 let Inst{23-22} = 0b00; // 32-bit size flag 5011 } 5012 5013 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5014 let Inst{23-22} = 0b01; // 64-bit size flag 5015 } 5016} 5017 5018multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5019 SDPatternOperator node = null_frag>{ 5020 5021 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5022 let Inst{23-22} = 0b00; // 32-bit registers 5023 } 5024 5025 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5026 let Inst{23-22} = 0b01; // 64-bit registers 5027 } 5028} 5029 5030// FRInt[32|64][Z|N] instructions 5031multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5032 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5033 5034//--- 5035// Two operand floating point data processing 5036//--- 5037 5038let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5039class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5040 string asm, list<dag> pat> 5041 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5042 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5043 Sched<[WriteF]> { 5044 bits<5> Rd; 5045 bits<5> Rn; 5046 bits<5> Rm; 5047 let Inst{31-24} = 0b00011110; 5048 let Inst{21} = 1; 5049 let Inst{20-16} = Rm; 5050 let Inst{15-12} = opcode; 5051 let Inst{11-10} = 0b10; 5052 let Inst{9-5} = Rn; 5053 let Inst{4-0} = Rd; 5054} 5055 5056multiclass TwoOperandFPData<bits<4> opcode, string asm, 5057 SDPatternOperator node = null_frag> { 5058 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5059 [(set (f16 FPR16:$Rd), 5060 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5061 let Inst{23-22} = 0b11; // 16-bit size flag 5062 let Predicates = [HasFullFP16]; 5063 } 5064 5065 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5066 [(set (f32 FPR32:$Rd), 5067 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5068 let Inst{23-22} = 0b00; // 32-bit size flag 5069 } 5070 5071 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5072 [(set (f64 FPR64:$Rd), 5073 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5074 let Inst{23-22} = 0b01; // 64-bit size flag 5075 } 5076} 5077 5078multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 5079 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5080 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5081 let Inst{23-22} = 0b11; // 16-bit size flag 5082 let Predicates = [HasFullFP16]; 5083 } 5084 5085 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5086 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5087 let Inst{23-22} = 0b00; // 32-bit size flag 5088 } 5089 5090 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5091 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5092 let Inst{23-22} = 0b01; // 64-bit size flag 5093 } 5094} 5095 5096 5097//--- 5098// Three operand floating point data processing 5099//--- 5100 5101class BaseThreeOperandFPData<bit isNegated, bit isSub, 5102 RegisterClass regtype, string asm, list<dag> pat> 5103 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5104 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5105 Sched<[WriteFMul]> { 5106 bits<5> Rd; 5107 bits<5> Rn; 5108 bits<5> Rm; 5109 bits<5> Ra; 5110 let Inst{31-24} = 0b00011111; 5111 let Inst{21} = isNegated; 5112 let Inst{20-16} = Rm; 5113 let Inst{15} = isSub; 5114 let Inst{14-10} = Ra; 5115 let Inst{9-5} = Rn; 5116 let Inst{4-0} = Rd; 5117} 5118 5119multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5120 SDPatternOperator node> { 5121 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5122 [(set (f16 FPR16:$Rd), 5123 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5124 let Inst{23-22} = 0b11; // 16-bit size flag 5125 let Predicates = [HasFullFP16]; 5126 } 5127 5128 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5129 [(set FPR32:$Rd, 5130 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5131 let Inst{23-22} = 0b00; // 32-bit size flag 5132 } 5133 5134 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5135 [(set FPR64:$Rd, 5136 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5137 let Inst{23-22} = 0b01; // 64-bit size flag 5138 } 5139} 5140 5141//--- 5142// Floating point data comparisons 5143//--- 5144 5145let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5146class BaseOneOperandFPComparison<bit signalAllNans, 5147 RegisterClass regtype, string asm, 5148 list<dag> pat> 5149 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5150 Sched<[WriteFCmp]> { 5151 bits<5> Rn; 5152 let Inst{31-24} = 0b00011110; 5153 let Inst{21} = 1; 5154 5155 let Inst{15-10} = 0b001000; 5156 let Inst{9-5} = Rn; 5157 let Inst{4} = signalAllNans; 5158 let Inst{3-0} = 0b1000; 5159 5160 // Rm should be 0b00000 canonically, but we need to accept any value. 5161 let PostEncoderMethod = "fixOneOperandFPComparison"; 5162} 5163 5164let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5165class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5166 string asm, list<dag> pat> 5167 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5168 Sched<[WriteFCmp]> { 5169 bits<5> Rm; 5170 bits<5> Rn; 5171 let Inst{31-24} = 0b00011110; 5172 let Inst{21} = 1; 5173 let Inst{20-16} = Rm; 5174 let Inst{15-10} = 0b001000; 5175 let Inst{9-5} = Rn; 5176 let Inst{4} = signalAllNans; 5177 let Inst{3-0} = 0b0000; 5178} 5179 5180multiclass FPComparison<bit signalAllNans, string asm, 5181 SDPatternOperator OpNode = null_frag> { 5182 let Defs = [NZCV] in { 5183 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5184 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5185 let Inst{23-22} = 0b11; 5186 let Predicates = [HasFullFP16]; 5187 } 5188 5189 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5190 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5191 let Inst{23-22} = 0b11; 5192 let Predicates = [HasFullFP16]; 5193 } 5194 5195 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5196 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5197 let Inst{23-22} = 0b00; 5198 } 5199 5200 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5201 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5202 let Inst{23-22} = 0b00; 5203 } 5204 5205 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5206 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5207 let Inst{23-22} = 0b01; 5208 } 5209 5210 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5211 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5212 let Inst{23-22} = 0b01; 5213 } 5214 } // Defs = [NZCV] 5215} 5216 5217//--- 5218// Floating point conditional comparisons 5219//--- 5220 5221let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5222class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5223 string mnemonic, list<dag> pat> 5224 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5225 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5226 Sched<[WriteFCmp]> { 5227 let Uses = [NZCV]; 5228 let Defs = [NZCV]; 5229 5230 bits<5> Rn; 5231 bits<5> Rm; 5232 bits<4> nzcv; 5233 bits<4> cond; 5234 5235 let Inst{31-24} = 0b00011110; 5236 let Inst{21} = 1; 5237 let Inst{20-16} = Rm; 5238 let Inst{15-12} = cond; 5239 let Inst{11-10} = 0b01; 5240 let Inst{9-5} = Rn; 5241 let Inst{4} = signalAllNans; 5242 let Inst{3-0} = nzcv; 5243} 5244 5245multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5246 SDPatternOperator OpNode = null_frag> { 5247 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5248 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5249 (i32 imm:$cond), NZCV))]> { 5250 let Inst{23-22} = 0b11; 5251 let Predicates = [HasFullFP16]; 5252 } 5253 5254 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5255 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5256 (i32 imm:$cond), NZCV))]> { 5257 let Inst{23-22} = 0b00; 5258 } 5259 5260 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5261 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5262 (i32 imm:$cond), NZCV))]> { 5263 let Inst{23-22} = 0b01; 5264 } 5265} 5266 5267//--- 5268// Floating point conditional select 5269//--- 5270 5271class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5272 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5273 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5274 [(set regtype:$Rd, 5275 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5276 (i32 imm:$cond), NZCV))]>, 5277 Sched<[WriteF]> { 5278 bits<5> Rd; 5279 bits<5> Rn; 5280 bits<5> Rm; 5281 bits<4> cond; 5282 5283 let Inst{31-24} = 0b00011110; 5284 let Inst{21} = 1; 5285 let Inst{20-16} = Rm; 5286 let Inst{15-12} = cond; 5287 let Inst{11-10} = 0b11; 5288 let Inst{9-5} = Rn; 5289 let Inst{4-0} = Rd; 5290} 5291 5292multiclass FPCondSelect<string asm> { 5293 let Uses = [NZCV] in { 5294 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5295 let Inst{23-22} = 0b11; 5296 let Predicates = [HasFullFP16]; 5297 } 5298 5299 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5300 let Inst{23-22} = 0b00; 5301 } 5302 5303 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5304 let Inst{23-22} = 0b01; 5305 } 5306 } // Uses = [NZCV] 5307} 5308 5309//--- 5310// Floating move immediate 5311//--- 5312 5313class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5314 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5315 [(set regtype:$Rd, fpimmtype:$imm)]>, 5316 Sched<[WriteFImm]> { 5317 bits<5> Rd; 5318 bits<8> imm; 5319 let Inst{31-24} = 0b00011110; 5320 let Inst{21} = 1; 5321 let Inst{20-13} = imm; 5322 let Inst{12-5} = 0b10000000; 5323 let Inst{4-0} = Rd; 5324} 5325 5326multiclass FPMoveImmediate<string asm> { 5327 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5328 let Inst{23-22} = 0b11; 5329 let Predicates = [HasFullFP16]; 5330 } 5331 5332 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5333 let Inst{23-22} = 0b00; 5334 } 5335 5336 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5337 let Inst{23-22} = 0b01; 5338 } 5339} 5340} // end of 'let Predicates = [HasFPARMv8]' 5341 5342//---------------------------------------------------------------------------- 5343// AdvSIMD 5344//---------------------------------------------------------------------------- 5345 5346let Predicates = [HasNEON] in { 5347 5348//---------------------------------------------------------------------------- 5349// AdvSIMD three register vector instructions 5350//---------------------------------------------------------------------------- 5351 5352let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5353class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5354 RegisterOperand regtype, string asm, string kind, 5355 list<dag> pattern> 5356 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5357 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5358 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5359 Sched<[!if(Q, WriteVq, WriteVd)]> { 5360 bits<5> Rd; 5361 bits<5> Rn; 5362 bits<5> Rm; 5363 let Inst{31} = 0; 5364 let Inst{30} = Q; 5365 let Inst{29} = U; 5366 let Inst{28-24} = 0b01110; 5367 let Inst{23-21} = size; 5368 let Inst{20-16} = Rm; 5369 let Inst{15-11} = opcode; 5370 let Inst{10} = 1; 5371 let Inst{9-5} = Rn; 5372 let Inst{4-0} = Rd; 5373} 5374 5375let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5376class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5377 RegisterOperand regtype, string asm, string kind, 5378 list<dag> pattern> 5379 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5380 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5381 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5382 Sched<[!if(Q, WriteVq, WriteVd)]> { 5383 bits<5> Rd; 5384 bits<5> Rn; 5385 bits<5> Rm; 5386 let Inst{31} = 0; 5387 let Inst{30} = Q; 5388 let Inst{29} = U; 5389 let Inst{28-24} = 0b01110; 5390 let Inst{23-21} = size; 5391 let Inst{20-16} = Rm; 5392 let Inst{15-11} = opcode; 5393 let Inst{10} = 1; 5394 let Inst{9-5} = Rn; 5395 let Inst{4-0} = Rd; 5396} 5397 5398let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5399class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5400 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5401 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5402 5403multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5404 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5405 [(set (v8i8 V64:$dst), 5406 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5407 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5408 [(set (v16i8 V128:$dst), 5409 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5410 (v16i8 V128:$Rm)))]>; 5411 5412 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5413 (v4i16 V64:$RHS))), 5414 (!cast<Instruction>(NAME#"v8i8") 5415 V64:$LHS, V64:$MHS, V64:$RHS)>; 5416 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5417 (v2i32 V64:$RHS))), 5418 (!cast<Instruction>(NAME#"v8i8") 5419 V64:$LHS, V64:$MHS, V64:$RHS)>; 5420 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5421 (v1i64 V64:$RHS))), 5422 (!cast<Instruction>(NAME#"v8i8") 5423 V64:$LHS, V64:$MHS, V64:$RHS)>; 5424 5425 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5426 (v8i16 V128:$RHS))), 5427 (!cast<Instruction>(NAME#"v16i8") 5428 V128:$LHS, V128:$MHS, V128:$RHS)>; 5429 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5430 (v4i32 V128:$RHS))), 5431 (!cast<Instruction>(NAME#"v16i8") 5432 V128:$LHS, V128:$MHS, V128:$RHS)>; 5433 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5434 (v2i64 V128:$RHS))), 5435 (!cast<Instruction>(NAME#"v16i8") 5436 V128:$LHS, V128:$MHS, V128:$RHS)>; 5437} 5438 5439// All operand sizes distinguished in the encoding. 5440multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5441 SDPatternOperator OpNode> { 5442 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5443 asm, ".8b", 5444 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5445 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5446 asm, ".16b", 5447 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5448 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5449 asm, ".4h", 5450 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5451 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5452 asm, ".8h", 5453 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5454 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5455 asm, ".2s", 5456 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5457 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5458 asm, ".4s", 5459 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5460 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5461 asm, ".2d", 5462 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5463} 5464 5465multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5466 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5467 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5468 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5469 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5470 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5471 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5472 5473 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5474 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5475 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5476 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5477 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5478 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5479 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5480 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5481} 5482 5483// As above, but D sized elements unsupported. 5484multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5485 SDPatternOperator OpNode> { 5486 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5487 asm, ".8b", 5488 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5489 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5490 asm, ".16b", 5491 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5492 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5493 asm, ".4h", 5494 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5495 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5496 asm, ".8h", 5497 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5498 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5499 asm, ".2s", 5500 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5501 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5502 asm, ".4s", 5503 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5504} 5505 5506multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5507 SDPatternOperator OpNode> { 5508 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5509 asm, ".8b", 5510 [(set (v8i8 V64:$dst), 5511 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5512 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5513 asm, ".16b", 5514 [(set (v16i8 V128:$dst), 5515 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5516 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5517 asm, ".4h", 5518 [(set (v4i16 V64:$dst), 5519 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5520 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5521 asm, ".8h", 5522 [(set (v8i16 V128:$dst), 5523 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5524 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5525 asm, ".2s", 5526 [(set (v2i32 V64:$dst), 5527 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5528 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5529 asm, ".4s", 5530 [(set (v4i32 V128:$dst), 5531 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5532} 5533 5534// As above, but only B sized elements supported. 5535multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5536 SDPatternOperator OpNode> { 5537 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5538 asm, ".8b", 5539 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5540 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5541 asm, ".16b", 5542 [(set (v16i8 V128:$Rd), 5543 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5544} 5545 5546// As above, but only floating point elements supported. 5547multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5548 string asm, SDPatternOperator OpNode> { 5549 let Predicates = [HasNEON, HasFullFP16] in { 5550 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5551 asm, ".4h", 5552 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5553 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5554 asm, ".8h", 5555 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5556 } // Predicates = [HasNEON, HasFullFP16] 5557 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5558 asm, ".2s", 5559 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5560 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5561 asm, ".4s", 5562 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5563 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5564 asm, ".2d", 5565 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5566} 5567 5568multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5569 string asm, 5570 SDPatternOperator OpNode> { 5571 let Predicates = [HasNEON, HasFullFP16] in { 5572 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5573 asm, ".4h", 5574 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5575 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5576 asm, ".8h", 5577 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5578 } // Predicates = [HasNEON, HasFullFP16] 5579 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5580 asm, ".2s", 5581 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5582 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5583 asm, ".4s", 5584 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5585 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5586 asm, ".2d", 5587 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5588} 5589 5590multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5591 string asm, SDPatternOperator OpNode> { 5592 let Predicates = [HasNEON, HasFullFP16] in { 5593 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5594 asm, ".4h", 5595 [(set (v4f16 V64:$dst), 5596 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5597 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5598 asm, ".8h", 5599 [(set (v8f16 V128:$dst), 5600 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5601 } // Predicates = [HasNEON, HasFullFP16] 5602 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5603 asm, ".2s", 5604 [(set (v2f32 V64:$dst), 5605 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5606 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5607 asm, ".4s", 5608 [(set (v4f32 V128:$dst), 5609 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5610 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5611 asm, ".2d", 5612 [(set (v2f64 V128:$dst), 5613 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5614} 5615 5616// As above, but D and B sized elements unsupported. 5617multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5618 SDPatternOperator OpNode> { 5619 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5620 asm, ".4h", 5621 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5622 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5623 asm, ".8h", 5624 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5625 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5626 asm, ".2s", 5627 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5628 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5629 asm, ".4s", 5630 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5631} 5632 5633// Logical three vector ops share opcode bits, and only use B sized elements. 5634multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5635 SDPatternOperator OpNode = null_frag> { 5636 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5637 asm, ".8b", 5638 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5639 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5640 asm, ".16b", 5641 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5642 5643 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5644 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5645 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5646 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5647 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5648 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5649 5650 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5651 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5652 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5653 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5654 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5655 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5656} 5657 5658multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5659 string asm, SDPatternOperator OpNode = null_frag> { 5660 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5661 asm, ".8b", 5662 [(set (v8i8 V64:$dst), 5663 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5664 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5665 asm, ".16b", 5666 [(set (v16i8 V128:$dst), 5667 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5668 (v16i8 V128:$Rm)))]>; 5669 5670 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5671 (v4i16 V64:$RHS))), 5672 (!cast<Instruction>(NAME#"v8i8") 5673 V64:$LHS, V64:$MHS, V64:$RHS)>; 5674 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5675 (v2i32 V64:$RHS))), 5676 (!cast<Instruction>(NAME#"v8i8") 5677 V64:$LHS, V64:$MHS, V64:$RHS)>; 5678 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5679 (v1i64 V64:$RHS))), 5680 (!cast<Instruction>(NAME#"v8i8") 5681 V64:$LHS, V64:$MHS, V64:$RHS)>; 5682 5683 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5684 (v8i16 V128:$RHS))), 5685 (!cast<Instruction>(NAME#"v16i8") 5686 V128:$LHS, V128:$MHS, V128:$RHS)>; 5687 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5688 (v4i32 V128:$RHS))), 5689 (!cast<Instruction>(NAME#"v16i8") 5690 V128:$LHS, V128:$MHS, V128:$RHS)>; 5691 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5692 (v2i64 V128:$RHS))), 5693 (!cast<Instruction>(NAME#"v16i8") 5694 V128:$LHS, V128:$MHS, V128:$RHS)>; 5695} 5696 5697// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5698// bytes from S-sized elements. 5699class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5700 string kind2, RegisterOperand RegType, 5701 ValueType AccumType, ValueType InputType, 5702 SDPatternOperator OpNode> : 5703 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5704 [(set (AccumType RegType:$dst), 5705 (OpNode (AccumType RegType:$Rd), 5706 (InputType RegType:$Rn), 5707 (InputType RegType:$Rm)))]> { 5708 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5709} 5710 5711multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5712 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5713 v2i32, v8i8, OpNode>; 5714 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5715 v4i32, v16i8, OpNode>; 5716} 5717 5718// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5719// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5720// 8H to 4S, when Q=1). 5721class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5722 string kind2, RegisterOperand RegType, 5723 ValueType AccumType, ValueType InputType, 5724 SDPatternOperator OpNode> : 5725 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5726 [(set (AccumType RegType:$dst), 5727 (OpNode (AccumType RegType:$Rd), 5728 (InputType RegType:$Rn), 5729 (InputType RegType:$Rm)))]> { 5730 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5731 let Inst{13} = b13; 5732} 5733 5734multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5735 SDPatternOperator OpNode> { 5736 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5737 v2f32, v4f16, OpNode>; 5738 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5739 v4f32, v8f16, OpNode>; 5740} 5741 5742 5743//---------------------------------------------------------------------------- 5744// AdvSIMD two register vector instructions. 5745//---------------------------------------------------------------------------- 5746 5747let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5748class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5749 bits<2> size2, RegisterOperand regtype, string asm, 5750 string dstkind, string srckind, list<dag> pattern> 5751 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5752 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5753 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5754 Sched<[!if(Q, WriteVq, WriteVd)]> { 5755 bits<5> Rd; 5756 bits<5> Rn; 5757 let Inst{31} = 0; 5758 let Inst{30} = Q; 5759 let Inst{29} = U; 5760 let Inst{28-24} = 0b01110; 5761 let Inst{23-22} = size; 5762 let Inst{21} = 0b1; 5763 let Inst{20-19} = size2; 5764 let Inst{18-17} = 0b00; 5765 let Inst{16-12} = opcode; 5766 let Inst{11-10} = 0b10; 5767 let Inst{9-5} = Rn; 5768 let Inst{4-0} = Rd; 5769} 5770 5771let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5772class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5773 bits<2> size2, RegisterOperand regtype, 5774 string asm, string dstkind, string srckind, 5775 list<dag> pattern> 5776 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5777 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5778 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5779 Sched<[!if(Q, WriteVq, WriteVd)]> { 5780 bits<5> Rd; 5781 bits<5> Rn; 5782 let Inst{31} = 0; 5783 let Inst{30} = Q; 5784 let Inst{29} = U; 5785 let Inst{28-24} = 0b01110; 5786 let Inst{23-22} = size; 5787 let Inst{21} = 0b1; 5788 let Inst{20-19} = size2; 5789 let Inst{18-17} = 0b00; 5790 let Inst{16-12} = opcode; 5791 let Inst{11-10} = 0b10; 5792 let Inst{9-5} = Rn; 5793 let Inst{4-0} = Rd; 5794} 5795 5796// Supports B, H, and S element sizes. 5797multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5798 SDPatternOperator OpNode> { 5799 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5800 asm, ".8b", ".8b", 5801 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5802 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5803 asm, ".16b", ".16b", 5804 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5805 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5806 asm, ".4h", ".4h", 5807 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5808 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5809 asm, ".8h", ".8h", 5810 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5811 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5812 asm, ".2s", ".2s", 5813 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5814 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5815 asm, ".4s", ".4s", 5816 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5817} 5818 5819class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5820 RegisterOperand regtype, string asm, string dstkind, 5821 string srckind, string amount> 5822 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5823 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5824 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5825 Sched<[WriteVq]> { 5826 bits<5> Rd; 5827 bits<5> Rn; 5828 let Inst{31} = 0; 5829 let Inst{30} = Q; 5830 let Inst{29-24} = 0b101110; 5831 let Inst{23-22} = size; 5832 let Inst{21-10} = 0b100001001110; 5833 let Inst{9-5} = Rn; 5834 let Inst{4-0} = Rd; 5835} 5836 5837multiclass SIMDVectorLShiftLongBySizeBHS { 5838 let hasSideEffects = 0 in { 5839 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5840 "shll", ".8h", ".8b", "8">; 5841 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5842 "shll2", ".8h", ".16b", "8">; 5843 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5844 "shll", ".4s", ".4h", "16">; 5845 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5846 "shll2", ".4s", ".8h", "16">; 5847 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5848 "shll", ".2d", ".2s", "32">; 5849 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5850 "shll2", ".2d", ".4s", "32">; 5851 } 5852} 5853 5854// Supports all element sizes. 5855multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5856 SDPatternOperator OpNode> { 5857 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5858 asm, ".4h", ".8b", 5859 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5860 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5861 asm, ".8h", ".16b", 5862 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5863 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5864 asm, ".2s", ".4h", 5865 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5866 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5867 asm, ".4s", ".8h", 5868 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5869 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5870 asm, ".1d", ".2s", 5871 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5872 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5873 asm, ".2d", ".4s", 5874 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5875} 5876 5877multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5878 SDPatternOperator OpNode> { 5879 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5880 asm, ".4h", ".8b", 5881 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5882 (v8i8 V64:$Rn)))]>; 5883 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5884 asm, ".8h", ".16b", 5885 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5886 (v16i8 V128:$Rn)))]>; 5887 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5888 asm, ".2s", ".4h", 5889 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5890 (v4i16 V64:$Rn)))]>; 5891 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5892 asm, ".4s", ".8h", 5893 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5894 (v8i16 V128:$Rn)))]>; 5895 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5896 asm, ".1d", ".2s", 5897 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5898 (v2i32 V64:$Rn)))]>; 5899 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5900 asm, ".2d", ".4s", 5901 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5902 (v4i32 V128:$Rn)))]>; 5903} 5904 5905// Supports all element sizes, except 1xD. 5906multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5907 SDPatternOperator OpNode> { 5908 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5909 asm, ".8b", ".8b", 5910 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5911 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5912 asm, ".16b", ".16b", 5913 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5914 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5915 asm, ".4h", ".4h", 5916 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5917 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5918 asm, ".8h", ".8h", 5919 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5920 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5921 asm, ".2s", ".2s", 5922 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5923 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5924 asm, ".4s", ".4s", 5925 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5926 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5927 asm, ".2d", ".2d", 5928 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5929} 5930 5931multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5932 SDPatternOperator OpNode = null_frag> { 5933 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5934 asm, ".8b", ".8b", 5935 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5936 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5937 asm, ".16b", ".16b", 5938 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5939 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5940 asm, ".4h", ".4h", 5941 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5942 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5943 asm, ".8h", ".8h", 5944 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5945 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5946 asm, ".2s", ".2s", 5947 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5948 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5949 asm, ".4s", ".4s", 5950 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5951 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5952 asm, ".2d", ".2d", 5953 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5954} 5955 5956 5957// Supports only B element sizes. 5958multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5959 SDPatternOperator OpNode> { 5960 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5961 asm, ".8b", ".8b", 5962 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5963 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5964 asm, ".16b", ".16b", 5965 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5966 5967} 5968 5969// Supports only B and H element sizes. 5970multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5971 SDPatternOperator OpNode> { 5972 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5973 asm, ".8b", ".8b", 5974 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5975 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5976 asm, ".16b", ".16b", 5977 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5978 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5979 asm, ".4h", ".4h", 5980 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5981 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5982 asm, ".8h", ".8h", 5983 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5984} 5985 5986// Supports H, S and D element sizes, uses high bit of the size field 5987// as an extra opcode bit. 5988multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5989 SDPatternOperator OpNode> { 5990 let Predicates = [HasNEON, HasFullFP16] in { 5991 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5992 asm, ".4h", ".4h", 5993 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5994 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5995 asm, ".8h", ".8h", 5996 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5997 } // Predicates = [HasNEON, HasFullFP16] 5998 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5999 asm, ".2s", ".2s", 6000 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6001 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6002 asm, ".4s", ".4s", 6003 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6004 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6005 asm, ".2d", ".2d", 6006 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6007} 6008 6009// Supports only S and D element sizes 6010multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6011 SDPatternOperator OpNode = null_frag> { 6012 6013 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6014 asm, ".2s", ".2s", 6015 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6016 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6017 asm, ".4s", ".4s", 6018 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6019 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6020 asm, ".2d", ".2d", 6021 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6022} 6023 6024multiclass FRIntNNTVector<bit U, bit op, string asm, 6025 SDPatternOperator OpNode = null_frag> : 6026 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6027 6028// Supports only S element size. 6029multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6030 SDPatternOperator OpNode> { 6031 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6032 asm, ".2s", ".2s", 6033 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6034 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6035 asm, ".4s", ".4s", 6036 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6037} 6038 6039 6040multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6041 SDPatternOperator OpNode> { 6042 let Predicates = [HasNEON, HasFullFP16] in { 6043 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6044 asm, ".4h", ".4h", 6045 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6046 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6047 asm, ".8h", ".8h", 6048 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6049 } // Predicates = [HasNEON, HasFullFP16] 6050 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6051 asm, ".2s", ".2s", 6052 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6053 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6054 asm, ".4s", ".4s", 6055 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6056 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6057 asm, ".2d", ".2d", 6058 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6059} 6060 6061multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6062 SDPatternOperator OpNode> { 6063 let Predicates = [HasNEON, HasFullFP16] in { 6064 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6065 asm, ".4h", ".4h", 6066 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6067 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6068 asm, ".8h", ".8h", 6069 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6070 } // Predicates = [HasNEON, HasFullFP16] 6071 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6072 asm, ".2s", ".2s", 6073 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6074 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6075 asm, ".4s", ".4s", 6076 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6077 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6078 asm, ".2d", ".2d", 6079 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6080} 6081 6082let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6083class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6084 RegisterOperand inreg, RegisterOperand outreg, 6085 string asm, string outkind, string inkind, 6086 list<dag> pattern> 6087 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6088 "{\t$Rd" # outkind # ", $Rn" # inkind # 6089 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6090 Sched<[WriteVq]> { 6091 bits<5> Rd; 6092 bits<5> Rn; 6093 let Inst{31} = 0; 6094 let Inst{30} = Q; 6095 let Inst{29} = U; 6096 let Inst{28-24} = 0b01110; 6097 let Inst{23-22} = size; 6098 let Inst{21-17} = 0b10000; 6099 let Inst{16-12} = opcode; 6100 let Inst{11-10} = 0b10; 6101 let Inst{9-5} = Rn; 6102 let Inst{4-0} = Rd; 6103} 6104 6105let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6106class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6107 RegisterOperand inreg, RegisterOperand outreg, 6108 string asm, string outkind, string inkind, 6109 list<dag> pattern> 6110 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6111 "{\t$Rd" # outkind # ", $Rn" # inkind # 6112 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6113 Sched<[WriteVq]> { 6114 bits<5> Rd; 6115 bits<5> Rn; 6116 let Inst{31} = 0; 6117 let Inst{30} = Q; 6118 let Inst{29} = U; 6119 let Inst{28-24} = 0b01110; 6120 let Inst{23-22} = size; 6121 let Inst{21-17} = 0b10000; 6122 let Inst{16-12} = opcode; 6123 let Inst{11-10} = 0b10; 6124 let Inst{9-5} = Rn; 6125 let Inst{4-0} = Rd; 6126} 6127 6128multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6129 SDPatternOperator OpNode> { 6130 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6131 asm, ".8b", ".8h", 6132 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6133 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6134 asm#"2", ".16b", ".8h", []>; 6135 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6136 asm, ".4h", ".4s", 6137 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6138 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6139 asm#"2", ".8h", ".4s", []>; 6140 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6141 asm, ".2s", ".2d", 6142 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6143 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6144 asm#"2", ".4s", ".2d", []>; 6145 6146 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6147 (!cast<Instruction>(NAME # "v16i8") 6148 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6149 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6150 (!cast<Instruction>(NAME # "v8i16") 6151 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6152 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6153 (!cast<Instruction>(NAME # "v4i32") 6154 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6155} 6156 6157class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6158 bits<5> opcode, RegisterOperand regtype, string asm, 6159 string kind, string zero, ValueType dty, 6160 ValueType sty, SDNode OpNode> 6161 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6162 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6163 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6164 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6165 Sched<[!if(Q, WriteVq, WriteVd)]> { 6166 bits<5> Rd; 6167 bits<5> Rn; 6168 let Inst{31} = 0; 6169 let Inst{30} = Q; 6170 let Inst{29} = U; 6171 let Inst{28-24} = 0b01110; 6172 let Inst{23-22} = size; 6173 let Inst{21} = 0b1; 6174 let Inst{20-19} = size2; 6175 let Inst{18-17} = 0b00; 6176 let Inst{16-12} = opcode; 6177 let Inst{11-10} = 0b10; 6178 let Inst{9-5} = Rn; 6179 let Inst{4-0} = Rd; 6180} 6181 6182// Comparisons support all element sizes, except 1xD. 6183multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6184 SDNode OpNode> { 6185 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6186 asm, ".8b", "0", 6187 v8i8, v8i8, OpNode>; 6188 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6189 asm, ".16b", "0", 6190 v16i8, v16i8, OpNode>; 6191 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6192 asm, ".4h", "0", 6193 v4i16, v4i16, OpNode>; 6194 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6195 asm, ".8h", "0", 6196 v8i16, v8i16, OpNode>; 6197 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6198 asm, ".2s", "0", 6199 v2i32, v2i32, OpNode>; 6200 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6201 asm, ".4s", "0", 6202 v4i32, v4i32, OpNode>; 6203 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6204 asm, ".2d", "0", 6205 v2i64, v2i64, OpNode>; 6206} 6207 6208// FP Comparisons support only S and D element sizes (and H for v8.2a). 6209multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6210 string asm, SDNode OpNode> { 6211 6212 let Predicates = [HasNEON, HasFullFP16] in { 6213 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6214 asm, ".4h", "0.0", 6215 v4i16, v4f16, OpNode>; 6216 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6217 asm, ".8h", "0.0", 6218 v8i16, v8f16, OpNode>; 6219 } // Predicates = [HasNEON, HasFullFP16] 6220 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6221 asm, ".2s", "0.0", 6222 v2i32, v2f32, OpNode>; 6223 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6224 asm, ".4s", "0.0", 6225 v4i32, v4f32, OpNode>; 6226 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6227 asm, ".2d", "0.0", 6228 v2i64, v2f64, OpNode>; 6229 6230 let Predicates = [HasNEON, HasFullFP16] in { 6231 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6232 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6233 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6234 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6235 } 6236 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6237 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6238 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6239 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6240 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6241 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6242 let Predicates = [HasNEON, HasFullFP16] in { 6243 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6244 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6245 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6246 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6247 } 6248 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6249 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6250 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6251 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6252 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6253 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6254} 6255 6256let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6257class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6258 RegisterOperand outtype, RegisterOperand intype, 6259 string asm, string VdTy, string VnTy, 6260 list<dag> pattern> 6261 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6262 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6263 Sched<[WriteVq]> { 6264 bits<5> Rd; 6265 bits<5> Rn; 6266 let Inst{31} = 0; 6267 let Inst{30} = Q; 6268 let Inst{29} = U; 6269 let Inst{28-24} = 0b01110; 6270 let Inst{23-22} = size; 6271 let Inst{21-17} = 0b10000; 6272 let Inst{16-12} = opcode; 6273 let Inst{11-10} = 0b10; 6274 let Inst{9-5} = Rn; 6275 let Inst{4-0} = Rd; 6276} 6277 6278let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6279class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6280 RegisterOperand outtype, RegisterOperand intype, 6281 string asm, string VdTy, string VnTy, 6282 list<dag> pattern> 6283 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6284 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6285 Sched<[WriteVq]> { 6286 bits<5> Rd; 6287 bits<5> Rn; 6288 let Inst{31} = 0; 6289 let Inst{30} = Q; 6290 let Inst{29} = U; 6291 let Inst{28-24} = 0b01110; 6292 let Inst{23-22} = size; 6293 let Inst{21-17} = 0b10000; 6294 let Inst{16-12} = opcode; 6295 let Inst{11-10} = 0b10; 6296 let Inst{9-5} = Rn; 6297 let Inst{4-0} = Rd; 6298} 6299 6300multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6301 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6302 asm, ".4s", ".4h", []>; 6303 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6304 asm#"2", ".4s", ".8h", []>; 6305 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6306 asm, ".2d", ".2s", []>; 6307 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6308 asm#"2", ".2d", ".4s", []>; 6309} 6310 6311multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6312 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6313 asm, ".4h", ".4s", []>; 6314 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6315 asm#"2", ".8h", ".4s", []>; 6316 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6317 asm, ".2s", ".2d", []>; 6318 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6319 asm#"2", ".4s", ".2d", []>; 6320} 6321 6322multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6323 Intrinsic OpNode> { 6324 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6325 asm, ".2s", ".2d", 6326 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6327 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6328 asm#"2", ".4s", ".2d", []>; 6329 6330 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6331 (!cast<Instruction>(NAME # "v4f32") 6332 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6333} 6334 6335//---------------------------------------------------------------------------- 6336// AdvSIMD three register different-size vector instructions. 6337//---------------------------------------------------------------------------- 6338 6339let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6340class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6341 RegisterOperand outtype, RegisterOperand intype1, 6342 RegisterOperand intype2, string asm, 6343 string outkind, string inkind1, string inkind2, 6344 list<dag> pattern> 6345 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6346 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6347 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6348 Sched<[WriteVq]> { 6349 bits<5> Rd; 6350 bits<5> Rn; 6351 bits<5> Rm; 6352 let Inst{31} = 0; 6353 let Inst{30} = size{0}; 6354 let Inst{29} = U; 6355 let Inst{28-24} = 0b01110; 6356 let Inst{23-22} = size{2-1}; 6357 let Inst{21} = 1; 6358 let Inst{20-16} = Rm; 6359 let Inst{15-12} = opcode; 6360 let Inst{11-10} = 0b00; 6361 let Inst{9-5} = Rn; 6362 let Inst{4-0} = Rd; 6363} 6364 6365let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6366class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6367 RegisterOperand outtype, RegisterOperand intype1, 6368 RegisterOperand intype2, string asm, 6369 string outkind, string inkind1, string inkind2, 6370 list<dag> pattern> 6371 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6372 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6373 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6374 Sched<[WriteVq]> { 6375 bits<5> Rd; 6376 bits<5> Rn; 6377 bits<5> Rm; 6378 let Inst{31} = 0; 6379 let Inst{30} = size{0}; 6380 let Inst{29} = U; 6381 let Inst{28-24} = 0b01110; 6382 let Inst{23-22} = size{2-1}; 6383 let Inst{21} = 1; 6384 let Inst{20-16} = Rm; 6385 let Inst{15-12} = opcode; 6386 let Inst{11-10} = 0b00; 6387 let Inst{9-5} = Rn; 6388 let Inst{4-0} = Rd; 6389} 6390 6391// FIXME: TableGen doesn't know how to deal with expanded types that also 6392// change the element count (in this case, placing the results in 6393// the high elements of the result register rather than the low 6394// elements). Until that's fixed, we can't code-gen those. 6395multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6396 Intrinsic IntOp> { 6397 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6398 V64, V128, V128, 6399 asm, ".8b", ".8h", ".8h", 6400 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6401 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6402 V128, V128, V128, 6403 asm#"2", ".16b", ".8h", ".8h", 6404 []>; 6405 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6406 V64, V128, V128, 6407 asm, ".4h", ".4s", ".4s", 6408 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6409 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6410 V128, V128, V128, 6411 asm#"2", ".8h", ".4s", ".4s", 6412 []>; 6413 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6414 V64, V128, V128, 6415 asm, ".2s", ".2d", ".2d", 6416 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6417 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6418 V128, V128, V128, 6419 asm#"2", ".4s", ".2d", ".2d", 6420 []>; 6421 6422 6423 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6424 // a version attached to an instruction. 6425 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6426 (v8i16 V128:$Rm))), 6427 (!cast<Instruction>(NAME # "v8i16_v16i8") 6428 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6429 V128:$Rn, V128:$Rm)>; 6430 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6431 (v4i32 V128:$Rm))), 6432 (!cast<Instruction>(NAME # "v4i32_v8i16") 6433 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6434 V128:$Rn, V128:$Rm)>; 6435 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6436 (v2i64 V128:$Rm))), 6437 (!cast<Instruction>(NAME # "v2i64_v4i32") 6438 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6439 V128:$Rn, V128:$Rm)>; 6440} 6441 6442multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6443 Intrinsic IntOp> { 6444 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6445 V128, V64, V64, 6446 asm, ".8h", ".8b", ".8b", 6447 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6448 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6449 V128, V128, V128, 6450 asm#"2", ".8h", ".16b", ".16b", []>; 6451 let Predicates = [HasAES] in { 6452 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6453 V128, V64, V64, 6454 asm, ".1q", ".1d", ".1d", []>; 6455 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6456 V128, V128, V128, 6457 asm#"2", ".1q", ".2d", ".2d", []>; 6458 } 6459 6460 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6461 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6462 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6463} 6464 6465multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6466 SDPatternOperator OpNode> { 6467 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6468 V128, V64, V64, 6469 asm, ".4s", ".4h", ".4h", 6470 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6471 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6472 V128, V128, V128, 6473 asm#"2", ".4s", ".8h", ".8h", 6474 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6475 (extract_high_v8i16 V128:$Rm)))]>; 6476 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6477 V128, V64, V64, 6478 asm, ".2d", ".2s", ".2s", 6479 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6480 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6481 V128, V128, V128, 6482 asm#"2", ".2d", ".4s", ".4s", 6483 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6484 (extract_high_v4i32 V128:$Rm)))]>; 6485} 6486 6487multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6488 SDPatternOperator OpNode = null_frag> { 6489 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6490 V128, V64, V64, 6491 asm, ".8h", ".8b", ".8b", 6492 [(set (v8i16 V128:$Rd), 6493 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6494 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6495 V128, V128, V128, 6496 asm#"2", ".8h", ".16b", ".16b", 6497 [(set (v8i16 V128:$Rd), 6498 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6499 (extract_high_v16i8 V128:$Rm)))))]>; 6500 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6501 V128, V64, V64, 6502 asm, ".4s", ".4h", ".4h", 6503 [(set (v4i32 V128:$Rd), 6504 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6505 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6506 V128, V128, V128, 6507 asm#"2", ".4s", ".8h", ".8h", 6508 [(set (v4i32 V128:$Rd), 6509 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6510 (extract_high_v8i16 V128:$Rm)))))]>; 6511 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6512 V128, V64, V64, 6513 asm, ".2d", ".2s", ".2s", 6514 [(set (v2i64 V128:$Rd), 6515 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6516 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6517 V128, V128, V128, 6518 asm#"2", ".2d", ".4s", ".4s", 6519 [(set (v2i64 V128:$Rd), 6520 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6521 (extract_high_v4i32 V128:$Rm)))))]>; 6522} 6523 6524multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6525 string asm, 6526 SDPatternOperator OpNode> { 6527 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6528 V128, V64, V64, 6529 asm, ".8h", ".8b", ".8b", 6530 [(set (v8i16 V128:$dst), 6531 (add (v8i16 V128:$Rd), 6532 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6533 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6534 V128, V128, V128, 6535 asm#"2", ".8h", ".16b", ".16b", 6536 [(set (v8i16 V128:$dst), 6537 (add (v8i16 V128:$Rd), 6538 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6539 (extract_high_v16i8 V128:$Rm))))))]>; 6540 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6541 V128, V64, V64, 6542 asm, ".4s", ".4h", ".4h", 6543 [(set (v4i32 V128:$dst), 6544 (add (v4i32 V128:$Rd), 6545 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6546 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6547 V128, V128, V128, 6548 asm#"2", ".4s", ".8h", ".8h", 6549 [(set (v4i32 V128:$dst), 6550 (add (v4i32 V128:$Rd), 6551 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6552 (extract_high_v8i16 V128:$Rm))))))]>; 6553 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6554 V128, V64, V64, 6555 asm, ".2d", ".2s", ".2s", 6556 [(set (v2i64 V128:$dst), 6557 (add (v2i64 V128:$Rd), 6558 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6559 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6560 V128, V128, V128, 6561 asm#"2", ".2d", ".4s", ".4s", 6562 [(set (v2i64 V128:$dst), 6563 (add (v2i64 V128:$Rd), 6564 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6565 (extract_high_v4i32 V128:$Rm))))))]>; 6566} 6567 6568multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6569 SDPatternOperator OpNode = null_frag> { 6570 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6571 V128, V64, V64, 6572 asm, ".8h", ".8b", ".8b", 6573 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6574 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6575 V128, V128, V128, 6576 asm#"2", ".8h", ".16b", ".16b", 6577 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6578 (extract_high_v16i8 V128:$Rm)))]>; 6579 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6580 V128, V64, V64, 6581 asm, ".4s", ".4h", ".4h", 6582 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6583 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6584 V128, V128, V128, 6585 asm#"2", ".4s", ".8h", ".8h", 6586 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6587 (extract_high_v8i16 V128:$Rm)))]>; 6588 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6589 V128, V64, V64, 6590 asm, ".2d", ".2s", ".2s", 6591 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6592 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6593 V128, V128, V128, 6594 asm#"2", ".2d", ".4s", ".4s", 6595 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6596 (extract_high_v4i32 V128:$Rm)))]>; 6597} 6598 6599multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6600 string asm, 6601 SDPatternOperator OpNode> { 6602 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6603 V128, V64, V64, 6604 asm, ".8h", ".8b", ".8b", 6605 [(set (v8i16 V128:$dst), 6606 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6607 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6608 V128, V128, V128, 6609 asm#"2", ".8h", ".16b", ".16b", 6610 [(set (v8i16 V128:$dst), 6611 (OpNode (v8i16 V128:$Rd), 6612 (extract_high_v16i8 V128:$Rn), 6613 (extract_high_v16i8 V128:$Rm)))]>; 6614 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6615 V128, V64, V64, 6616 asm, ".4s", ".4h", ".4h", 6617 [(set (v4i32 V128:$dst), 6618 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6619 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6620 V128, V128, V128, 6621 asm#"2", ".4s", ".8h", ".8h", 6622 [(set (v4i32 V128:$dst), 6623 (OpNode (v4i32 V128:$Rd), 6624 (extract_high_v8i16 V128:$Rn), 6625 (extract_high_v8i16 V128:$Rm)))]>; 6626 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6627 V128, V64, V64, 6628 asm, ".2d", ".2s", ".2s", 6629 [(set (v2i64 V128:$dst), 6630 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6631 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6632 V128, V128, V128, 6633 asm#"2", ".2d", ".4s", ".4s", 6634 [(set (v2i64 V128:$dst), 6635 (OpNode (v2i64 V128:$Rd), 6636 (extract_high_v4i32 V128:$Rn), 6637 (extract_high_v4i32 V128:$Rm)))]>; 6638} 6639 6640multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6641 SDPatternOperator Accum> { 6642 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6643 V128, V64, V64, 6644 asm, ".4s", ".4h", ".4h", 6645 [(set (v4i32 V128:$dst), 6646 (Accum (v4i32 V128:$Rd), 6647 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6648 (v4i16 V64:$Rm)))))]>; 6649 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6650 V128, V128, V128, 6651 asm#"2", ".4s", ".8h", ".8h", 6652 [(set (v4i32 V128:$dst), 6653 (Accum (v4i32 V128:$Rd), 6654 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6655 (extract_high_v8i16 V128:$Rm)))))]>; 6656 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6657 V128, V64, V64, 6658 asm, ".2d", ".2s", ".2s", 6659 [(set (v2i64 V128:$dst), 6660 (Accum (v2i64 V128:$Rd), 6661 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6662 (v2i32 V64:$Rm)))))]>; 6663 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6664 V128, V128, V128, 6665 asm#"2", ".2d", ".4s", ".4s", 6666 [(set (v2i64 V128:$dst), 6667 (Accum (v2i64 V128:$Rd), 6668 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6669 (extract_high_v4i32 V128:$Rm)))))]>; 6670} 6671 6672multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6673 SDPatternOperator OpNode> { 6674 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6675 V128, V128, V64, 6676 asm, ".8h", ".8h", ".8b", 6677 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6678 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6679 V128, V128, V128, 6680 asm#"2", ".8h", ".8h", ".16b", 6681 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6682 (extract_high_v16i8 V128:$Rm)))]>; 6683 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6684 V128, V128, V64, 6685 asm, ".4s", ".4s", ".4h", 6686 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6687 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6688 V128, V128, V128, 6689 asm#"2", ".4s", ".4s", ".8h", 6690 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6691 (extract_high_v8i16 V128:$Rm)))]>; 6692 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6693 V128, V128, V64, 6694 asm, ".2d", ".2d", ".2s", 6695 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6696 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6697 V128, V128, V128, 6698 asm#"2", ".2d", ".2d", ".4s", 6699 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6700 (extract_high_v4i32 V128:$Rm)))]>; 6701} 6702 6703//---------------------------------------------------------------------------- 6704// AdvSIMD bitwise extract from vector 6705//---------------------------------------------------------------------------- 6706 6707class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6708 string asm, string kind> 6709 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6710 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6711 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6712 [(set (vty regtype:$Rd), 6713 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6714 Sched<[!if(size, WriteVq, WriteVd)]> { 6715 bits<5> Rd; 6716 bits<5> Rn; 6717 bits<5> Rm; 6718 bits<4> imm; 6719 let Inst{31} = 0; 6720 let Inst{30} = size; 6721 let Inst{29-21} = 0b101110000; 6722 let Inst{20-16} = Rm; 6723 let Inst{15} = 0; 6724 let Inst{14-11} = imm; 6725 let Inst{10} = 0; 6726 let Inst{9-5} = Rn; 6727 let Inst{4-0} = Rd; 6728} 6729 6730 6731multiclass SIMDBitwiseExtract<string asm> { 6732 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6733 let imm{3} = 0; 6734 } 6735 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6736} 6737 6738//---------------------------------------------------------------------------- 6739// AdvSIMD zip vector 6740//---------------------------------------------------------------------------- 6741 6742class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6743 string asm, string kind, SDNode OpNode, ValueType valty> 6744 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6745 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6746 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6747 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6748 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 6749 bits<5> Rd; 6750 bits<5> Rn; 6751 bits<5> Rm; 6752 let Inst{31} = 0; 6753 let Inst{30} = size{0}; 6754 let Inst{29-24} = 0b001110; 6755 let Inst{23-22} = size{2-1}; 6756 let Inst{21} = 0; 6757 let Inst{20-16} = Rm; 6758 let Inst{15} = 0; 6759 let Inst{14-12} = opc; 6760 let Inst{11-10} = 0b10; 6761 let Inst{9-5} = Rn; 6762 let Inst{4-0} = Rd; 6763} 6764 6765multiclass SIMDZipVector<bits<3>opc, string asm, 6766 SDNode OpNode> { 6767 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6768 asm, ".8b", OpNode, v8i8>; 6769 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6770 asm, ".16b", OpNode, v16i8>; 6771 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6772 asm, ".4h", OpNode, v4i16>; 6773 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6774 asm, ".8h", OpNode, v8i16>; 6775 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6776 asm, ".2s", OpNode, v2i32>; 6777 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6778 asm, ".4s", OpNode, v4i32>; 6779 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6780 asm, ".2d", OpNode, v2i64>; 6781 6782 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6783 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6784 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6785 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6786 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6787 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6788 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6789 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6790 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6791 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6792} 6793 6794//---------------------------------------------------------------------------- 6795// AdvSIMD three register scalar instructions 6796//---------------------------------------------------------------------------- 6797 6798let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6799class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6800 RegisterClass regtype, string asm, 6801 list<dag> pattern> 6802 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6803 "\t$Rd, $Rn, $Rm", "", pattern>, 6804 Sched<[WriteVd]> { 6805 bits<5> Rd; 6806 bits<5> Rn; 6807 bits<5> Rm; 6808 let Inst{31-30} = 0b01; 6809 let Inst{29} = U; 6810 let Inst{28-24} = 0b11110; 6811 let Inst{23-21} = size; 6812 let Inst{20-16} = Rm; 6813 let Inst{15-11} = opcode; 6814 let Inst{10} = 1; 6815 let Inst{9-5} = Rn; 6816 let Inst{4-0} = Rd; 6817} 6818 6819let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6820class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6821 dag oops, dag iops, string asm, 6822 list<dag> pattern> 6823 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6824 Sched<[WriteVd]> { 6825 bits<5> Rd; 6826 bits<5> Rn; 6827 bits<5> Rm; 6828 let Inst{31-30} = 0b01; 6829 let Inst{29} = U; 6830 let Inst{28-24} = 0b11110; 6831 let Inst{23-22} = size; 6832 let Inst{21} = R; 6833 let Inst{20-16} = Rm; 6834 let Inst{15-11} = opcode; 6835 let Inst{10} = 1; 6836 let Inst{9-5} = Rn; 6837 let Inst{4-0} = Rd; 6838} 6839 6840multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6841 SDPatternOperator OpNode> { 6842 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6843 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6844} 6845 6846multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6847 SDPatternOperator OpNode> { 6848 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6849 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6850 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6851 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6852 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6853 6854 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6855 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6856 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6857 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6858} 6859 6860multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6861 SDPatternOperator OpNode> { 6862 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6863 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6864 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6865} 6866 6867multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 6868 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6869 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6870 asm, []>; 6871 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6872 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6873 asm, []>; 6874} 6875 6876multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6877 SDPatternOperator OpNode = null_frag, 6878 Predicate pred = HasNEON> { 6879 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6880 let Predicates = [pred] in { 6881 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6882 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6883 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6884 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6885 } 6886 let Predicates = [pred, HasFullFP16] in { 6887 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6888 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6889 } 6890 } 6891 6892 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6893 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6894} 6895 6896multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6897 SDPatternOperator OpNode = null_frag> { 6898 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6899 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6900 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6901 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6902 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6903 let Predicates = [HasNEON, HasFullFP16] in { 6904 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6905 []>; 6906 } // Predicates = [HasNEON, HasFullFP16] 6907 } 6908 6909 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6910 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6911} 6912 6913class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6914 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6915 : I<oops, iops, asm, 6916 "\t$Rd, $Rn, $Rm", cstr, pat>, 6917 Sched<[WriteVd]> { 6918 bits<5> Rd; 6919 bits<5> Rn; 6920 bits<5> Rm; 6921 let Inst{31-30} = 0b01; 6922 let Inst{29} = U; 6923 let Inst{28-24} = 0b11110; 6924 let Inst{23-22} = size; 6925 let Inst{21} = 1; 6926 let Inst{20-16} = Rm; 6927 let Inst{15-11} = opcode; 6928 let Inst{10} = 0; 6929 let Inst{9-5} = Rn; 6930 let Inst{4-0} = Rd; 6931} 6932 6933let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6934multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6935 SDPatternOperator OpNode = null_frag> { 6936 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6937 (outs FPR32:$Rd), 6938 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6939 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6940 (outs FPR64:$Rd), 6941 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6942 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6943} 6944 6945let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6946multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6947 SDPatternOperator OpNode = null_frag> { 6948 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6949 (outs FPR32:$dst), 6950 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6951 asm, "$Rd = $dst", []>; 6952 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6953 (outs FPR64:$dst), 6954 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6955 asm, "$Rd = $dst", 6956 [(set (i64 FPR64:$dst), 6957 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6958} 6959 6960//---------------------------------------------------------------------------- 6961// AdvSIMD two register scalar instructions 6962//---------------------------------------------------------------------------- 6963 6964let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6965class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6966 RegisterClass regtype, RegisterClass regtype2, 6967 string asm, list<dag> pat> 6968 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6969 "\t$Rd, $Rn", "", pat>, 6970 Sched<[WriteVd]> { 6971 bits<5> Rd; 6972 bits<5> Rn; 6973 let Inst{31-30} = 0b01; 6974 let Inst{29} = U; 6975 let Inst{28-24} = 0b11110; 6976 let Inst{23-22} = size; 6977 let Inst{21} = 0b1; 6978 let Inst{20-19} = size2; 6979 let Inst{18-17} = 0b00; 6980 let Inst{16-12} = opcode; 6981 let Inst{11-10} = 0b10; 6982 let Inst{9-5} = Rn; 6983 let Inst{4-0} = Rd; 6984} 6985 6986let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6987class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6988 RegisterClass regtype, RegisterClass regtype2, 6989 string asm, list<dag> pat> 6990 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6991 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6992 Sched<[WriteVd]> { 6993 bits<5> Rd; 6994 bits<5> Rn; 6995 let Inst{31-30} = 0b01; 6996 let Inst{29} = U; 6997 let Inst{28-24} = 0b11110; 6998 let Inst{23-22} = size; 6999 let Inst{21-17} = 0b10000; 7000 let Inst{16-12} = opcode; 7001 let Inst{11-10} = 0b10; 7002 let Inst{9-5} = Rn; 7003 let Inst{4-0} = Rd; 7004} 7005 7006 7007let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7008class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7009 RegisterClass regtype, string asm, string zero> 7010 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7011 "\t$Rd, $Rn, #" # zero, "", []>, 7012 Sched<[WriteVd]> { 7013 bits<5> Rd; 7014 bits<5> Rn; 7015 let Inst{31-30} = 0b01; 7016 let Inst{29} = U; 7017 let Inst{28-24} = 0b11110; 7018 let Inst{23-22} = size; 7019 let Inst{21} = 0b1; 7020 let Inst{20-19} = size2; 7021 let Inst{18-17} = 0b00; 7022 let Inst{16-12} = opcode; 7023 let Inst{11-10} = 0b10; 7024 let Inst{9-5} = Rn; 7025 let Inst{4-0} = Rd; 7026} 7027 7028class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7029 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7030 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7031 Sched<[WriteVd]> { 7032 bits<5> Rd; 7033 bits<5> Rn; 7034 let Inst{31-17} = 0b011111100110000; 7035 let Inst{16-12} = opcode; 7036 let Inst{11-10} = 0b10; 7037 let Inst{9-5} = Rn; 7038 let Inst{4-0} = Rd; 7039} 7040 7041multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7042 SDPatternOperator OpNode> { 7043 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7044 7045 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7046 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7047} 7048 7049multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7050 SDPatternOperator OpNode> { 7051 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7052 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7053 let Predicates = [HasNEON, HasFullFP16] in { 7054 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7055 } 7056 7057 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7058 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7059 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7060 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7061 let Predicates = [HasNEON, HasFullFP16] in { 7062 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7063 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7064 } 7065 7066 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7067 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7068} 7069 7070multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7071 SDPatternOperator OpNode = null_frag> { 7072 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7073 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7074 7075 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7076 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7077} 7078 7079multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7080 Predicate pred = HasNEON> { 7081 let Predicates = [pred] in { 7082 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7083 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7084 } 7085 let Predicates = [pred, HasFullFP16] in { 7086 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7087 } 7088} 7089 7090multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7091 SDPatternOperator OpNode> { 7092 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7093 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7094 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7095 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7096 let Predicates = [HasNEON, HasFullFP16] in { 7097 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7098 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7099 } 7100} 7101 7102multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7103 SDPatternOperator OpNode = null_frag> { 7104 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7105 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7106 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7107 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7108 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7109 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7110 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7111 } 7112 7113 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7114 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7115} 7116 7117multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7118 Intrinsic OpNode> { 7119 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7120 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7121 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7122 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7123 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7124 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7125 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7126 } 7127 7128 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7129 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7130} 7131 7132 7133 7134let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7135multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7136 SDPatternOperator OpNode = null_frag> { 7137 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7138 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7139 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7140 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7141} 7142 7143//---------------------------------------------------------------------------- 7144// AdvSIMD scalar pairwise instructions 7145//---------------------------------------------------------------------------- 7146 7147let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7148class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7149 RegisterOperand regtype, RegisterOperand vectype, 7150 string asm, string kind> 7151 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7152 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7153 Sched<[WriteVd]> { 7154 bits<5> Rd; 7155 bits<5> Rn; 7156 let Inst{31-30} = 0b01; 7157 let Inst{29} = U; 7158 let Inst{28-24} = 0b11110; 7159 let Inst{23-22} = size; 7160 let Inst{21-17} = 0b11000; 7161 let Inst{16-12} = opcode; 7162 let Inst{11-10} = 0b10; 7163 let Inst{9-5} = Rn; 7164 let Inst{4-0} = Rd; 7165} 7166 7167multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7168 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7169 asm, ".2d">; 7170} 7171 7172multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7173 let Predicates = [HasNEON, HasFullFP16] in { 7174 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7175 asm, ".2h">; 7176 } 7177 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7178 asm, ".2s">; 7179 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7180 asm, ".2d">; 7181} 7182 7183//---------------------------------------------------------------------------- 7184// AdvSIMD across lanes instructions 7185//---------------------------------------------------------------------------- 7186 7187let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7188class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7189 RegisterClass regtype, RegisterOperand vectype, 7190 string asm, string kind, list<dag> pattern> 7191 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7192 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7193 Sched<[!if(Q, WriteVq, WriteVd)]> { 7194 bits<5> Rd; 7195 bits<5> Rn; 7196 let Inst{31} = 0; 7197 let Inst{30} = Q; 7198 let Inst{29} = U; 7199 let Inst{28-24} = 0b01110; 7200 let Inst{23-22} = size; 7201 let Inst{21-17} = 0b11000; 7202 let Inst{16-12} = opcode; 7203 let Inst{11-10} = 0b10; 7204 let Inst{9-5} = Rn; 7205 let Inst{4-0} = Rd; 7206} 7207 7208multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7209 string asm> { 7210 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7211 asm, ".8b", []>; 7212 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7213 asm, ".16b", []>; 7214 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7215 asm, ".4h", []>; 7216 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7217 asm, ".8h", []>; 7218 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7219 asm, ".4s", []>; 7220} 7221 7222multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7223 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7224 asm, ".8b", []>; 7225 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7226 asm, ".16b", []>; 7227 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7228 asm, ".4h", []>; 7229 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7230 asm, ".8h", []>; 7231 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7232 asm, ".4s", []>; 7233} 7234 7235multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7236 Intrinsic intOp> { 7237 let Predicates = [HasNEON, HasFullFP16] in { 7238 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7239 asm, ".4h", 7240 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7241 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7242 asm, ".8h", 7243 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7244 } // Predicates = [HasNEON, HasFullFP16] 7245 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7246 asm, ".4s", 7247 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7248} 7249 7250//---------------------------------------------------------------------------- 7251// AdvSIMD INS/DUP instructions 7252//---------------------------------------------------------------------------- 7253 7254// FIXME: There has got to be a better way to factor these. ugh. 7255 7256class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7257 string operands, string constraints, list<dag> pattern> 7258 : I<outs, ins, asm, operands, constraints, pattern>, 7259 Sched<[!if(Q, WriteVq, WriteVd)]> { 7260 bits<5> Rd; 7261 bits<5> Rn; 7262 let Inst{31} = 0; 7263 let Inst{30} = Q; 7264 let Inst{29} = op; 7265 let Inst{28-21} = 0b01110000; 7266 let Inst{15} = 0; 7267 let Inst{10} = 1; 7268 let Inst{9-5} = Rn; 7269 let Inst{4-0} = Rd; 7270} 7271 7272class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7273 RegisterOperand vecreg, RegisterClass regtype> 7274 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7275 "{\t$Rd" # size # ", $Rn" # 7276 "|" # size # "\t$Rd, $Rn}", "", 7277 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7278 let Inst{20-16} = imm5; 7279 let Inst{14-11} = 0b0001; 7280} 7281 7282class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7283 ValueType vectype, ValueType insreg, 7284 RegisterOperand vecreg, Operand idxtype, 7285 SDNode OpNode> 7286 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7287 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7288 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7289 [(set (vectype vecreg:$Rd), 7290 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7291 let Inst{14-11} = 0b0000; 7292} 7293 7294class SIMDDup64FromElement 7295 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7296 VectorIndexD, AArch64duplane64> { 7297 bits<1> idx; 7298 let Inst{20} = idx; 7299 let Inst{19-16} = 0b1000; 7300} 7301 7302class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7303 RegisterOperand vecreg> 7304 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7305 VectorIndexS, AArch64duplane32> { 7306 bits<2> idx; 7307 let Inst{20-19} = idx; 7308 let Inst{18-16} = 0b100; 7309} 7310 7311class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7312 RegisterOperand vecreg> 7313 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7314 VectorIndexH, AArch64duplane16> { 7315 bits<3> idx; 7316 let Inst{20-18} = idx; 7317 let Inst{17-16} = 0b10; 7318} 7319 7320class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7321 RegisterOperand vecreg> 7322 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7323 VectorIndexB, AArch64duplane8> { 7324 bits<4> idx; 7325 let Inst{20-17} = idx; 7326 let Inst{16} = 1; 7327} 7328 7329class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7330 Operand idxtype, string asm, list<dag> pattern> 7331 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7332 "{\t$Rd, $Rn" # size # "$idx" # 7333 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7334 let Inst{14-11} = imm4; 7335} 7336 7337class SIMDSMov<bit Q, string size, RegisterClass regtype, 7338 Operand idxtype> 7339 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7340class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7341 Operand idxtype> 7342 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7343 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7344 7345class SIMDMovAlias<string asm, string size, Instruction inst, 7346 RegisterClass regtype, Operand idxtype> 7347 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7348 "|" # size # "\t$dst, $src$idx}", 7349 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7350 7351multiclass SMov { 7352 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7353 // streaming mode. 7354 let Predicates = [HasNEONorStreamingSVE] in { 7355 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7356 let Inst{20-16} = 0b00001; 7357 } 7358 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7359 let Inst{20-16} = 0b00001; 7360 } 7361 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7362 let Inst{20-16} = 0b00010; 7363 } 7364 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7365 let Inst{20-16} = 0b00010; 7366 } 7367 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7368 let Inst{20-16} = 0b00100; 7369 } 7370 } 7371 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7372 bits<4> idx; 7373 let Inst{20-17} = idx; 7374 let Inst{16} = 1; 7375 } 7376 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7377 bits<4> idx; 7378 let Inst{20-17} = idx; 7379 let Inst{16} = 1; 7380 } 7381 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7382 bits<3> idx; 7383 let Inst{20-18} = idx; 7384 let Inst{17-16} = 0b10; 7385 } 7386 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7387 bits<3> idx; 7388 let Inst{20-18} = idx; 7389 let Inst{17-16} = 0b10; 7390 } 7391 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7392 bits<2> idx; 7393 let Inst{20-19} = idx; 7394 let Inst{18-16} = 0b100; 7395 } 7396} 7397 7398multiclass UMov { 7399 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7400 // streaming mode. 7401 let Predicates = [HasNEONorStreamingSVE] in { 7402 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7403 let Inst{20-16} = 0b00001; 7404 } 7405 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7406 let Inst{20-16} = 0b00010; 7407 } 7408 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7409 let Inst{20-16} = 0b00100; 7410 } 7411 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7412 let Inst{20-16} = 0b01000; 7413 } 7414 def : SIMDMovAlias<"mov", ".s", 7415 !cast<Instruction>(NAME # vi32_idx0), 7416 GPR32, VectorIndex0>; 7417 def : SIMDMovAlias<"mov", ".d", 7418 !cast<Instruction>(NAME # vi64_idx0), 7419 GPR64, VectorIndex0>; 7420 } 7421 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7422 bits<4> idx; 7423 let Inst{20-17} = idx; 7424 let Inst{16} = 1; 7425 } 7426 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7427 bits<3> idx; 7428 let Inst{20-18} = idx; 7429 let Inst{17-16} = 0b10; 7430 } 7431 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7432 bits<2> idx; 7433 let Inst{20-19} = idx; 7434 let Inst{18-16} = 0b100; 7435 } 7436 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7437 bits<1> idx; 7438 let Inst{20} = idx; 7439 let Inst{19-16} = 0b1000; 7440 } 7441 def : SIMDMovAlias<"mov", ".s", 7442 !cast<Instruction>(NAME#"vi32"), 7443 GPR32, VectorIndexS>; 7444 def : SIMDMovAlias<"mov", ".d", 7445 !cast<Instruction>(NAME#"vi64"), 7446 GPR64, VectorIndexD>; 7447} 7448 7449class SIMDInsFromMain<string size, ValueType vectype, 7450 RegisterClass regtype, Operand idxtype> 7451 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7452 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7453 "{\t$Rd" # size # "$idx, $Rn" # 7454 "|" # size # "\t$Rd$idx, $Rn}", 7455 "$Rd = $dst", 7456 [(set V128:$dst, 7457 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7458 let Inst{14-11} = 0b0011; 7459} 7460 7461class SIMDInsFromElement<string size, ValueType vectype, 7462 ValueType elttype, Operand idxtype> 7463 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7464 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7465 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7466 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7467 "$Rd = $dst", 7468 [(set V128:$dst, 7469 (vector_insert 7470 (vectype V128:$Rd), 7471 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7472 idxtype:$idx))]>; 7473 7474class SIMDInsMainMovAlias<string size, Instruction inst, 7475 RegisterClass regtype, Operand idxtype> 7476 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7477 "|" # size #"\t$dst$idx, $src}", 7478 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7479class SIMDInsElementMovAlias<string size, Instruction inst, 7480 Operand idxtype> 7481 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7482 # "|" # size #"\t$dst$idx, $src$idx2}", 7483 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7484 7485 7486multiclass SIMDIns { 7487 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7488 bits<4> idx; 7489 let Inst{20-17} = idx; 7490 let Inst{16} = 1; 7491 } 7492 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7493 bits<3> idx; 7494 let Inst{20-18} = idx; 7495 let Inst{17-16} = 0b10; 7496 } 7497 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7498 bits<2> idx; 7499 let Inst{20-19} = idx; 7500 let Inst{18-16} = 0b100; 7501 } 7502 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7503 bits<1> idx; 7504 let Inst{20} = idx; 7505 let Inst{19-16} = 0b1000; 7506 } 7507 7508 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7509 bits<4> idx; 7510 bits<4> idx2; 7511 let Inst{20-17} = idx; 7512 let Inst{16} = 1; 7513 let Inst{14-11} = idx2; 7514 } 7515 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7516 bits<3> idx; 7517 bits<3> idx2; 7518 let Inst{20-18} = idx; 7519 let Inst{17-16} = 0b10; 7520 let Inst{14-12} = idx2; 7521 let Inst{11} = {?}; 7522 } 7523 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7524 bits<2> idx; 7525 bits<2> idx2; 7526 let Inst{20-19} = idx; 7527 let Inst{18-16} = 0b100; 7528 let Inst{14-13} = idx2; 7529 let Inst{12-11} = {?,?}; 7530 } 7531 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7532 bits<1> idx; 7533 bits<1> idx2; 7534 let Inst{20} = idx; 7535 let Inst{19-16} = 0b1000; 7536 let Inst{14} = idx2; 7537 let Inst{13-11} = {?,?,?}; 7538 } 7539 7540 // For all forms of the INS instruction, the "mov" mnemonic is the 7541 // preferred alias. Why they didn't just call the instruction "mov" in 7542 // the first place is a very good question indeed... 7543 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7544 GPR32, VectorIndexB>; 7545 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7546 GPR32, VectorIndexH>; 7547 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7548 GPR32, VectorIndexS>; 7549 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7550 GPR64, VectorIndexD>; 7551 7552 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7553 VectorIndexB>; 7554 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7555 VectorIndexH>; 7556 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7557 VectorIndexS>; 7558 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7559 VectorIndexD>; 7560} 7561 7562//---------------------------------------------------------------------------- 7563// AdvSIMD TBL/TBX 7564//---------------------------------------------------------------------------- 7565 7566let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7567class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7568 RegisterOperand listtype, string asm, string kind> 7569 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7570 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7571 Sched<[!if(Q, WriteVq, WriteVd)]> { 7572 bits<5> Vd; 7573 bits<5> Vn; 7574 bits<5> Vm; 7575 let Inst{31} = 0; 7576 let Inst{30} = Q; 7577 let Inst{29-21} = 0b001110000; 7578 let Inst{20-16} = Vm; 7579 let Inst{15} = 0; 7580 let Inst{14-13} = len; 7581 let Inst{12} = op; 7582 let Inst{11-10} = 0b00; 7583 let Inst{9-5} = Vn; 7584 let Inst{4-0} = Vd; 7585} 7586 7587let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7588class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7589 RegisterOperand listtype, string asm, string kind> 7590 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7591 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7592 Sched<[!if(Q, WriteVq, WriteVd)]> { 7593 bits<5> Vd; 7594 bits<5> Vn; 7595 bits<5> Vm; 7596 let Inst{31} = 0; 7597 let Inst{30} = Q; 7598 let Inst{29-21} = 0b001110000; 7599 let Inst{20-16} = Vm; 7600 let Inst{15} = 0; 7601 let Inst{14-13} = len; 7602 let Inst{12} = op; 7603 let Inst{11-10} = 0b00; 7604 let Inst{9-5} = Vn; 7605 let Inst{4-0} = Vd; 7606} 7607 7608class SIMDTableLookupAlias<string asm, Instruction inst, 7609 RegisterOperand vectype, RegisterOperand listtype> 7610 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7611 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7612 7613multiclass SIMDTableLookup<bit op, string asm> { 7614 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7615 asm, ".8b">; 7616 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7617 asm, ".8b">; 7618 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7619 asm, ".8b">; 7620 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7621 asm, ".8b">; 7622 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7623 asm, ".16b">; 7624 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7625 asm, ".16b">; 7626 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7627 asm, ".16b">; 7628 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7629 asm, ".16b">; 7630 7631 def : SIMDTableLookupAlias<asm # ".8b", 7632 !cast<Instruction>(NAME#"v8i8One"), 7633 V64, VecListOne128>; 7634 def : SIMDTableLookupAlias<asm # ".8b", 7635 !cast<Instruction>(NAME#"v8i8Two"), 7636 V64, VecListTwo128>; 7637 def : SIMDTableLookupAlias<asm # ".8b", 7638 !cast<Instruction>(NAME#"v8i8Three"), 7639 V64, VecListThree128>; 7640 def : SIMDTableLookupAlias<asm # ".8b", 7641 !cast<Instruction>(NAME#"v8i8Four"), 7642 V64, VecListFour128>; 7643 def : SIMDTableLookupAlias<asm # ".16b", 7644 !cast<Instruction>(NAME#"v16i8One"), 7645 V128, VecListOne128>; 7646 def : SIMDTableLookupAlias<asm # ".16b", 7647 !cast<Instruction>(NAME#"v16i8Two"), 7648 V128, VecListTwo128>; 7649 def : SIMDTableLookupAlias<asm # ".16b", 7650 !cast<Instruction>(NAME#"v16i8Three"), 7651 V128, VecListThree128>; 7652 def : SIMDTableLookupAlias<asm # ".16b", 7653 !cast<Instruction>(NAME#"v16i8Four"), 7654 V128, VecListFour128>; 7655} 7656 7657multiclass SIMDTableLookupTied<bit op, string asm> { 7658 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7659 asm, ".8b">; 7660 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7661 asm, ".8b">; 7662 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7663 asm, ".8b">; 7664 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7665 asm, ".8b">; 7666 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7667 asm, ".16b">; 7668 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7669 asm, ".16b">; 7670 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7671 asm, ".16b">; 7672 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7673 asm, ".16b">; 7674 7675 def : SIMDTableLookupAlias<asm # ".8b", 7676 !cast<Instruction>(NAME#"v8i8One"), 7677 V64, VecListOne128>; 7678 def : SIMDTableLookupAlias<asm # ".8b", 7679 !cast<Instruction>(NAME#"v8i8Two"), 7680 V64, VecListTwo128>; 7681 def : SIMDTableLookupAlias<asm # ".8b", 7682 !cast<Instruction>(NAME#"v8i8Three"), 7683 V64, VecListThree128>; 7684 def : SIMDTableLookupAlias<asm # ".8b", 7685 !cast<Instruction>(NAME#"v8i8Four"), 7686 V64, VecListFour128>; 7687 def : SIMDTableLookupAlias<asm # ".16b", 7688 !cast<Instruction>(NAME#"v16i8One"), 7689 V128, VecListOne128>; 7690 def : SIMDTableLookupAlias<asm # ".16b", 7691 !cast<Instruction>(NAME#"v16i8Two"), 7692 V128, VecListTwo128>; 7693 def : SIMDTableLookupAlias<asm # ".16b", 7694 !cast<Instruction>(NAME#"v16i8Three"), 7695 V128, VecListThree128>; 7696 def : SIMDTableLookupAlias<asm # ".16b", 7697 !cast<Instruction>(NAME#"v16i8Four"), 7698 V128, VecListFour128>; 7699} 7700 7701 7702//---------------------------------------------------------------------------- 7703// AdvSIMD scalar DUP 7704//---------------------------------------------------------------------------- 7705let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7706class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 7707 string asm, string kind, Operand idxtype> 7708 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 7709 "{\t$dst, $src" # kind # "$idx" # 7710 "|\t$dst, $src$idx}", "", []>, 7711 Sched<[WriteVd]> { 7712 bits<5> dst; 7713 bits<5> src; 7714 let Inst{31-21} = 0b01011110000; 7715 let Inst{15-10} = 0b000001; 7716 let Inst{9-5} = src; 7717 let Inst{4-0} = dst; 7718} 7719 7720class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 7721 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7722 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7723 # "|\t$dst, $src$index}", 7724 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7725 7726 7727multiclass SIMDScalarDUP<string asm> { 7728 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 7729 bits<4> idx; 7730 let Inst{20-17} = idx; 7731 let Inst{16} = 1; 7732 } 7733 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 7734 bits<3> idx; 7735 let Inst{20-18} = idx; 7736 let Inst{17-16} = 0b10; 7737 } 7738 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 7739 bits<2> idx; 7740 let Inst{20-19} = idx; 7741 let Inst{18-16} = 0b100; 7742 } 7743 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 7744 bits<1> idx; 7745 let Inst{20} = idx; 7746 let Inst{19-16} = 0b1000; 7747 } 7748 7749 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7750 VectorIndexD:$idx)))), 7751 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7752 7753 // 'DUP' mnemonic aliases. 7754 def : SIMDScalarDUPAlias<"dup", ".b", 7755 !cast<Instruction>(NAME#"i8"), 7756 FPR8, V128, VectorIndexB>; 7757 def : SIMDScalarDUPAlias<"dup", ".h", 7758 !cast<Instruction>(NAME#"i16"), 7759 FPR16, V128, VectorIndexH>; 7760 def : SIMDScalarDUPAlias<"dup", ".s", 7761 !cast<Instruction>(NAME#"i32"), 7762 FPR32, V128, VectorIndexS>; 7763 def : SIMDScalarDUPAlias<"dup", ".d", 7764 !cast<Instruction>(NAME#"i64"), 7765 FPR64, V128, VectorIndexD>; 7766} 7767 7768//---------------------------------------------------------------------------- 7769// AdvSIMD modified immediate instructions 7770//---------------------------------------------------------------------------- 7771 7772class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7773 string asm, string op_string, 7774 string cstr, list<dag> pattern> 7775 : I<oops, iops, asm, op_string, cstr, pattern>, 7776 Sched<[!if(Q, WriteVq, WriteVd)]> { 7777 bits<5> Rd; 7778 bits<8> imm8; 7779 let Inst{31} = 0; 7780 let Inst{30} = Q; 7781 let Inst{29} = op; 7782 let Inst{28-19} = 0b0111100000; 7783 let Inst{18-16} = imm8{7-5}; 7784 let Inst{11} = op2; 7785 let Inst{10} = 1; 7786 let Inst{9-5} = imm8{4-0}; 7787 let Inst{4-0} = Rd; 7788} 7789 7790class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7791 Operand immtype, dag opt_shift_iop, 7792 string opt_shift, string asm, string kind, 7793 list<dag> pattern> 7794 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7795 !con((ins immtype:$imm8), opt_shift_iop), asm, 7796 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7797 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7798 "", pattern> { 7799 let DecoderMethod = "DecodeModImmInstruction"; 7800} 7801 7802class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7803 Operand immtype, dag opt_shift_iop, 7804 string opt_shift, string asm, string kind, 7805 list<dag> pattern> 7806 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7807 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7808 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7809 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7810 "$Rd = $dst", pattern> { 7811 let DecoderMethod = "DecodeModImmTiedInstruction"; 7812} 7813 7814class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7815 RegisterOperand vectype, string asm, 7816 string kind, list<dag> pattern> 7817 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7818 (ins logical_vec_shift:$shift), 7819 "$shift", asm, kind, pattern> { 7820 bits<2> shift; 7821 let Inst{15} = b15_b12{1}; 7822 let Inst{14-13} = shift; 7823 let Inst{12} = b15_b12{0}; 7824} 7825 7826class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7827 RegisterOperand vectype, string asm, 7828 string kind, list<dag> pattern> 7829 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7830 (ins logical_vec_shift:$shift), 7831 "$shift", asm, kind, pattern> { 7832 bits<2> shift; 7833 let Inst{15} = b15_b12{1}; 7834 let Inst{14-13} = shift; 7835 let Inst{12} = b15_b12{0}; 7836} 7837 7838 7839class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7840 RegisterOperand vectype, string asm, 7841 string kind, list<dag> pattern> 7842 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7843 (ins logical_vec_hw_shift:$shift), 7844 "$shift", asm, kind, pattern> { 7845 bits<2> shift; 7846 let Inst{15} = b15_b12{1}; 7847 let Inst{14} = 0; 7848 let Inst{13} = shift{0}; 7849 let Inst{12} = b15_b12{0}; 7850} 7851 7852class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7853 RegisterOperand vectype, string asm, 7854 string kind, list<dag> pattern> 7855 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7856 (ins logical_vec_hw_shift:$shift), 7857 "$shift", asm, kind, pattern> { 7858 bits<2> shift; 7859 let Inst{15} = b15_b12{1}; 7860 let Inst{14} = 0; 7861 let Inst{13} = shift{0}; 7862 let Inst{12} = b15_b12{0}; 7863} 7864 7865multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7866 string asm> { 7867 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7868 asm, ".4h", []>; 7869 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7870 asm, ".8h", []>; 7871 7872 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7873 asm, ".2s", []>; 7874 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7875 asm, ".4s", []>; 7876} 7877 7878multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7879 bits<2> w_cmode, string asm, 7880 SDNode OpNode> { 7881 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7882 asm, ".4h", 7883 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7884 imm0_255:$imm8, 7885 (i32 imm:$shift)))]>; 7886 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7887 asm, ".8h", 7888 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7889 imm0_255:$imm8, 7890 (i32 imm:$shift)))]>; 7891 7892 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7893 asm, ".2s", 7894 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7895 imm0_255:$imm8, 7896 (i32 imm:$shift)))]>; 7897 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7898 asm, ".4s", 7899 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7900 imm0_255:$imm8, 7901 (i32 imm:$shift)))]>; 7902} 7903 7904class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7905 RegisterOperand vectype, string asm, 7906 string kind, list<dag> pattern> 7907 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7908 (ins move_vec_shift:$shift), 7909 "$shift", asm, kind, pattern> { 7910 bits<1> shift; 7911 let Inst{15-13} = cmode{3-1}; 7912 let Inst{12} = shift; 7913} 7914 7915class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7916 RegisterOperand vectype, 7917 Operand imm_type, string asm, 7918 string kind, list<dag> pattern> 7919 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7920 asm, kind, pattern> { 7921 let Inst{15-12} = cmode; 7922} 7923 7924class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7925 list<dag> pattern> 7926 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7927 "\t$Rd, $imm8", "", pattern> { 7928 let Inst{15-12} = cmode; 7929 let DecoderMethod = "DecodeModImmInstruction"; 7930} 7931 7932//---------------------------------------------------------------------------- 7933// AdvSIMD indexed element 7934//---------------------------------------------------------------------------- 7935 7936let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7937class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7938 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7939 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7940 string apple_kind, string dst_kind, string lhs_kind, 7941 string rhs_kind, list<dag> pattern> 7942 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7943 asm, 7944 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7945 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7946 Sched<[WriteVd]> { 7947 bits<5> Rd; 7948 bits<5> Rn; 7949 bits<5> Rm; 7950 7951 let Inst{31} = 0; 7952 let Inst{30} = Q; 7953 let Inst{29} = U; 7954 let Inst{28} = Scalar; 7955 let Inst{27-24} = 0b1111; 7956 let Inst{23-22} = size; 7957 // Bit 21 must be set by the derived class. 7958 let Inst{20-16} = Rm; 7959 let Inst{15-12} = opc; 7960 // Bit 11 must be set by the derived class. 7961 let Inst{10} = 0; 7962 let Inst{9-5} = Rn; 7963 let Inst{4-0} = Rd; 7964} 7965 7966let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7967class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7968 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7969 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7970 string apple_kind, string dst_kind, string lhs_kind, 7971 string rhs_kind, list<dag> pattern> 7972 : I<(outs dst_reg:$dst), 7973 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7974 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7975 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7976 Sched<[WriteVd]> { 7977 bits<5> Rd; 7978 bits<5> Rn; 7979 bits<5> Rm; 7980 7981 let Inst{31} = 0; 7982 let Inst{30} = Q; 7983 let Inst{29} = U; 7984 let Inst{28} = Scalar; 7985 let Inst{27-24} = 0b1111; 7986 let Inst{23-22} = size; 7987 // Bit 21 must be set by the derived class. 7988 let Inst{20-16} = Rm; 7989 let Inst{15-12} = opc; 7990 // Bit 11 must be set by the derived class. 7991 let Inst{10} = 0; 7992 let Inst{9-5} = Rn; 7993 let Inst{4-0} = Rd; 7994} 7995 7996 7997//---------------------------------------------------------------------------- 7998// Armv8.6 BFloat16 Extension 7999//---------------------------------------------------------------------------- 8000let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8001 8002class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8003 string kind2, RegisterOperand RegType, 8004 ValueType AccumType, ValueType InputType> 8005 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8006 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8007 (InputType RegType:$Rn), 8008 (InputType RegType:$Rm)))]> { 8009 let AsmString = !strconcat(asm, 8010 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8011 ", $Rm" # kind2 # "}"); 8012} 8013 8014multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8015 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8016 v2f32, v4bf16>; 8017 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8018 v4f32, v8bf16>; 8019} 8020 8021class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8022 string dst_kind, string lhs_kind, 8023 string rhs_kind, 8024 RegisterOperand RegType, 8025 ValueType AccumType, 8026 ValueType InputType> 8027 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8028 RegType, RegType, V128, VectorIndexS, 8029 asm, "", dst_kind, lhs_kind, rhs_kind, 8030 [(set (AccumType RegType:$dst), 8031 (AccumType (int_aarch64_neon_bfdot 8032 (AccumType RegType:$Rd), 8033 (InputType RegType:$Rn), 8034 (InputType (bitconvert (AccumType 8035 (AArch64duplane32 (v4f32 V128:$Rm), 8036 VectorIndexS:$idx)))))))]> { 8037 8038 bits<2> idx; 8039 let Inst{21} = idx{0}; // L 8040 let Inst{11} = idx{1}; // H 8041} 8042 8043multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8044 8045 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8046 ".2h", V64, v2f32, v4bf16>; 8047 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8048 ".2h", V128, v4f32, v8bf16>; 8049} 8050 8051class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8052 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8053 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8054 (v8bf16 V128:$Rn), 8055 (v8bf16 V128:$Rm)))]> { 8056 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8057} 8058 8059class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8060 : I<(outs V128:$dst), 8061 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8062 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8063 [(set (v4f32 V128:$dst), 8064 (v4f32 (OpNode (v4f32 V128:$Rd), 8065 (v8bf16 V128:$Rn), 8066 (v8bf16 8067 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8068 VectorIndexH:$idx)))))]>, 8069 Sched<[WriteVq]> { 8070 bits<5> Rd; 8071 bits<5> Rn; 8072 bits<4> Rm; 8073 bits<3> idx; 8074 8075 let Inst{31} = 0; 8076 let Inst{30} = Q; 8077 let Inst{29-22} = 0b00111111; 8078 let Inst{21-20} = idx{1-0}; 8079 let Inst{19-16} = Rm; 8080 let Inst{15-12} = 0b1111; 8081 let Inst{11} = idx{2}; // H 8082 let Inst{10} = 0; 8083 let Inst{9-5} = Rn; 8084 let Inst{4-0} = Rd; 8085} 8086 8087class SIMDThreeSameVectorBF16MatrixMul<string asm> 8088 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8089 V128, asm, ".4s", 8090 [(set (v4f32 V128:$dst), 8091 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8092 (v8bf16 V128:$Rn), 8093 (v8bf16 V128:$Rm)))]> { 8094 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8095 ", $Rm", ".8h", "}"); 8096} 8097 8098class SIMD_BFCVTN 8099 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8100 "bfcvtn", ".4h", ".4s", 8101 [(set (v8bf16 V128:$Rd), 8102 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8103 8104class SIMD_BFCVTN2 8105 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8106 "bfcvtn2", ".8h", ".4s", 8107 [(set (v8bf16 V128:$dst), 8108 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8109 8110class BF16ToSinglePrecision<string asm> 8111 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8112 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8113 Sched<[WriteFCvt]> { 8114 bits<5> Rd; 8115 bits<5> Rn; 8116 let Inst{31-10} = 0b0001111001100011010000; 8117 let Inst{9-5} = Rn; 8118 let Inst{4-0} = Rd; 8119} 8120} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8121 8122//---------------------------------------------------------------------------- 8123// Armv8.6 Matrix Multiply Extension 8124//---------------------------------------------------------------------------- 8125 8126class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8127 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8128 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8129 (v16i8 V128:$Rn), 8130 (v16i8 V128:$Rm)))]> { 8131 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8132} 8133 8134//---------------------------------------------------------------------------- 8135// ARMv8.2-A Dot Product Instructions (Indexed) 8136class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8137 string dst_kind, string lhs_kind, string rhs_kind, 8138 RegisterOperand RegType, 8139 ValueType AccumType, ValueType InputType, 8140 SDPatternOperator OpNode> : 8141 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8142 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8143 [(set (AccumType RegType:$dst), 8144 (AccumType (OpNode (AccumType RegType:$Rd), 8145 (InputType RegType:$Rn), 8146 (InputType (bitconvert (AccumType 8147 (AArch64duplane32 (v4i32 V128:$Rm), 8148 VectorIndexS:$idx)))))))]> { 8149 bits<2> idx; 8150 let Inst{21} = idx{0}; // L 8151 let Inst{11} = idx{1}; // H 8152} 8153 8154multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8155 SDPatternOperator OpNode> { 8156 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8157 V64, v2i32, v8i8, OpNode>; 8158 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8159 V128, v4i32, v16i8, OpNode>; 8160} 8161 8162// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8163class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8164 string dst_kind, string lhs_kind, 8165 string rhs_kind, RegisterOperand RegType, 8166 ValueType AccumType, ValueType InputType, 8167 SDPatternOperator OpNode> : 8168 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8169 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8170 [(set (AccumType RegType:$dst), 8171 (AccumType (OpNode (AccumType RegType:$Rd), 8172 (InputType RegType:$Rn), 8173 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8174 VectorIndexH:$idx)))))]> { 8175 // idx = H:L:M 8176 bits<3> idx; 8177 let Inst{11} = idx{2}; // H 8178 let Inst{21} = idx{1}; // L 8179 let Inst{20} = idx{0}; // M 8180} 8181 8182multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8183 SDPatternOperator OpNode> { 8184 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8185 V64, v2f32, v4f16, OpNode>; 8186 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8187 V128, v4f32, v8f16, OpNode>; 8188} 8189 8190multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8191 SDPatternOperator OpNode> { 8192 let Predicates = [HasNEON, HasFullFP16] in { 8193 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8194 V64, V64, 8195 V128_lo, VectorIndexH, 8196 asm, ".4h", ".4h", ".4h", ".h", 8197 [(set (v4f16 V64:$Rd), 8198 (OpNode (v4f16 V64:$Rn), 8199 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8200 bits<3> idx; 8201 let Inst{11} = idx{2}; 8202 let Inst{21} = idx{1}; 8203 let Inst{20} = idx{0}; 8204 } 8205 8206 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8207 V128, V128, 8208 V128_lo, VectorIndexH, 8209 asm, ".8h", ".8h", ".8h", ".h", 8210 [(set (v8f16 V128:$Rd), 8211 (OpNode (v8f16 V128:$Rn), 8212 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8213 bits<3> idx; 8214 let Inst{11} = idx{2}; 8215 let Inst{21} = idx{1}; 8216 let Inst{20} = idx{0}; 8217 } 8218 } // Predicates = [HasNEON, HasFullFP16] 8219 8220 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8221 V64, V64, 8222 V128, VectorIndexS, 8223 asm, ".2s", ".2s", ".2s", ".s", 8224 [(set (v2f32 V64:$Rd), 8225 (OpNode (v2f32 V64:$Rn), 8226 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8227 bits<2> idx; 8228 let Inst{11} = idx{1}; 8229 let Inst{21} = idx{0}; 8230 } 8231 8232 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8233 V128, V128, 8234 V128, VectorIndexS, 8235 asm, ".4s", ".4s", ".4s", ".s", 8236 [(set (v4f32 V128:$Rd), 8237 (OpNode (v4f32 V128:$Rn), 8238 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8239 bits<2> idx; 8240 let Inst{11} = idx{1}; 8241 let Inst{21} = idx{0}; 8242 } 8243 8244 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8245 V128, V128, 8246 V128, VectorIndexD, 8247 asm, ".2d", ".2d", ".2d", ".d", 8248 [(set (v2f64 V128:$Rd), 8249 (OpNode (v2f64 V128:$Rn), 8250 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8251 bits<1> idx; 8252 let Inst{11} = idx{0}; 8253 let Inst{21} = 0; 8254 } 8255 8256 let Predicates = [HasNEON, HasFullFP16] in { 8257 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8258 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8259 asm, ".h", "", "", ".h", 8260 [(set (f16 FPR16Op:$Rd), 8261 (OpNode (f16 FPR16Op:$Rn), 8262 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8263 VectorIndexH:$idx))))]> { 8264 bits<3> idx; 8265 let Inst{11} = idx{2}; 8266 let Inst{21} = idx{1}; 8267 let Inst{20} = idx{0}; 8268 } 8269 } // Predicates = [HasNEON, HasFullFP16] 8270 8271 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8272 FPR32Op, FPR32Op, V128, VectorIndexS, 8273 asm, ".s", "", "", ".s", 8274 [(set (f32 FPR32Op:$Rd), 8275 (OpNode (f32 FPR32Op:$Rn), 8276 (f32 (vector_extract (v4f32 V128:$Rm), 8277 VectorIndexS:$idx))))]> { 8278 bits<2> idx; 8279 let Inst{11} = idx{1}; 8280 let Inst{21} = idx{0}; 8281 } 8282 8283 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8284 FPR64Op, FPR64Op, V128, VectorIndexD, 8285 asm, ".d", "", "", ".d", 8286 [(set (f64 FPR64Op:$Rd), 8287 (OpNode (f64 FPR64Op:$Rn), 8288 (f64 (vector_extract (v2f64 V128:$Rm), 8289 VectorIndexD:$idx))))]> { 8290 bits<1> idx; 8291 let Inst{11} = idx{0}; 8292 let Inst{21} = 0; 8293 } 8294} 8295 8296multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8297 let Predicates = [HasNEON, HasFullFP16] in { 8298 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8299 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8300 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8301 VectorIndexH:$idx))), 8302 (!cast<Instruction>(INST # "v8i16_indexed") 8303 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8304 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8305 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8306 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8307 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8308 8309 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8310 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8311 VectorIndexH:$idx))), 8312 (!cast<Instruction>(INST # "v4i16_indexed") 8313 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8314 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8315 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8316 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8317 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8318 8319 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8320 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8321 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8322 V128_lo:$Rm, VectorIndexH:$idx)>; 8323 } // Predicates = [HasNEON, HasFullFP16] 8324 8325 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8326 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8327 (AArch64duplane32 (v4f32 V128:$Rm), 8328 VectorIndexS:$idx))), 8329 (!cast<Instruction>(INST # v2i32_indexed) 8330 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8331 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8332 (AArch64dup (f32 FPR32Op:$Rm)))), 8333 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8334 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8335 8336 8337 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8338 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8339 (AArch64duplane32 (v4f32 V128:$Rm), 8340 VectorIndexS:$idx))), 8341 (!cast<Instruction>(INST # "v4i32_indexed") 8342 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8343 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8344 (AArch64dup (f32 FPR32Op:$Rm)))), 8345 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8346 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8347 8348 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8349 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8350 (AArch64duplane64 (v2f64 V128:$Rm), 8351 VectorIndexD:$idx))), 8352 (!cast<Instruction>(INST # "v2i64_indexed") 8353 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8354 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8355 (AArch64dup (f64 FPR64Op:$Rm)))), 8356 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8357 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8358 8359 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8360 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8361 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8362 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8363 V128:$Rm, VectorIndexS:$idx)>; 8364 8365 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8366 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8367 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8368 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8369 V128:$Rm, VectorIndexD:$idx)>; 8370} 8371 8372multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8373 let Predicates = [HasNEON, HasFullFP16] in { 8374 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8375 V128_lo, VectorIndexH, 8376 asm, ".4h", ".4h", ".4h", ".h", []> { 8377 bits<3> idx; 8378 let Inst{11} = idx{2}; 8379 let Inst{21} = idx{1}; 8380 let Inst{20} = idx{0}; 8381 } 8382 8383 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8384 V128, V128, 8385 V128_lo, VectorIndexH, 8386 asm, ".8h", ".8h", ".8h", ".h", []> { 8387 bits<3> idx; 8388 let Inst{11} = idx{2}; 8389 let Inst{21} = idx{1}; 8390 let Inst{20} = idx{0}; 8391 } 8392 } // Predicates = [HasNEON, HasFullFP16] 8393 8394 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8395 V128, VectorIndexS, 8396 asm, ".2s", ".2s", ".2s", ".s", []> { 8397 bits<2> idx; 8398 let Inst{11} = idx{1}; 8399 let Inst{21} = idx{0}; 8400 } 8401 8402 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8403 V128, V128, 8404 V128, VectorIndexS, 8405 asm, ".4s", ".4s", ".4s", ".s", []> { 8406 bits<2> idx; 8407 let Inst{11} = idx{1}; 8408 let Inst{21} = idx{0}; 8409 } 8410 8411 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8412 V128, V128, 8413 V128, VectorIndexD, 8414 asm, ".2d", ".2d", ".2d", ".d", []> { 8415 bits<1> idx; 8416 let Inst{11} = idx{0}; 8417 let Inst{21} = 0; 8418 } 8419 8420 let Predicates = [HasNEON, HasFullFP16] in { 8421 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8422 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8423 asm, ".h", "", "", ".h", []> { 8424 bits<3> idx; 8425 let Inst{11} = idx{2}; 8426 let Inst{21} = idx{1}; 8427 let Inst{20} = idx{0}; 8428 } 8429 } // Predicates = [HasNEON, HasFullFP16] 8430 8431 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8432 FPR32Op, FPR32Op, V128, VectorIndexS, 8433 asm, ".s", "", "", ".s", []> { 8434 bits<2> idx; 8435 let Inst{11} = idx{1}; 8436 let Inst{21} = idx{0}; 8437 } 8438 8439 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8440 FPR64Op, FPR64Op, V128, VectorIndexD, 8441 asm, ".d", "", "", ".d", []> { 8442 bits<1> idx; 8443 let Inst{11} = idx{0}; 8444 let Inst{21} = 0; 8445 } 8446} 8447 8448multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8449 SDPatternOperator OpNodeLaneQ> { 8450 8451 def : Pat<(v4i16 (OpNodeLane 8452 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8453 VectorIndexS32b:$idx)), 8454 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8455 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8456 (UImmS1XForm $idx))>; 8457 8458 def : Pat<(v4i16 (OpNodeLaneQ 8459 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8460 VectorIndexH32b:$idx)), 8461 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8462 (UImmS1XForm $idx))>; 8463 8464 def : Pat<(v8i16 (OpNodeLane 8465 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8466 VectorIndexS32b:$idx)), 8467 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8468 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8469 (UImmS1XForm $idx))>; 8470 8471 def : Pat<(v8i16 (OpNodeLaneQ 8472 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8473 VectorIndexH32b:$idx)), 8474 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8475 (UImmS1XForm $idx))>; 8476 8477 def : Pat<(v2i32 (OpNodeLane 8478 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8479 VectorIndexD32b:$idx)), 8480 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8481 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8482 (UImmS1XForm $idx))>; 8483 8484 def : Pat<(v2i32 (OpNodeLaneQ 8485 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8486 VectorIndexS32b:$idx)), 8487 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8488 (UImmS1XForm $idx))>; 8489 8490 def : Pat<(v4i32 (OpNodeLane 8491 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8492 VectorIndexD32b:$idx)), 8493 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8494 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8495 (UImmS1XForm $idx))>; 8496 8497 def : Pat<(v4i32 (OpNodeLaneQ 8498 (v4i32 V128:$Rn), 8499 (v4i32 V128:$Rm), 8500 VectorIndexS32b:$idx)), 8501 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8502 (UImmS1XForm $idx))>; 8503 8504} 8505 8506multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8507 SDPatternOperator OpNode> { 8508 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8509 V128_lo, VectorIndexH, 8510 asm, ".4h", ".4h", ".4h", ".h", 8511 [(set (v4i16 V64:$Rd), 8512 (OpNode (v4i16 V64:$Rn), 8513 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8514 bits<3> idx; 8515 let Inst{11} = idx{2}; 8516 let Inst{21} = idx{1}; 8517 let Inst{20} = idx{0}; 8518 } 8519 8520 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8521 V128, V128, 8522 V128_lo, VectorIndexH, 8523 asm, ".8h", ".8h", ".8h", ".h", 8524 [(set (v8i16 V128:$Rd), 8525 (OpNode (v8i16 V128:$Rn), 8526 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8527 bits<3> idx; 8528 let Inst{11} = idx{2}; 8529 let Inst{21} = idx{1}; 8530 let Inst{20} = idx{0}; 8531 } 8532 8533 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8534 V64, V64, 8535 V128, VectorIndexS, 8536 asm, ".2s", ".2s", ".2s", ".s", 8537 [(set (v2i32 V64:$Rd), 8538 (OpNode (v2i32 V64:$Rn), 8539 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8540 bits<2> idx; 8541 let Inst{11} = idx{1}; 8542 let Inst{21} = idx{0}; 8543 } 8544 8545 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8546 V128, V128, 8547 V128, VectorIndexS, 8548 asm, ".4s", ".4s", ".4s", ".s", 8549 [(set (v4i32 V128:$Rd), 8550 (OpNode (v4i32 V128:$Rn), 8551 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8552 bits<2> idx; 8553 let Inst{11} = idx{1}; 8554 let Inst{21} = idx{0}; 8555 } 8556 8557 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8558 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8559 asm, ".h", "", "", ".h", []> { 8560 bits<3> idx; 8561 let Inst{11} = idx{2}; 8562 let Inst{21} = idx{1}; 8563 let Inst{20} = idx{0}; 8564 } 8565 8566 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8567 FPR32Op, FPR32Op, V128, VectorIndexS, 8568 asm, ".s", "", "", ".s", 8569 [(set (i32 FPR32Op:$Rd), 8570 (OpNode FPR32Op:$Rn, 8571 (i32 (vector_extract (v4i32 V128:$Rm), 8572 VectorIndexS:$idx))))]> { 8573 bits<2> idx; 8574 let Inst{11} = idx{1}; 8575 let Inst{21} = idx{0}; 8576 } 8577} 8578 8579multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8580 SDPatternOperator OpNode> { 8581 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8582 V64, V64, 8583 V128_lo, VectorIndexH, 8584 asm, ".4h", ".4h", ".4h", ".h", 8585 [(set (v4i16 V64:$Rd), 8586 (OpNode (v4i16 V64:$Rn), 8587 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8588 bits<3> idx; 8589 let Inst{11} = idx{2}; 8590 let Inst{21} = idx{1}; 8591 let Inst{20} = idx{0}; 8592 } 8593 8594 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8595 V128, V128, 8596 V128_lo, VectorIndexH, 8597 asm, ".8h", ".8h", ".8h", ".h", 8598 [(set (v8i16 V128:$Rd), 8599 (OpNode (v8i16 V128:$Rn), 8600 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8601 bits<3> idx; 8602 let Inst{11} = idx{2}; 8603 let Inst{21} = idx{1}; 8604 let Inst{20} = idx{0}; 8605 } 8606 8607 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8608 V64, V64, 8609 V128, VectorIndexS, 8610 asm, ".2s", ".2s", ".2s", ".s", 8611 [(set (v2i32 V64:$Rd), 8612 (OpNode (v2i32 V64:$Rn), 8613 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8614 bits<2> idx; 8615 let Inst{11} = idx{1}; 8616 let Inst{21} = idx{0}; 8617 } 8618 8619 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8620 V128, V128, 8621 V128, VectorIndexS, 8622 asm, ".4s", ".4s", ".4s", ".s", 8623 [(set (v4i32 V128:$Rd), 8624 (OpNode (v4i32 V128:$Rn), 8625 (v4i32 (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 8632multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8633 SDPatternOperator OpNode> { 8634 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8635 V128_lo, VectorIndexH, 8636 asm, ".4h", ".4h", ".4h", ".h", 8637 [(set (v4i16 V64:$dst), 8638 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8639 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8640 bits<3> idx; 8641 let Inst{11} = idx{2}; 8642 let Inst{21} = idx{1}; 8643 let Inst{20} = idx{0}; 8644 } 8645 8646 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8647 V128, V128, 8648 V128_lo, VectorIndexH, 8649 asm, ".8h", ".8h", ".8h", ".h", 8650 [(set (v8i16 V128:$dst), 8651 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8652 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8653 bits<3> idx; 8654 let Inst{11} = idx{2}; 8655 let Inst{21} = idx{1}; 8656 let Inst{20} = idx{0}; 8657 } 8658 8659 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8660 V64, V64, 8661 V128, VectorIndexS, 8662 asm, ".2s", ".2s", ".2s", ".s", 8663 [(set (v2i32 V64:$dst), 8664 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8665 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8666 bits<2> idx; 8667 let Inst{11} = idx{1}; 8668 let Inst{21} = idx{0}; 8669 } 8670 8671 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8672 V128, V128, 8673 V128, VectorIndexS, 8674 asm, ".4s", ".4s", ".4s", ".s", 8675 [(set (v4i32 V128:$dst), 8676 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8677 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8678 bits<2> idx; 8679 let Inst{11} = idx{1}; 8680 let Inst{21} = idx{0}; 8681 } 8682} 8683 8684multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8685 SDPatternOperator OpNode> { 8686 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8687 V128, V64, 8688 V128_lo, VectorIndexH, 8689 asm, ".4s", ".4s", ".4h", ".h", 8690 [(set (v4i32 V128:$Rd), 8691 (OpNode (v4i16 V64:$Rn), 8692 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8693 bits<3> idx; 8694 let Inst{11} = idx{2}; 8695 let Inst{21} = idx{1}; 8696 let Inst{20} = idx{0}; 8697 } 8698 8699 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8700 V128, V128, 8701 V128_lo, VectorIndexH, 8702 asm#"2", ".4s", ".4s", ".8h", ".h", 8703 [(set (v4i32 V128:$Rd), 8704 (OpNode (extract_high_v8i16 V128:$Rn), 8705 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8706 VectorIndexH:$idx))))]> { 8707 8708 bits<3> idx; 8709 let Inst{11} = idx{2}; 8710 let Inst{21} = idx{1}; 8711 let Inst{20} = idx{0}; 8712 } 8713 8714 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8715 V128, V64, 8716 V128, VectorIndexS, 8717 asm, ".2d", ".2d", ".2s", ".s", 8718 [(set (v2i64 V128:$Rd), 8719 (OpNode (v2i32 V64:$Rn), 8720 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8721 bits<2> idx; 8722 let Inst{11} = idx{1}; 8723 let Inst{21} = idx{0}; 8724 } 8725 8726 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8727 V128, V128, 8728 V128, VectorIndexS, 8729 asm#"2", ".2d", ".2d", ".4s", ".s", 8730 [(set (v2i64 V128:$Rd), 8731 (OpNode (extract_high_v4i32 V128:$Rn), 8732 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8733 VectorIndexS:$idx))))]> { 8734 bits<2> idx; 8735 let Inst{11} = idx{1}; 8736 let Inst{21} = idx{0}; 8737 } 8738 8739 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8740 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8741 asm, ".h", "", "", ".h", []> { 8742 bits<3> idx; 8743 let Inst{11} = idx{2}; 8744 let Inst{21} = idx{1}; 8745 let Inst{20} = idx{0}; 8746 } 8747 8748 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8749 FPR64Op, FPR32Op, V128, VectorIndexS, 8750 asm, ".s", "", "", ".s", []> { 8751 bits<2> idx; 8752 let Inst{11} = idx{1}; 8753 let Inst{21} = idx{0}; 8754 } 8755} 8756 8757multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8758 SDPatternOperator Accum> { 8759 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8760 V128, V64, 8761 V128_lo, VectorIndexH, 8762 asm, ".4s", ".4s", ".4h", ".h", 8763 [(set (v4i32 V128:$dst), 8764 (Accum (v4i32 V128:$Rd), 8765 (v4i32 (int_aarch64_neon_sqdmull 8766 (v4i16 V64:$Rn), 8767 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8768 VectorIndexH:$idx))))))]> { 8769 bits<3> idx; 8770 let Inst{11} = idx{2}; 8771 let Inst{21} = idx{1}; 8772 let Inst{20} = idx{0}; 8773 } 8774 8775 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8776 // intermediate EXTRACT_SUBREG would be untyped. 8777 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8778 (i32 (vector_extract (v4i32 8779 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8780 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8781 VectorIndexH:$idx)))), 8782 (i64 0))))), 8783 (EXTRACT_SUBREG 8784 (!cast<Instruction>(NAME # v4i16_indexed) 8785 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8786 V128_lo:$Rm, VectorIndexH:$idx), 8787 ssub)>; 8788 8789 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8790 V128, V128, 8791 V128_lo, VectorIndexH, 8792 asm#"2", ".4s", ".4s", ".8h", ".h", 8793 [(set (v4i32 V128:$dst), 8794 (Accum (v4i32 V128:$Rd), 8795 (v4i32 (int_aarch64_neon_sqdmull 8796 (extract_high_v8i16 V128:$Rn), 8797 (extract_high_v8i16 8798 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8799 VectorIndexH:$idx))))))]> { 8800 bits<3> idx; 8801 let Inst{11} = idx{2}; 8802 let Inst{21} = idx{1}; 8803 let Inst{20} = idx{0}; 8804 } 8805 8806 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8807 V128, V64, 8808 V128, VectorIndexS, 8809 asm, ".2d", ".2d", ".2s", ".s", 8810 [(set (v2i64 V128:$dst), 8811 (Accum (v2i64 V128:$Rd), 8812 (v2i64 (int_aarch64_neon_sqdmull 8813 (v2i32 V64:$Rn), 8814 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8815 VectorIndexS:$idx))))))]> { 8816 bits<2> idx; 8817 let Inst{11} = idx{1}; 8818 let Inst{21} = idx{0}; 8819 } 8820 8821 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8822 V128, V128, 8823 V128, VectorIndexS, 8824 asm#"2", ".2d", ".2d", ".4s", ".s", 8825 [(set (v2i64 V128:$dst), 8826 (Accum (v2i64 V128:$Rd), 8827 (v2i64 (int_aarch64_neon_sqdmull 8828 (extract_high_v4i32 V128:$Rn), 8829 (extract_high_v4i32 8830 (AArch64duplane32 (v4i32 V128:$Rm), 8831 VectorIndexS:$idx))))))]> { 8832 bits<2> idx; 8833 let Inst{11} = idx{1}; 8834 let Inst{21} = idx{0}; 8835 } 8836 8837 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8838 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8839 asm, ".h", "", "", ".h", []> { 8840 bits<3> idx; 8841 let Inst{11} = idx{2}; 8842 let Inst{21} = idx{1}; 8843 let Inst{20} = idx{0}; 8844 } 8845 8846 8847 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8848 FPR64Op, FPR32Op, V128, VectorIndexS, 8849 asm, ".s", "", "", ".s", 8850 [(set (i64 FPR64Op:$dst), 8851 (Accum (i64 FPR64Op:$Rd), 8852 (i64 (int_aarch64_neon_sqdmulls_scalar 8853 (i32 FPR32Op:$Rn), 8854 (i32 (vector_extract (v4i32 V128:$Rm), 8855 VectorIndexS:$idx))))))]> { 8856 8857 bits<2> idx; 8858 let Inst{11} = idx{1}; 8859 let Inst{21} = idx{0}; 8860 } 8861} 8862 8863multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8864 SDPatternOperator OpNode> { 8865 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8866 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8867 V128, V64, 8868 V128_lo, VectorIndexH, 8869 asm, ".4s", ".4s", ".4h", ".h", 8870 [(set (v4i32 V128:$Rd), 8871 (OpNode (v4i16 V64:$Rn), 8872 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8873 bits<3> idx; 8874 let Inst{11} = idx{2}; 8875 let Inst{21} = idx{1}; 8876 let Inst{20} = idx{0}; 8877 } 8878 8879 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8880 V128, V128, 8881 V128_lo, VectorIndexH, 8882 asm#"2", ".4s", ".4s", ".8h", ".h", 8883 [(set (v4i32 V128:$Rd), 8884 (OpNode (extract_high_v8i16 V128:$Rn), 8885 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8886 VectorIndexH:$idx))))]> { 8887 8888 bits<3> idx; 8889 let Inst{11} = idx{2}; 8890 let Inst{21} = idx{1}; 8891 let Inst{20} = idx{0}; 8892 } 8893 8894 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8895 V128, V64, 8896 V128, VectorIndexS, 8897 asm, ".2d", ".2d", ".2s", ".s", 8898 [(set (v2i64 V128:$Rd), 8899 (OpNode (v2i32 V64:$Rn), 8900 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8901 bits<2> idx; 8902 let Inst{11} = idx{1}; 8903 let Inst{21} = idx{0}; 8904 } 8905 8906 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8907 V128, V128, 8908 V128, VectorIndexS, 8909 asm#"2", ".2d", ".2d", ".4s", ".s", 8910 [(set (v2i64 V128:$Rd), 8911 (OpNode (extract_high_v4i32 V128:$Rn), 8912 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8913 VectorIndexS:$idx))))]> { 8914 bits<2> idx; 8915 let Inst{11} = idx{1}; 8916 let Inst{21} = idx{0}; 8917 } 8918 } 8919} 8920 8921multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8922 SDPatternOperator OpNode> { 8923 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8924 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8925 V128, V64, 8926 V128_lo, VectorIndexH, 8927 asm, ".4s", ".4s", ".4h", ".h", 8928 [(set (v4i32 V128:$dst), 8929 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8930 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8931 bits<3> idx; 8932 let Inst{11} = idx{2}; 8933 let Inst{21} = idx{1}; 8934 let Inst{20} = idx{0}; 8935 } 8936 8937 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8938 V128, V128, 8939 V128_lo, VectorIndexH, 8940 asm#"2", ".4s", ".4s", ".8h", ".h", 8941 [(set (v4i32 V128:$dst), 8942 (OpNode (v4i32 V128:$Rd), 8943 (extract_high_v8i16 V128:$Rn), 8944 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8945 VectorIndexH:$idx))))]> { 8946 bits<3> idx; 8947 let Inst{11} = idx{2}; 8948 let Inst{21} = idx{1}; 8949 let Inst{20} = idx{0}; 8950 } 8951 8952 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8953 V128, V64, 8954 V128, VectorIndexS, 8955 asm, ".2d", ".2d", ".2s", ".s", 8956 [(set (v2i64 V128:$dst), 8957 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8958 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8959 bits<2> idx; 8960 let Inst{11} = idx{1}; 8961 let Inst{21} = idx{0}; 8962 } 8963 8964 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8965 V128, V128, 8966 V128, VectorIndexS, 8967 asm#"2", ".2d", ".2d", ".4s", ".s", 8968 [(set (v2i64 V128:$dst), 8969 (OpNode (v2i64 V128:$Rd), 8970 (extract_high_v4i32 V128:$Rn), 8971 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8972 VectorIndexS:$idx))))]> { 8973 bits<2> idx; 8974 let Inst{11} = idx{1}; 8975 let Inst{21} = idx{0}; 8976 } 8977 } 8978} 8979 8980//---------------------------------------------------------------------------- 8981// AdvSIMD scalar shift by immediate 8982//---------------------------------------------------------------------------- 8983 8984let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8985class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8986 RegisterClass regtype1, RegisterClass regtype2, 8987 Operand immtype, string asm, list<dag> pattern> 8988 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8989 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8990 Sched<[WriteVd]> { 8991 bits<5> Rd; 8992 bits<5> Rn; 8993 bits<7> imm; 8994 let Inst{31-30} = 0b01; 8995 let Inst{29} = U; 8996 let Inst{28-23} = 0b111110; 8997 let Inst{22-16} = fixed_imm; 8998 let Inst{15-11} = opc; 8999 let Inst{10} = 1; 9000 let Inst{9-5} = Rn; 9001 let Inst{4-0} = Rd; 9002} 9003 9004let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9005class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9006 RegisterClass regtype1, RegisterClass regtype2, 9007 Operand immtype, string asm, list<dag> pattern> 9008 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9009 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9010 Sched<[WriteVd]> { 9011 bits<5> Rd; 9012 bits<5> Rn; 9013 bits<7> imm; 9014 let Inst{31-30} = 0b01; 9015 let Inst{29} = U; 9016 let Inst{28-23} = 0b111110; 9017 let Inst{22-16} = fixed_imm; 9018 let Inst{15-11} = opc; 9019 let Inst{10} = 1; 9020 let Inst{9-5} = Rn; 9021 let Inst{4-0} = Rd; 9022} 9023 9024 9025multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9026 let Predicates = [HasNEON, HasFullFP16] in { 9027 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9028 FPR16, FPR16, vecshiftR16, asm, []> { 9029 let Inst{19-16} = imm{3-0}; 9030 } 9031 } // Predicates = [HasNEON, HasFullFP16] 9032 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9033 FPR32, FPR32, vecshiftR32, asm, []> { 9034 let Inst{20-16} = imm{4-0}; 9035 } 9036 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9037 FPR64, FPR64, vecshiftR64, asm, []> { 9038 let Inst{21-16} = imm{5-0}; 9039 } 9040} 9041 9042multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9043 SDPatternOperator OpNode> { 9044 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9045 FPR64, FPR64, vecshiftR64, asm, 9046 [(set (i64 FPR64:$Rd), 9047 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9048 let Inst{21-16} = imm{5-0}; 9049 } 9050 9051 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9052 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9053} 9054 9055multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9056 SDPatternOperator OpNode = null_frag> { 9057 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9058 FPR64, FPR64, vecshiftR64, asm, 9059 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9060 (i32 vecshiftR64:$imm)))]> { 9061 let Inst{21-16} = imm{5-0}; 9062 } 9063 9064 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9065 (i32 vecshiftR64:$imm))), 9066 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9067 vecshiftR64:$imm)>; 9068} 9069 9070multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9071 SDPatternOperator OpNode> { 9072 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9073 FPR64, FPR64, vecshiftL64, asm, 9074 [(set (i64 FPR64:$Rd), 9075 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9076 let Inst{21-16} = imm{5-0}; 9077 } 9078 9079 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9080 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9081} 9082 9083let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9084multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9085 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9086 FPR64, FPR64, vecshiftL64, asm, []> { 9087 let Inst{21-16} = imm{5-0}; 9088 } 9089} 9090 9091let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9092multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9093 SDPatternOperator OpNode = null_frag> { 9094 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9095 FPR8, FPR16, vecshiftR8, asm, []> { 9096 let Inst{18-16} = imm{2-0}; 9097 } 9098 9099 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9100 FPR16, FPR32, vecshiftR16, asm, []> { 9101 let Inst{19-16} = imm{3-0}; 9102 } 9103 9104 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9105 FPR32, FPR64, vecshiftR32, asm, 9106 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9107 let Inst{20-16} = imm{4-0}; 9108 } 9109} 9110 9111multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9112 SDPatternOperator OpNode> { 9113 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9114 FPR8, FPR8, vecshiftL8, asm, []> { 9115 let Inst{18-16} = imm{2-0}; 9116 } 9117 9118 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9119 FPR16, FPR16, vecshiftL16, asm, []> { 9120 let Inst{19-16} = imm{3-0}; 9121 } 9122 9123 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9124 FPR32, FPR32, vecshiftL32, asm, 9125 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9126 let Inst{20-16} = imm{4-0}; 9127 } 9128 9129 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9130 FPR64, FPR64, vecshiftL64, asm, 9131 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9132 let Inst{21-16} = imm{5-0}; 9133 } 9134 9135 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9136 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9137} 9138 9139multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9140 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9141 FPR8, FPR8, vecshiftR8, asm, []> { 9142 let Inst{18-16} = imm{2-0}; 9143 } 9144 9145 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9146 FPR16, FPR16, vecshiftR16, asm, []> { 9147 let Inst{19-16} = imm{3-0}; 9148 } 9149 9150 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9151 FPR32, FPR32, vecshiftR32, asm, []> { 9152 let Inst{20-16} = imm{4-0}; 9153 } 9154 9155 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9156 FPR64, FPR64, vecshiftR64, asm, []> { 9157 let Inst{21-16} = imm{5-0}; 9158 } 9159} 9160 9161//---------------------------------------------------------------------------- 9162// AdvSIMD vector x indexed element 9163//---------------------------------------------------------------------------- 9164 9165let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9166class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9167 RegisterOperand dst_reg, RegisterOperand src_reg, 9168 Operand immtype, 9169 string asm, string dst_kind, string src_kind, 9170 list<dag> pattern> 9171 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9172 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9173 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9174 Sched<[!if(Q, WriteVq, WriteVd)]> { 9175 bits<5> Rd; 9176 bits<5> Rn; 9177 let Inst{31} = 0; 9178 let Inst{30} = Q; 9179 let Inst{29} = U; 9180 let Inst{28-23} = 0b011110; 9181 let Inst{22-16} = fixed_imm; 9182 let Inst{15-11} = opc; 9183 let Inst{10} = 1; 9184 let Inst{9-5} = Rn; 9185 let Inst{4-0} = Rd; 9186} 9187 9188let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9189class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9190 RegisterOperand vectype1, RegisterOperand vectype2, 9191 Operand immtype, 9192 string asm, string dst_kind, string src_kind, 9193 list<dag> pattern> 9194 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9195 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9196 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9197 Sched<[!if(Q, WriteVq, WriteVd)]> { 9198 bits<5> Rd; 9199 bits<5> Rn; 9200 let Inst{31} = 0; 9201 let Inst{30} = Q; 9202 let Inst{29} = U; 9203 let Inst{28-23} = 0b011110; 9204 let Inst{22-16} = fixed_imm; 9205 let Inst{15-11} = opc; 9206 let Inst{10} = 1; 9207 let Inst{9-5} = Rn; 9208 let Inst{4-0} = Rd; 9209} 9210 9211multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9212 Intrinsic OpNode> { 9213 let Predicates = [HasNEON, HasFullFP16] in { 9214 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9215 V64, V64, vecshiftR16, 9216 asm, ".4h", ".4h", 9217 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9218 bits<4> imm; 9219 let Inst{19-16} = imm; 9220 } 9221 9222 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9223 V128, V128, vecshiftR16, 9224 asm, ".8h", ".8h", 9225 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9226 bits<4> imm; 9227 let Inst{19-16} = imm; 9228 } 9229 } // Predicates = [HasNEON, HasFullFP16] 9230 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9231 V64, V64, vecshiftR32, 9232 asm, ".2s", ".2s", 9233 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9234 bits<5> imm; 9235 let Inst{20-16} = imm; 9236 } 9237 9238 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9239 V128, V128, vecshiftR32, 9240 asm, ".4s", ".4s", 9241 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9242 bits<5> imm; 9243 let Inst{20-16} = imm; 9244 } 9245 9246 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9247 V128, V128, vecshiftR64, 9248 asm, ".2d", ".2d", 9249 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9250 bits<6> imm; 9251 let Inst{21-16} = imm; 9252 } 9253} 9254 9255multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9256 Intrinsic OpNode> { 9257 let Predicates = [HasNEON, HasFullFP16] in { 9258 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9259 V64, V64, vecshiftR16, 9260 asm, ".4h", ".4h", 9261 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9262 bits<4> imm; 9263 let Inst{19-16} = imm; 9264 } 9265 9266 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9267 V128, V128, vecshiftR16, 9268 asm, ".8h", ".8h", 9269 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9270 bits<4> imm; 9271 let Inst{19-16} = imm; 9272 } 9273 } // Predicates = [HasNEON, HasFullFP16] 9274 9275 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9276 V64, V64, vecshiftR32, 9277 asm, ".2s", ".2s", 9278 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9279 bits<5> imm; 9280 let Inst{20-16} = imm; 9281 } 9282 9283 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9284 V128, V128, vecshiftR32, 9285 asm, ".4s", ".4s", 9286 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9287 bits<5> imm; 9288 let Inst{20-16} = imm; 9289 } 9290 9291 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9292 V128, V128, vecshiftR64, 9293 asm, ".2d", ".2d", 9294 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9295 bits<6> imm; 9296 let Inst{21-16} = imm; 9297 } 9298} 9299 9300multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9301 SDPatternOperator OpNode> { 9302 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9303 V64, V128, vecshiftR16Narrow, 9304 asm, ".8b", ".8h", 9305 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9306 bits<3> imm; 9307 let Inst{18-16} = imm; 9308 } 9309 9310 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9311 V128, V128, vecshiftR16Narrow, 9312 asm#"2", ".16b", ".8h", []> { 9313 bits<3> imm; 9314 let Inst{18-16} = imm; 9315 let hasSideEffects = 0; 9316 } 9317 9318 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9319 V64, V128, vecshiftR32Narrow, 9320 asm, ".4h", ".4s", 9321 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9322 bits<4> imm; 9323 let Inst{19-16} = imm; 9324 } 9325 9326 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9327 V128, V128, vecshiftR32Narrow, 9328 asm#"2", ".8h", ".4s", []> { 9329 bits<4> imm; 9330 let Inst{19-16} = imm; 9331 let hasSideEffects = 0; 9332 } 9333 9334 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9335 V64, V128, vecshiftR64Narrow, 9336 asm, ".2s", ".2d", 9337 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9338 bits<5> imm; 9339 let Inst{20-16} = imm; 9340 } 9341 9342 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9343 V128, V128, vecshiftR64Narrow, 9344 asm#"2", ".4s", ".2d", []> { 9345 bits<5> imm; 9346 let Inst{20-16} = imm; 9347 let hasSideEffects = 0; 9348 } 9349 9350 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9351 // themselves, so put them here instead. 9352 9353 // Patterns involving what's effectively an insert high and a normal 9354 // intrinsic, represented by CONCAT_VECTORS. 9355 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9356 vecshiftR16Narrow:$imm)), 9357 (!cast<Instruction>(NAME # "v16i8_shift") 9358 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9359 V128:$Rn, vecshiftR16Narrow:$imm)>; 9360 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9361 vecshiftR32Narrow:$imm)), 9362 (!cast<Instruction>(NAME # "v8i16_shift") 9363 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9364 V128:$Rn, vecshiftR32Narrow:$imm)>; 9365 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9366 vecshiftR64Narrow:$imm)), 9367 (!cast<Instruction>(NAME # "v4i32_shift") 9368 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9369 V128:$Rn, vecshiftR64Narrow:$imm)>; 9370} 9371 9372multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9373 SDPatternOperator OpNode> { 9374 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9375 V64, V64, vecshiftL8, 9376 asm, ".8b", ".8b", 9377 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9378 (i32 vecshiftL8:$imm)))]> { 9379 bits<3> imm; 9380 let Inst{18-16} = imm; 9381 } 9382 9383 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9384 V128, V128, vecshiftL8, 9385 asm, ".16b", ".16b", 9386 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9387 (i32 vecshiftL8:$imm)))]> { 9388 bits<3> imm; 9389 let Inst{18-16} = imm; 9390 } 9391 9392 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9393 V64, V64, vecshiftL16, 9394 asm, ".4h", ".4h", 9395 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9396 (i32 vecshiftL16:$imm)))]> { 9397 bits<4> imm; 9398 let Inst{19-16} = imm; 9399 } 9400 9401 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9402 V128, V128, vecshiftL16, 9403 asm, ".8h", ".8h", 9404 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9405 (i32 vecshiftL16:$imm)))]> { 9406 bits<4> imm; 9407 let Inst{19-16} = imm; 9408 } 9409 9410 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9411 V64, V64, vecshiftL32, 9412 asm, ".2s", ".2s", 9413 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9414 (i32 vecshiftL32:$imm)))]> { 9415 bits<5> imm; 9416 let Inst{20-16} = imm; 9417 } 9418 9419 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9420 V128, V128, vecshiftL32, 9421 asm, ".4s", ".4s", 9422 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9423 (i32 vecshiftL32:$imm)))]> { 9424 bits<5> imm; 9425 let Inst{20-16} = imm; 9426 } 9427 9428 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9429 V128, V128, vecshiftL64, 9430 asm, ".2d", ".2d", 9431 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9432 (i32 vecshiftL64:$imm)))]> { 9433 bits<6> imm; 9434 let Inst{21-16} = imm; 9435 } 9436} 9437 9438multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9439 SDPatternOperator OpNode> { 9440 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9441 V64, V64, vecshiftR8, 9442 asm, ".8b", ".8b", 9443 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9444 (i32 vecshiftR8:$imm)))]> { 9445 bits<3> imm; 9446 let Inst{18-16} = imm; 9447 } 9448 9449 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9450 V128, V128, vecshiftR8, 9451 asm, ".16b", ".16b", 9452 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9453 (i32 vecshiftR8:$imm)))]> { 9454 bits<3> imm; 9455 let Inst{18-16} = imm; 9456 } 9457 9458 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9459 V64, V64, vecshiftR16, 9460 asm, ".4h", ".4h", 9461 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9462 (i32 vecshiftR16:$imm)))]> { 9463 bits<4> imm; 9464 let Inst{19-16} = imm; 9465 } 9466 9467 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9468 V128, V128, vecshiftR16, 9469 asm, ".8h", ".8h", 9470 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9471 (i32 vecshiftR16:$imm)))]> { 9472 bits<4> imm; 9473 let Inst{19-16} = imm; 9474 } 9475 9476 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9477 V64, V64, vecshiftR32, 9478 asm, ".2s", ".2s", 9479 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9480 (i32 vecshiftR32:$imm)))]> { 9481 bits<5> imm; 9482 let Inst{20-16} = imm; 9483 } 9484 9485 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9486 V128, V128, vecshiftR32, 9487 asm, ".4s", ".4s", 9488 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9489 (i32 vecshiftR32:$imm)))]> { 9490 bits<5> imm; 9491 let Inst{20-16} = imm; 9492 } 9493 9494 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9495 V128, V128, vecshiftR64, 9496 asm, ".2d", ".2d", 9497 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9498 (i32 vecshiftR64:$imm)))]> { 9499 bits<6> imm; 9500 let Inst{21-16} = imm; 9501 } 9502} 9503 9504let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9505multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9506 SDPatternOperator OpNode = null_frag> { 9507 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9508 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9509 [(set (v8i8 V64:$dst), 9510 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9511 (i32 vecshiftR8:$imm)))]> { 9512 bits<3> imm; 9513 let Inst{18-16} = imm; 9514 } 9515 9516 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9517 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9518 [(set (v16i8 V128:$dst), 9519 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9520 (i32 vecshiftR8:$imm)))]> { 9521 bits<3> imm; 9522 let Inst{18-16} = imm; 9523 } 9524 9525 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9526 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9527 [(set (v4i16 V64:$dst), 9528 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9529 (i32 vecshiftR16:$imm)))]> { 9530 bits<4> imm; 9531 let Inst{19-16} = imm; 9532 } 9533 9534 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9535 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9536 [(set (v8i16 V128:$dst), 9537 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9538 (i32 vecshiftR16:$imm)))]> { 9539 bits<4> imm; 9540 let Inst{19-16} = imm; 9541 } 9542 9543 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9544 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9545 [(set (v2i32 V64:$dst), 9546 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9547 (i32 vecshiftR32:$imm)))]> { 9548 bits<5> imm; 9549 let Inst{20-16} = imm; 9550 } 9551 9552 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9553 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9554 [(set (v4i32 V128:$dst), 9555 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9556 (i32 vecshiftR32:$imm)))]> { 9557 bits<5> imm; 9558 let Inst{20-16} = imm; 9559 } 9560 9561 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9562 V128, V128, vecshiftR64, 9563 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9564 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9565 (i32 vecshiftR64:$imm)))]> { 9566 bits<6> imm; 9567 let Inst{21-16} = imm; 9568 } 9569} 9570 9571multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9572 SDPatternOperator OpNode = null_frag> { 9573 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9574 V64, V64, vecshiftL8, 9575 asm, ".8b", ".8b", 9576 [(set (v8i8 V64:$dst), 9577 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9578 (i32 vecshiftL8:$imm)))]> { 9579 bits<3> imm; 9580 let Inst{18-16} = imm; 9581 } 9582 9583 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9584 V128, V128, vecshiftL8, 9585 asm, ".16b", ".16b", 9586 [(set (v16i8 V128:$dst), 9587 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9588 (i32 vecshiftL8:$imm)))]> { 9589 bits<3> imm; 9590 let Inst{18-16} = imm; 9591 } 9592 9593 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9594 V64, V64, vecshiftL16, 9595 asm, ".4h", ".4h", 9596 [(set (v4i16 V64:$dst), 9597 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9598 (i32 vecshiftL16:$imm)))]> { 9599 bits<4> imm; 9600 let Inst{19-16} = imm; 9601 } 9602 9603 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9604 V128, V128, vecshiftL16, 9605 asm, ".8h", ".8h", 9606 [(set (v8i16 V128:$dst), 9607 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9608 (i32 vecshiftL16:$imm)))]> { 9609 bits<4> imm; 9610 let Inst{19-16} = imm; 9611 } 9612 9613 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9614 V64, V64, vecshiftL32, 9615 asm, ".2s", ".2s", 9616 [(set (v2i32 V64:$dst), 9617 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9618 (i32 vecshiftL32:$imm)))]> { 9619 bits<5> imm; 9620 let Inst{20-16} = imm; 9621 } 9622 9623 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9624 V128, V128, vecshiftL32, 9625 asm, ".4s", ".4s", 9626 [(set (v4i32 V128:$dst), 9627 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9628 (i32 vecshiftL32:$imm)))]> { 9629 bits<5> imm; 9630 let Inst{20-16} = imm; 9631 } 9632 9633 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9634 V128, V128, vecshiftL64, 9635 asm, ".2d", ".2d", 9636 [(set (v2i64 V128:$dst), 9637 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9638 (i32 vecshiftL64:$imm)))]> { 9639 bits<6> imm; 9640 let Inst{21-16} = imm; 9641 } 9642} 9643 9644multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9645 SDPatternOperator OpNode> { 9646 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9647 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9648 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9649 bits<3> imm; 9650 let Inst{18-16} = imm; 9651 } 9652 9653 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9654 V128, V128, vecshiftL8, 9655 asm#"2", ".8h", ".16b", 9656 [(set (v8i16 V128:$Rd), 9657 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 9658 bits<3> imm; 9659 let Inst{18-16} = imm; 9660 } 9661 9662 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9663 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9664 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9665 bits<4> imm; 9666 let Inst{19-16} = imm; 9667 } 9668 9669 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9670 V128, V128, vecshiftL16, 9671 asm#"2", ".4s", ".8h", 9672 [(set (v4i32 V128:$Rd), 9673 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 9674 9675 bits<4> imm; 9676 let Inst{19-16} = imm; 9677 } 9678 9679 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9680 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9681 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9682 bits<5> imm; 9683 let Inst{20-16} = imm; 9684 } 9685 9686 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9687 V128, V128, vecshiftL32, 9688 asm#"2", ".2d", ".4s", 9689 [(set (v2i64 V128:$Rd), 9690 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9691 bits<5> imm; 9692 let Inst{20-16} = imm; 9693 } 9694} 9695 9696 9697//--- 9698// Vector load/store 9699//--- 9700// SIMD ldX/stX no-index memory references don't allow the optional 9701// ", #0" constant and handle post-indexing explicitly, so we use 9702// a more specialized parse method for them. Otherwise, it's the same as 9703// the general GPR64sp handling. 9704 9705class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9706 string asm, dag oops, dag iops, list<dag> pattern> 9707 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9708 bits<5> Vt; 9709 bits<5> Rn; 9710 let Inst{31} = 0; 9711 let Inst{30} = Q; 9712 let Inst{29-23} = 0b0011000; 9713 let Inst{22} = L; 9714 let Inst{21-16} = 0b000000; 9715 let Inst{15-12} = opcode; 9716 let Inst{11-10} = size; 9717 let Inst{9-5} = Rn; 9718 let Inst{4-0} = Vt; 9719} 9720 9721class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9722 string asm, dag oops, dag iops> 9723 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9724 bits<5> Vt; 9725 bits<5> Rn; 9726 bits<5> Xm; 9727 let Inst{31} = 0; 9728 let Inst{30} = Q; 9729 let Inst{29-23} = 0b0011001; 9730 let Inst{22} = L; 9731 let Inst{21} = 0; 9732 let Inst{20-16} = Xm; 9733 let Inst{15-12} = opcode; 9734 let Inst{11-10} = size; 9735 let Inst{9-5} = Rn; 9736 let Inst{4-0} = Vt; 9737} 9738 9739// The immediate form of AdvSIMD post-indexed addressing is encoded with 9740// register post-index addressing from the zero register. 9741multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9742 int Offset, int Size> { 9743 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9744 // "ld1\t$Vt, [$Rn], #16" 9745 // may get mapped to 9746 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9747 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9748 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9749 GPR64sp:$Rn, 9750 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9751 XZR), 1>; 9752 9753 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9754 // "ld1.8b\t$Vt, [$Rn], #16" 9755 // may get mapped to 9756 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9757 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9758 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9759 GPR64sp:$Rn, 9760 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9761 XZR), 0>; 9762 9763 // E.g. "ld1.8b { v0, v1 }, [x1]" 9764 // "ld1\t$Vt, [$Rn]" 9765 // may get mapped to 9766 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9767 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9768 (!cast<Instruction>(BaseName # Count # "v" # layout) 9769 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9770 GPR64sp:$Rn), 0>; 9771 9772 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9773 // "ld1\t$Vt, [$Rn], $Xm" 9774 // may get mapped to 9775 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9776 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9777 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9778 GPR64sp:$Rn, 9779 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9780 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9781} 9782 9783multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9784 int Offset128, int Offset64, bits<4> opcode> { 9785 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9786 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9787 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9788 (ins GPR64sp:$Rn), []>; 9789 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9790 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9791 (ins GPR64sp:$Rn), []>; 9792 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9793 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9794 (ins GPR64sp:$Rn), []>; 9795 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9796 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9797 (ins GPR64sp:$Rn), []>; 9798 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9799 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9800 (ins GPR64sp:$Rn), []>; 9801 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9802 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9803 (ins GPR64sp:$Rn), []>; 9804 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9805 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9806 (ins GPR64sp:$Rn), []>; 9807 9808 9809 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9810 (outs GPR64sp:$wback, 9811 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9812 (ins GPR64sp:$Rn, 9813 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9814 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9815 (outs GPR64sp:$wback, 9816 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9817 (ins GPR64sp:$Rn, 9818 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9819 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9820 (outs GPR64sp:$wback, 9821 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9822 (ins GPR64sp:$Rn, 9823 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9824 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9825 (outs GPR64sp:$wback, 9826 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9827 (ins GPR64sp:$Rn, 9828 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9829 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9830 (outs GPR64sp:$wback, 9831 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9832 (ins GPR64sp:$Rn, 9833 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9834 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9835 (outs GPR64sp:$wback, 9836 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9837 (ins GPR64sp:$Rn, 9838 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9839 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9840 (outs GPR64sp:$wback, 9841 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9842 (ins GPR64sp:$Rn, 9843 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9844 } 9845 9846 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9847 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9848 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9849 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9850 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9851 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9852 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9853} 9854 9855// Only ld1/st1 has a v1d version. 9856multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9857 int Offset128, int Offset64, bits<4> opcode> { 9858 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9859 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9860 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9861 GPR64sp:$Rn), []>; 9862 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9863 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9864 GPR64sp:$Rn), []>; 9865 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9866 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9867 GPR64sp:$Rn), []>; 9868 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9869 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9870 GPR64sp:$Rn), []>; 9871 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9872 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9873 GPR64sp:$Rn), []>; 9874 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9875 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9876 GPR64sp:$Rn), []>; 9877 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9878 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9879 GPR64sp:$Rn), []>; 9880 9881 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9882 (outs GPR64sp:$wback), 9883 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9884 GPR64sp:$Rn, 9885 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9886 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9887 (outs GPR64sp:$wback), 9888 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9889 GPR64sp:$Rn, 9890 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9891 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9892 (outs GPR64sp:$wback), 9893 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9894 GPR64sp:$Rn, 9895 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9896 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9897 (outs GPR64sp:$wback), 9898 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9899 GPR64sp:$Rn, 9900 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9901 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9902 (outs GPR64sp:$wback), 9903 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9904 GPR64sp:$Rn, 9905 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9906 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9907 (outs GPR64sp:$wback), 9908 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9909 GPR64sp:$Rn, 9910 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9911 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9912 (outs GPR64sp:$wback), 9913 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9914 GPR64sp:$Rn, 9915 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9916 } 9917 9918 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9919 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9920 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9921 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9922 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9923 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9924 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9925} 9926 9927multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9928 int Offset128, int Offset64, bits<4> opcode> 9929 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9930 9931 // LD1 instructions have extra "1d" variants. 9932 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9933 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9934 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9935 (ins GPR64sp:$Rn), []>; 9936 9937 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9938 (outs GPR64sp:$wback, 9939 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9940 (ins GPR64sp:$Rn, 9941 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9942 } 9943 9944 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9945} 9946 9947multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9948 int Offset128, int Offset64, bits<4> opcode> 9949 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9950 9951 // ST1 instructions have extra "1d" variants. 9952 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9953 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9954 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9955 GPR64sp:$Rn), []>; 9956 9957 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9958 (outs GPR64sp:$wback), 9959 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9960 GPR64sp:$Rn, 9961 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9962 } 9963 9964 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9965} 9966 9967multiclass SIMDLd1Multiple<string asm> { 9968 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9969 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9970 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9971 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9972} 9973 9974multiclass SIMDSt1Multiple<string asm> { 9975 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9976 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9977 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9978 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9979} 9980 9981multiclass SIMDLd2Multiple<string asm> { 9982 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9983} 9984 9985multiclass SIMDSt2Multiple<string asm> { 9986 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9987} 9988 9989multiclass SIMDLd3Multiple<string asm> { 9990 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9991} 9992 9993multiclass SIMDSt3Multiple<string asm> { 9994 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9995} 9996 9997multiclass SIMDLd4Multiple<string asm> { 9998 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9999} 10000 10001multiclass SIMDSt4Multiple<string asm> { 10002 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10003} 10004 10005//--- 10006// AdvSIMD Load/store single-element 10007//--- 10008 10009class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10010 string asm, string operands, string cst, 10011 dag oops, dag iops, list<dag> pattern> 10012 : I<oops, iops, asm, operands, cst, pattern> { 10013 bits<5> Vt; 10014 bits<5> Rn; 10015 let Inst{31} = 0; 10016 let Inst{29-24} = 0b001101; 10017 let Inst{22} = L; 10018 let Inst{21} = R; 10019 let Inst{15-13} = opcode; 10020 let Inst{9-5} = Rn; 10021 let Inst{4-0} = Vt; 10022} 10023 10024class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10025 string asm, string operands, string cst, 10026 dag oops, dag iops, list<dag> pattern> 10027 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10028 bits<5> Vt; 10029 bits<5> Rn; 10030 let Inst{31} = 0; 10031 let Inst{29-24} = 0b001101; 10032 let Inst{22} = L; 10033 let Inst{21} = R; 10034 let Inst{15-13} = opcode; 10035 let Inst{9-5} = Rn; 10036 let Inst{4-0} = Vt; 10037} 10038 10039 10040let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10041class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10042 DAGOperand listtype> 10043 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10044 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10045 []> { 10046 let Inst{30} = Q; 10047 let Inst{23} = 0; 10048 let Inst{20-16} = 0b00000; 10049 let Inst{12} = S; 10050 let Inst{11-10} = size; 10051} 10052let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10053class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10054 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10055 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10056 "$Rn = $wback", 10057 (outs GPR64sp:$wback, listtype:$Vt), 10058 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10059 bits<5> Xm; 10060 let Inst{30} = Q; 10061 let Inst{23} = 1; 10062 let Inst{20-16} = Xm; 10063 let Inst{12} = S; 10064 let Inst{11-10} = size; 10065} 10066 10067multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10068 int Offset, int Size> { 10069 // E.g. "ld1r { v0.8b }, [x1], #1" 10070 // "ld1r.8b\t$Vt, [$Rn], #1" 10071 // may get mapped to 10072 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10073 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10074 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10075 GPR64sp:$Rn, 10076 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10077 XZR), 1>; 10078 10079 // E.g. "ld1r.8b { v0 }, [x1], #1" 10080 // "ld1r.8b\t$Vt, [$Rn], #1" 10081 // may get mapped to 10082 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10083 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10084 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10085 GPR64sp:$Rn, 10086 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10087 XZR), 0>; 10088 10089 // E.g. "ld1r.8b { v0 }, [x1]" 10090 // "ld1r.8b\t$Vt, [$Rn]" 10091 // may get mapped to 10092 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10093 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10094 (!cast<Instruction>(BaseName # "v" # layout) 10095 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10096 GPR64sp:$Rn), 0>; 10097 10098 // E.g. "ld1r.8b { v0 }, [x1], x2" 10099 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10100 // may get mapped to 10101 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10102 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10103 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10104 GPR64sp:$Rn, 10105 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10106 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10107} 10108 10109multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10110 int Offset1, int Offset2, int Offset4, int Offset8> { 10111 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10112 !cast<DAGOperand>("VecList" # Count # "8b")>; 10113 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10114 !cast<DAGOperand>("VecList" # Count #"16b")>; 10115 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10116 !cast<DAGOperand>("VecList" # Count #"4h")>; 10117 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10118 !cast<DAGOperand>("VecList" # Count #"8h")>; 10119 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10120 !cast<DAGOperand>("VecList" # Count #"2s")>; 10121 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10122 !cast<DAGOperand>("VecList" # Count #"4s")>; 10123 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10124 !cast<DAGOperand>("VecList" # Count #"1d")>; 10125 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10126 !cast<DAGOperand>("VecList" # Count #"2d")>; 10127 10128 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10129 !cast<DAGOperand>("VecList" # Count # "8b"), 10130 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10131 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10132 !cast<DAGOperand>("VecList" # Count # "16b"), 10133 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10134 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10135 !cast<DAGOperand>("VecList" # Count # "4h"), 10136 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10137 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10138 !cast<DAGOperand>("VecList" # Count # "8h"), 10139 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10140 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10141 !cast<DAGOperand>("VecList" # Count # "2s"), 10142 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10143 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10144 !cast<DAGOperand>("VecList" # Count # "4s"), 10145 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10146 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10147 !cast<DAGOperand>("VecList" # Count # "1d"), 10148 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10149 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10150 !cast<DAGOperand>("VecList" # Count # "2d"), 10151 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10152 10153 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10154 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10155 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10156 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10157 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10158 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10159 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10160 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10161} 10162 10163class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10164 dag oops, dag iops, list<dag> pattern> 10165 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10166 pattern> { 10167 // idx encoded in Q:S:size fields. 10168 bits<4> idx; 10169 let Inst{30} = idx{3}; 10170 let Inst{23} = 0; 10171 let Inst{20-16} = 0b00000; 10172 let Inst{12} = idx{2}; 10173 let Inst{11-10} = idx{1-0}; 10174} 10175class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10176 dag oops, dag iops, list<dag> pattern> 10177 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10178 oops, iops, pattern> { 10179 // idx encoded in Q:S:size fields. 10180 bits<4> idx; 10181 let Inst{30} = idx{3}; 10182 let Inst{23} = 0; 10183 let Inst{20-16} = 0b00000; 10184 let Inst{12} = idx{2}; 10185 let Inst{11-10} = idx{1-0}; 10186} 10187class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10188 dag oops, dag iops> 10189 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10190 "$Rn = $wback", oops, iops, []> { 10191 // idx encoded in Q:S:size fields. 10192 bits<4> idx; 10193 bits<5> Xm; 10194 let Inst{30} = idx{3}; 10195 let Inst{23} = 1; 10196 let Inst{20-16} = Xm; 10197 let Inst{12} = idx{2}; 10198 let Inst{11-10} = idx{1-0}; 10199} 10200class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10201 dag oops, dag iops> 10202 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10203 "$Rn = $wback", oops, iops, []> { 10204 // idx encoded in Q:S:size fields. 10205 bits<4> idx; 10206 bits<5> Xm; 10207 let Inst{30} = idx{3}; 10208 let Inst{23} = 1; 10209 let Inst{20-16} = Xm; 10210 let Inst{12} = idx{2}; 10211 let Inst{11-10} = idx{1-0}; 10212} 10213 10214class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10215 dag oops, dag iops, list<dag> pattern> 10216 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10217 pattern> { 10218 // idx encoded in Q:S:size<1> fields. 10219 bits<3> idx; 10220 let Inst{30} = idx{2}; 10221 let Inst{23} = 0; 10222 let Inst{20-16} = 0b00000; 10223 let Inst{12} = idx{1}; 10224 let Inst{11} = idx{0}; 10225 let Inst{10} = size; 10226} 10227class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10228 dag oops, dag iops, list<dag> pattern> 10229 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10230 oops, iops, pattern> { 10231 // idx encoded in Q:S:size<1> fields. 10232 bits<3> idx; 10233 let Inst{30} = idx{2}; 10234 let Inst{23} = 0; 10235 let Inst{20-16} = 0b00000; 10236 let Inst{12} = idx{1}; 10237 let Inst{11} = idx{0}; 10238 let Inst{10} = size; 10239} 10240 10241class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10242 dag oops, dag iops> 10243 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10244 "$Rn = $wback", oops, iops, []> { 10245 // idx encoded in Q:S:size<1> fields. 10246 bits<3> idx; 10247 bits<5> Xm; 10248 let Inst{30} = idx{2}; 10249 let Inst{23} = 1; 10250 let Inst{20-16} = Xm; 10251 let Inst{12} = idx{1}; 10252 let Inst{11} = idx{0}; 10253 let Inst{10} = size; 10254} 10255class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10256 dag oops, dag iops> 10257 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10258 "$Rn = $wback", oops, iops, []> { 10259 // idx encoded in Q:S:size<1> fields. 10260 bits<3> idx; 10261 bits<5> Xm; 10262 let Inst{30} = idx{2}; 10263 let Inst{23} = 1; 10264 let Inst{20-16} = Xm; 10265 let Inst{12} = idx{1}; 10266 let Inst{11} = idx{0}; 10267 let Inst{10} = size; 10268} 10269class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10270 dag oops, dag iops, list<dag> pattern> 10271 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10272 pattern> { 10273 // idx encoded in Q:S fields. 10274 bits<2> idx; 10275 let Inst{30} = idx{1}; 10276 let Inst{23} = 0; 10277 let Inst{20-16} = 0b00000; 10278 let Inst{12} = idx{0}; 10279 let Inst{11-10} = size; 10280} 10281class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10282 dag oops, dag iops, list<dag> pattern> 10283 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10284 oops, iops, pattern> { 10285 // idx encoded in Q:S fields. 10286 bits<2> idx; 10287 let Inst{30} = idx{1}; 10288 let Inst{23} = 0; 10289 let Inst{20-16} = 0b00000; 10290 let Inst{12} = idx{0}; 10291 let Inst{11-10} = size; 10292} 10293class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10294 string asm, dag oops, dag iops> 10295 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10296 "$Rn = $wback", oops, iops, []> { 10297 // idx encoded in Q:S fields. 10298 bits<2> idx; 10299 bits<5> Xm; 10300 let Inst{30} = idx{1}; 10301 let Inst{23} = 1; 10302 let Inst{20-16} = Xm; 10303 let Inst{12} = idx{0}; 10304 let Inst{11-10} = size; 10305} 10306class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10307 string asm, dag oops, dag iops> 10308 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10309 "$Rn = $wback", oops, iops, []> { 10310 // idx encoded in Q:S fields. 10311 bits<2> idx; 10312 bits<5> Xm; 10313 let Inst{30} = idx{1}; 10314 let Inst{23} = 1; 10315 let Inst{20-16} = Xm; 10316 let Inst{12} = idx{0}; 10317 let Inst{11-10} = size; 10318} 10319class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10320 dag oops, dag iops, list<dag> pattern> 10321 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10322 pattern> { 10323 // idx encoded in Q field. 10324 bits<1> idx; 10325 let Inst{30} = idx; 10326 let Inst{23} = 0; 10327 let Inst{20-16} = 0b00000; 10328 let Inst{12} = 0; 10329 let Inst{11-10} = size; 10330} 10331class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10332 dag oops, dag iops, list<dag> pattern> 10333 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10334 oops, iops, pattern> { 10335 // idx encoded in Q field. 10336 bits<1> idx; 10337 let Inst{30} = idx; 10338 let Inst{23} = 0; 10339 let Inst{20-16} = 0b00000; 10340 let Inst{12} = 0; 10341 let Inst{11-10} = size; 10342} 10343class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10344 string asm, dag oops, dag iops> 10345 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10346 "$Rn = $wback", oops, iops, []> { 10347 // idx encoded in Q field. 10348 bits<1> idx; 10349 bits<5> Xm; 10350 let Inst{30} = idx; 10351 let Inst{23} = 1; 10352 let Inst{20-16} = Xm; 10353 let Inst{12} = 0; 10354 let Inst{11-10} = size; 10355} 10356class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10357 string asm, dag oops, dag iops> 10358 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10359 "$Rn = $wback", oops, iops, []> { 10360 // idx encoded in Q field. 10361 bits<1> idx; 10362 bits<5> Xm; 10363 let Inst{30} = idx; 10364 let Inst{23} = 1; 10365 let Inst{20-16} = Xm; 10366 let Inst{12} = 0; 10367 let Inst{11-10} = size; 10368} 10369 10370let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10371multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10372 RegisterOperand listtype, 10373 RegisterOperand GPR64pi> { 10374 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10375 (outs listtype:$dst), 10376 (ins listtype:$Vt, VectorIndexB:$idx, 10377 GPR64sp:$Rn), []>; 10378 10379 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10380 (outs GPR64sp:$wback, listtype:$dst), 10381 (ins listtype:$Vt, VectorIndexB:$idx, 10382 GPR64sp:$Rn, GPR64pi:$Xm)>; 10383} 10384let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10385multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10386 RegisterOperand listtype, 10387 RegisterOperand GPR64pi> { 10388 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10389 (outs listtype:$dst), 10390 (ins listtype:$Vt, VectorIndexH:$idx, 10391 GPR64sp:$Rn), []>; 10392 10393 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10394 (outs GPR64sp:$wback, listtype:$dst), 10395 (ins listtype:$Vt, VectorIndexH:$idx, 10396 GPR64sp:$Rn, GPR64pi:$Xm)>; 10397} 10398let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10399multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10400 RegisterOperand listtype, 10401 RegisterOperand GPR64pi> { 10402 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10403 (outs listtype:$dst), 10404 (ins listtype:$Vt, VectorIndexS:$idx, 10405 GPR64sp:$Rn), []>; 10406 10407 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10408 (outs GPR64sp:$wback, listtype:$dst), 10409 (ins listtype:$Vt, VectorIndexS:$idx, 10410 GPR64sp:$Rn, GPR64pi:$Xm)>; 10411} 10412let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10413multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10414 RegisterOperand listtype, RegisterOperand GPR64pi> { 10415 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10416 (outs listtype:$dst), 10417 (ins listtype:$Vt, VectorIndexD:$idx, 10418 GPR64sp:$Rn), []>; 10419 10420 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10421 (outs GPR64sp:$wback, listtype:$dst), 10422 (ins listtype:$Vt, VectorIndexD:$idx, 10423 GPR64sp:$Rn, GPR64pi:$Xm)>; 10424} 10425let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10426multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10427 RegisterOperand listtype, RegisterOperand GPR64pi> { 10428 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10429 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10430 GPR64sp:$Rn), []>; 10431 10432 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10433 (outs GPR64sp:$wback), 10434 (ins listtype:$Vt, VectorIndexB:$idx, 10435 GPR64sp:$Rn, GPR64pi:$Xm)>; 10436} 10437let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10438multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10439 RegisterOperand listtype, RegisterOperand GPR64pi> { 10440 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10441 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10442 GPR64sp:$Rn), []>; 10443 10444 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10445 (outs GPR64sp:$wback), 10446 (ins listtype:$Vt, VectorIndexH:$idx, 10447 GPR64sp:$Rn, GPR64pi:$Xm)>; 10448} 10449let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10450multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10451 RegisterOperand listtype, RegisterOperand GPR64pi> { 10452 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10453 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10454 GPR64sp:$Rn), []>; 10455 10456 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10457 (outs GPR64sp:$wback), 10458 (ins listtype:$Vt, VectorIndexS:$idx, 10459 GPR64sp:$Rn, GPR64pi:$Xm)>; 10460} 10461let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10462multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10463 RegisterOperand listtype, RegisterOperand GPR64pi> { 10464 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10465 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10466 GPR64sp:$Rn), []>; 10467 10468 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10469 (outs GPR64sp:$wback), 10470 (ins listtype:$Vt, VectorIndexD:$idx, 10471 GPR64sp:$Rn, GPR64pi:$Xm)>; 10472} 10473 10474multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10475 string Count, int Offset, Operand idxtype> { 10476 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10477 // "ld1\t$Vt, [$Rn], #1" 10478 // may get mapped to 10479 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10480 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10481 (!cast<Instruction>(NAME # Type # "_POST") 10482 GPR64sp:$Rn, 10483 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10484 idxtype:$idx, XZR), 1>; 10485 10486 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10487 // "ld1.8b\t$Vt, [$Rn], #1" 10488 // may get mapped to 10489 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10490 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10491 (!cast<Instruction>(NAME # Type # "_POST") 10492 GPR64sp:$Rn, 10493 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10494 idxtype:$idx, XZR), 0>; 10495 10496 // E.g. "ld1.8b { v0 }[0], [x1]" 10497 // "ld1.8b\t$Vt, [$Rn]" 10498 // may get mapped to 10499 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10500 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10501 (!cast<Instruction>(NAME # Type) 10502 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10503 idxtype:$idx, GPR64sp:$Rn), 0>; 10504 10505 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10506 // "ld1.8b\t$Vt, [$Rn], $Xm" 10507 // may get mapped to 10508 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10509 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10510 (!cast<Instruction>(NAME # Type # "_POST") 10511 GPR64sp:$Rn, 10512 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10513 idxtype:$idx, 10514 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10515} 10516 10517multiclass SIMDLdSt1SingleAliases<string asm> { 10518 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10519 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10520 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10521 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10522} 10523 10524multiclass SIMDLdSt2SingleAliases<string asm> { 10525 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10526 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10527 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10528 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10529} 10530 10531multiclass SIMDLdSt3SingleAliases<string asm> { 10532 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10533 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10534 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10535 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10536} 10537 10538multiclass SIMDLdSt4SingleAliases<string asm> { 10539 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10540 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10541 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10542 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10543} 10544} // end of 'let Predicates = [HasNEON]' 10545 10546//---------------------------------------------------------------------------- 10547// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10548//---------------------------------------------------------------------------- 10549 10550let Predicates = [HasNEON, HasRDM] in { 10551 10552class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10553 RegisterOperand regtype, string asm, 10554 string kind, list<dag> pattern> 10555 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10556 pattern> { 10557} 10558multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10559 SDPatternOperator op> { 10560 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10561 [(set (v4i16 V64:$dst), 10562 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 10563 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10564 [(set (v8i16 V128:$dst), 10565 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 10566 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10567 [(set (v2i32 V64:$dst), 10568 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 10569 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10570 [(set (v4i32 V128:$dst), 10571 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 10572} 10573 10574multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10575 SDPatternOperator op> { 10576 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10577 V64, V64, V128_lo, VectorIndexH, 10578 asm, ".4h", ".4h", ".4h", ".h", 10579 [(set (v4i16 V64:$dst), 10580 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10581 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10582 VectorIndexH:$idx)))))]> { 10583 bits<3> idx; 10584 let Inst{11} = idx{2}; 10585 let Inst{21} = idx{1}; 10586 let Inst{20} = idx{0}; 10587 } 10588 10589 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10590 V128, V128, V128_lo, VectorIndexH, 10591 asm, ".8h", ".8h", ".8h", ".h", 10592 [(set (v8i16 V128:$dst), 10593 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10594 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10595 VectorIndexH:$idx)))))]> { 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 v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10603 V64, V64, V128, VectorIndexS, 10604 asm, ".2s", ".2s", ".2s", ".s", 10605 [(set (v2i32 V64:$dst), 10606 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10607 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10608 VectorIndexS:$idx)))))]> { 10609 bits<2> idx; 10610 let Inst{11} = idx{1}; 10611 let Inst{21} = idx{0}; 10612 } 10613 10614 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10615 V128, V128, V128, VectorIndexS, 10616 asm, ".4s", ".4s", ".4s", ".s", 10617 [(set (v4i32 V128:$dst), 10618 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10619 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10620 VectorIndexS:$idx)))))]> { 10621 bits<2> idx; 10622 let Inst{11} = idx{1}; 10623 let Inst{21} = idx{0}; 10624 } 10625 10626 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10627 FPR16Op, FPR16Op, V128_lo, 10628 VectorIndexH, asm, ".h", "", "", ".h", 10629 []> { 10630 bits<3> idx; 10631 let Inst{11} = idx{2}; 10632 let Inst{21} = idx{1}; 10633 let Inst{20} = idx{0}; 10634 } 10635 10636 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10637 FPR32Op, FPR32Op, V128, VectorIndexS, 10638 asm, ".s", "", "", ".s", 10639 [(set (i32 FPR32Op:$dst), 10640 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 10641 (i32 (vector_extract (v4i32 V128:$Rm), 10642 VectorIndexS:$idx)))))]> { 10643 bits<2> idx; 10644 let Inst{11} = idx{1}; 10645 let Inst{21} = idx{0}; 10646 } 10647} 10648} // let Predicates = [HasNeon, HasRDM] 10649 10650//---------------------------------------------------------------------------- 10651// ARMv8.3 Complex ADD/MLA instructions 10652//---------------------------------------------------------------------------- 10653 10654class ComplexRotationOperand<int Angle, int Remainder, string Type> 10655 : AsmOperandClass { 10656 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10657 let DiagnosticType = "InvalidComplexRotation" # Type; 10658 let Name = "ComplexRotation" # Type; 10659} 10660def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10661 SDNodeXForm<imm, [{ 10662 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10663}]>> { 10664 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10665 let PrintMethod = "printComplexRotationOp<90, 0>"; 10666} 10667def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10668 SDNodeXForm<imm, [{ 10669 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10670}]>> { 10671 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10672 let PrintMethod = "printComplexRotationOp<180, 90>"; 10673} 10674let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10675class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10676 RegisterOperand regtype, Operand rottype, 10677 string asm, string kind, list<dag> pattern> 10678 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10679 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10680 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10681 Sched<[!if(Q, WriteVq, WriteVd)]> { 10682 bits<5> Rd; 10683 bits<5> Rn; 10684 bits<5> Rm; 10685 bits<1> rot; 10686 let Inst{31} = 0; 10687 let Inst{30} = Q; 10688 let Inst{29} = U; 10689 let Inst{28-24} = 0b01110; 10690 let Inst{23-22} = size; 10691 let Inst{21} = 0; 10692 let Inst{20-16} = Rm; 10693 let Inst{15-13} = opcode; 10694 // Non-tied version (FCADD) only has one rotation bit 10695 let Inst{12} = rot; 10696 let Inst{11} = 0; 10697 let Inst{10} = 1; 10698 let Inst{9-5} = Rn; 10699 let Inst{4-0} = Rd; 10700} 10701 10702//8.3 CompNum - Floating-point complex number support 10703multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10704 string asm, SDPatternOperator OpNode>{ 10705 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10706 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10707 asm, ".4h", 10708 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10709 (v4f16 V64:$Rn), 10710 (v4f16 V64:$Rm), 10711 (i32 rottype:$rot)))]>; 10712 10713 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10714 asm, ".8h", 10715 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10716 (v8f16 V128:$Rn), 10717 (v8f16 V128:$Rm), 10718 (i32 rottype:$rot)))]>; 10719 } 10720 10721 let Predicates = [HasComplxNum, HasNEON] in { 10722 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10723 asm, ".2s", 10724 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10725 (v2f32 V64:$Rn), 10726 (v2f32 V64:$Rm), 10727 (i32 rottype:$rot)))]>; 10728 10729 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10730 asm, ".4s", 10731 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10732 (v4f32 V128:$Rn), 10733 (v4f32 V128:$Rm), 10734 (i32 rottype:$rot)))]>; 10735 10736 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10737 asm, ".2d", 10738 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10739 (v2f64 V128:$Rn), 10740 (v2f64 V128:$Rm), 10741 (i32 rottype:$rot)))]>; 10742 } 10743} 10744 10745let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10746class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10747 bits<3> opcode, 10748 RegisterOperand regtype, 10749 Operand rottype, string asm, 10750 string kind, list<dag> pattern> 10751 : I<(outs regtype:$dst), 10752 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10753 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10754 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10755 Sched<[!if(Q, WriteVq, WriteVd)]> { 10756 bits<5> Rd; 10757 bits<5> Rn; 10758 bits<5> Rm; 10759 bits<2> rot; 10760 let Inst{31} = 0; 10761 let Inst{30} = Q; 10762 let Inst{29} = U; 10763 let Inst{28-24} = 0b01110; 10764 let Inst{23-22} = size; 10765 let Inst{21} = 0; 10766 let Inst{20-16} = Rm; 10767 let Inst{15-13} = opcode; 10768 let Inst{12-11} = rot; 10769 let Inst{10} = 1; 10770 let Inst{9-5} = Rn; 10771 let Inst{4-0} = Rd; 10772} 10773 10774multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10775 Operand rottype, string asm, 10776 SDPatternOperator OpNode> { 10777 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10778 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10779 rottype, asm, ".4h", 10780 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10781 (v4f16 V64:$Rn), 10782 (v4f16 V64:$Rm), 10783 (i32 rottype:$rot)))]>; 10784 10785 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10786 rottype, asm, ".8h", 10787 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10788 (v8f16 V128:$Rn), 10789 (v8f16 V128:$Rm), 10790 (i32 rottype:$rot)))]>; 10791 } 10792 10793 let Predicates = [HasComplxNum, HasNEON] in { 10794 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10795 rottype, asm, ".2s", 10796 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10797 (v2f32 V64:$Rn), 10798 (v2f32 V64:$Rm), 10799 (i32 rottype:$rot)))]>; 10800 10801 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10802 rottype, asm, ".4s", 10803 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10804 (v4f32 V128:$Rn), 10805 (v4f32 V128:$Rm), 10806 (i32 rottype:$rot)))]>; 10807 10808 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10809 rottype, asm, ".2d", 10810 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10811 (v2f64 V128:$Rn), 10812 (v2f64 V128:$Rm), 10813 (i32 rottype:$rot)))]>; 10814 } 10815} 10816 10817let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10818class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10819 bit opc1, bit opc2, RegisterOperand dst_reg, 10820 RegisterOperand lhs_reg, 10821 RegisterOperand rhs_reg, Operand vec_idx, 10822 Operand rottype, string asm, string apple_kind, 10823 string dst_kind, string lhs_kind, 10824 string rhs_kind, list<dag> pattern> 10825 : I<(outs dst_reg:$dst), 10826 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10827 asm, 10828 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10829 "$idx, $rot" # "|" # apple_kind # 10830 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10831 Sched<[!if(Q, WriteVq, WriteVd)]> { 10832 bits<5> Rd; 10833 bits<5> Rn; 10834 bits<5> Rm; 10835 bits<2> rot; 10836 10837 let Inst{31} = 0; 10838 let Inst{30} = Q; 10839 let Inst{29} = U; 10840 let Inst{28} = Scalar; 10841 let Inst{27-24} = 0b1111; 10842 let Inst{23-22} = size; 10843 // Bit 21 must be set by the derived class. 10844 let Inst{20-16} = Rm; 10845 let Inst{15} = opc1; 10846 let Inst{14-13} = rot; 10847 let Inst{12} = opc2; 10848 // Bit 11 must be set by the derived class. 10849 let Inst{10} = 0; 10850 let Inst{9-5} = Rn; 10851 let Inst{4-0} = Rd; 10852} 10853 10854// The complex instructions index by pairs of elements, so the VectorIndexes 10855// don't match the lane types, and the index bits are different to the other 10856// classes. 10857multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 10858 string asm> { 10859 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10860 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10861 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10862 ".4h", ".h", []> { 10863 bits<1> idx; 10864 let Inst{11} = 0; 10865 let Inst{21} = idx{0}; 10866 } 10867 10868 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10869 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10870 ".8h", ".8h", ".h", []> { 10871 bits<2> idx; 10872 let Inst{11} = idx{1}; 10873 let Inst{21} = idx{0}; 10874 } 10875 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10876 10877 let Predicates = [HasComplxNum, HasNEON] in { 10878 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10879 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10880 ".4s", ".4s", ".s", []> { 10881 bits<1> idx; 10882 let Inst{11} = idx{0}; 10883 let Inst{21} = 0; 10884 } 10885 } // Predicates = [HasComplxNum, HasNEON] 10886} 10887 10888//---------------------------------------------------------------------------- 10889// Crypto extensions 10890//---------------------------------------------------------------------------- 10891 10892let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10893class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10894 list<dag> pat> 10895 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10896 Sched<[WriteVq]>{ 10897 bits<5> Rd; 10898 bits<5> Rn; 10899 let Inst{31-16} = 0b0100111000101000; 10900 let Inst{15-12} = opc; 10901 let Inst{11-10} = 0b10; 10902 let Inst{9-5} = Rn; 10903 let Inst{4-0} = Rd; 10904} 10905 10906class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10907 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10908 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10909 10910class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10911 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10912 "$Rd = $dst", 10913 [(set (v16i8 V128:$dst), 10914 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10915 10916let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10917class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10918 dag oops, dag iops, list<dag> pat> 10919 : I<oops, iops, asm, 10920 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10921 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10922 Sched<[WriteVq]>{ 10923 bits<5> Rd; 10924 bits<5> Rn; 10925 bits<5> Rm; 10926 let Inst{31-21} = 0b01011110000; 10927 let Inst{20-16} = Rm; 10928 let Inst{15} = 0; 10929 let Inst{14-12} = opc; 10930 let Inst{11-10} = 0b00; 10931 let Inst{9-5} = Rn; 10932 let Inst{4-0} = Rd; 10933} 10934 10935class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10936 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10937 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10938 [(set (v4i32 FPR128:$dst), 10939 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10940 (v4i32 V128:$Rm)))]>; 10941 10942class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10943 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10944 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10945 [(set (v4i32 V128:$dst), 10946 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10947 (v4i32 V128:$Rm)))]>; 10948 10949class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10950 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10951 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10952 [(set (v4i32 FPR128:$dst), 10953 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10954 (v4i32 V128:$Rm)))]>; 10955 10956let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10957class SHA2OpInst<bits<4> opc, string asm, string kind, 10958 string cstr, dag oops, dag iops, 10959 list<dag> pat> 10960 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10961 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10962 Sched<[WriteVq]>{ 10963 bits<5> Rd; 10964 bits<5> Rn; 10965 let Inst{31-16} = 0b0101111000101000; 10966 let Inst{15-12} = opc; 10967 let Inst{11-10} = 0b10; 10968 let Inst{9-5} = Rn; 10969 let Inst{4-0} = Rd; 10970} 10971 10972class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10973 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10974 (ins V128:$Rd, V128:$Rn), 10975 [(set (v4i32 V128:$dst), 10976 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10977 10978class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10979 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10980 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10981 10982// Armv8.2-A Crypto extensions 10983class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10984 list<dag> pattern> 10985 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 10986 bits<5> Vd; 10987 bits<5> Vn; 10988 let Inst{31-25} = 0b1100111; 10989 let Inst{9-5} = Vn; 10990 let Inst{4-0} = Vd; 10991} 10992 10993class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10994 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 10995 "$Vd = $Vdst", []> { 10996 let Inst{31-25} = 0b1100111; 10997 let Inst{24-21} = 0b0110; 10998 let Inst{20-15} = 0b000001; 10999 let Inst{14} = op0; 11000 let Inst{13-12} = 0b00; 11001 let Inst{11-10} = op1; 11002} 11003class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11004 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11005class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11006 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11007 11008class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11009 string asmops, string cst> 11010 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11011 bits<5> Vm; 11012 let Inst{24-21} = 0b0011; 11013 let Inst{20-16} = Vm; 11014 let Inst{15} = 0b1; 11015 let Inst{14} = op0; 11016 let Inst{13-12} = 0b00; 11017 let Inst{11-10} = op1; 11018} 11019class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11020 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11021 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11022class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11023 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11024 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11025class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11026 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11027 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11028class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11029 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11030 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11031class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11032 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11033 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11034 11035class CryptoRRRR<bits<2>op0, string asm, string asmops> 11036 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11037 asmops, "", []> { 11038 bits<5> Vm; 11039 bits<5> Va; 11040 let Inst{24-23} = 0b00; 11041 let Inst{22-21} = op0; 11042 let Inst{20-16} = Vm; 11043 let Inst{15} = 0b0; 11044 let Inst{14-10} = Va; 11045} 11046class CryptoRRRR_16B<bits<2>op0, string asm> 11047 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11048 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11049} 11050class CryptoRRRR_4S<bits<2>op0, string asm> 11051 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11052 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11053} 11054 11055class CryptoRRRi6<string asm> 11056 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11057 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11058 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11059 bits<6> imm; 11060 bits<5> Vm; 11061 let Inst{24-21} = 0b0100; 11062 let Inst{20-16} = Vm; 11063 let Inst{15-10} = imm; 11064 let Inst{9-5} = Vn; 11065 let Inst{4-0} = Vd; 11066} 11067 11068class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11069 : BaseCryptoV82<(outs V128:$Vdst), 11070 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11071 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11072 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11073 bits<2> imm; 11074 bits<5> Vm; 11075 let Inst{24-21} = 0b0010; 11076 let Inst{20-16} = Vm; 11077 let Inst{15} = 0b1; 11078 let Inst{14} = op0; 11079 let Inst{13-12} = imm; 11080 let Inst{11-10} = op1; 11081} 11082 11083//---------------------------------------------------------------------------- 11084// v8.1 atomic instructions extension: 11085// * CAS 11086// * CASP 11087// * SWP 11088// * LDOPregister<OP>, and aliases STOPregister<OP> 11089 11090// Instruction encodings: 11091// 11092// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11093// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11094// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11095// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11096// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11097// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11098 11099// Instruction syntax: 11100// 11101// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11102// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11103// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11104// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11105// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11106// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11107// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11108// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11109// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11110// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11111 11112let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11113class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11114 string cstr, list<dag> pattern> 11115 : I<oops, iops, asm, operands, cstr, pattern> { 11116 bits<2> Sz; 11117 bit NP; 11118 bit Acq; 11119 bit Rel; 11120 bits<5> Rs; 11121 bits<5> Rn; 11122 bits<5> Rt; 11123 let Inst{31-30} = Sz; 11124 let Inst{29-24} = 0b001000; 11125 let Inst{23} = NP; 11126 let Inst{22} = Acq; 11127 let Inst{21} = 0b1; 11128 let Inst{20-16} = Rs; 11129 let Inst{15} = Rel; 11130 let Inst{14-10} = 0b11111; 11131 let Inst{9-5} = Rn; 11132 let Inst{4-0} = Rt; 11133 let Predicates = [HasLSE]; 11134} 11135 11136class BaseCAS<string order, string size, RegisterClass RC> 11137 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11138 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11139 "$out = $Rs",[]>, 11140 Sched<[WriteAtomic]> { 11141 let NP = 1; 11142} 11143 11144multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11145 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11146 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11147 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11148 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11149} 11150 11151class BaseCASP<string order, string size, RegisterOperand RC> 11152 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11153 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11154 "$out = $Rs",[]>, 11155 Sched<[WriteAtomic]> { 11156 let NP = 0; 11157} 11158 11159multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11160 let Sz = 0b00, Acq = Acq, Rel = Rel in 11161 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11162 let Sz = 0b01, Acq = Acq, Rel = Rel in 11163 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11164} 11165 11166let Predicates = [HasLSE] in 11167class BaseSWP<string order, string size, RegisterClass RC> 11168 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11169 "\t$Rs, $Rt, [$Rn]","",[]>, 11170 Sched<[WriteAtomic]> { 11171 bits<2> Sz; 11172 bit Acq; 11173 bit Rel; 11174 bits<5> Rs; 11175 bits<3> opc = 0b000; 11176 bits<5> Rn; 11177 bits<5> Rt; 11178 let Inst{31-30} = Sz; 11179 let Inst{29-24} = 0b111000; 11180 let Inst{23} = Acq; 11181 let Inst{22} = Rel; 11182 let Inst{21} = 0b1; 11183 let Inst{20-16} = Rs; 11184 let Inst{15} = 0b1; 11185 let Inst{14-12} = opc; 11186 let Inst{11-10} = 0b00; 11187 let Inst{9-5} = Rn; 11188 let Inst{4-0} = Rt; 11189 let Predicates = [HasLSE]; 11190} 11191 11192multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11193 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11194 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11195 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11196 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11197} 11198 11199let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11200class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11201 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11202 "\t$Rs, $Rt, [$Rn]","",[]>, 11203 Sched<[WriteAtomic]> { 11204 bits<2> Sz; 11205 bit Acq; 11206 bit Rel; 11207 bits<5> Rs; 11208 bits<3> opc; 11209 bits<5> Rn; 11210 bits<5> Rt; 11211 let Inst{31-30} = Sz; 11212 let Inst{29-24} = 0b111000; 11213 let Inst{23} = Acq; 11214 let Inst{22} = Rel; 11215 let Inst{21} = 0b1; 11216 let Inst{20-16} = Rs; 11217 let Inst{15} = 0b0; 11218 let Inst{14-12} = opc; 11219 let Inst{11-10} = 0b00; 11220 let Inst{9-5} = Rn; 11221 let Inst{4-0} = Rt; 11222 let Predicates = [HasLSE]; 11223} 11224 11225multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11226 string order> { 11227 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11228 def B : BaseLDOPregister<op, order, "b", GPR32>; 11229 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11230 def H : BaseLDOPregister<op, order, "h", GPR32>; 11231 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11232 def W : BaseLDOPregister<op, order, "", GPR32>; 11233 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11234 def X : BaseLDOPregister<op, order, "", GPR64>; 11235} 11236 11237// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11238// complex DAG for DstRHS. 11239let Predicates = [HasLSE] in 11240multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11241 string size, dag SrcRHS, dag DstRHS> { 11242 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11243 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11244 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11245 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11246 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11247 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11248 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11249 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11250 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11251 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11252} 11253 11254multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11255 string size, dag RHS> { 11256 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11257} 11258 11259multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11260 string size, dag LHS, dag RHS> { 11261 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11262} 11263 11264multiclass LDOPregister_patterns<string inst, string op> { 11265 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11266 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11267 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11268 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11269} 11270 11271multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11272 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11273 (i64 GPR64:$Rm), 11274 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11275 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11276 (i32 GPR32:$Rm), 11277 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11278 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11279 (i32 GPR32:$Rm), 11280 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11281 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11282 (i32 GPR32:$Rm), 11283 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11284} 11285 11286let Predicates = [HasLSE] in 11287multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11288 string size, dag OLD, dag NEW> { 11289 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11290 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11291 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11292 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11293 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11294 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11295 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11296 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11297 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11298 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11299} 11300 11301multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11302 string size, dag OLD, dag NEW> { 11303 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11304} 11305 11306multiclass CASregister_patterns<string inst, string op> { 11307 defm : CASregister_patterns_ord<inst, "X", op, "64", 11308 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11309 defm : CASregister_patterns_ord<inst, "W", op, "32", 11310 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11311 defm : CASregister_patterns_ord<inst, "H", op, "16", 11312 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11313 defm : CASregister_patterns_ord<inst, "B", op, "8", 11314 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11315} 11316 11317let Predicates = [HasLSE] in 11318class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11319 Instruction inst> : 11320 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11321 11322multiclass STOPregister<string asm, string instr> { 11323 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11324 !cast<Instruction>(instr # "LB")>; 11325 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11326 !cast<Instruction>(instr # "LH")>; 11327 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11328 !cast<Instruction>(instr # "LW")>; 11329 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11330 !cast<Instruction>(instr # "LX")>; 11331 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11332 !cast<Instruction>(instr # "B")>; 11333 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11334 !cast<Instruction>(instr # "H")>; 11335 def : BaseSTOPregister<asm, GPR32, WZR, 11336 !cast<Instruction>(instr # "W")>; 11337 def : BaseSTOPregister<asm, GPR64, XZR, 11338 !cast<Instruction>(instr # "X")>; 11339} 11340 11341class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11342 dag iops, dag oops, list<dag> pat> 11343 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11344 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11345 bits<5> Rt; 11346 bits<5> Rn; 11347 let Inst{31-21} = 0b11111000001; 11348 let Inst{15} = 1; 11349 let Inst{14-12} = opc; 11350 let Inst{11-10} = 0b00; 11351 let Inst{9-5} = Rn; 11352 let Inst{4-0} = Rt; 11353 11354 let Predicates = [HasV8_7a]; 11355} 11356 11357class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11358 list<dag> pat = []> 11359 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11360 let Inst{20-16} = 0b11111; 11361} 11362 11363class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11364 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11365 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11366 bits<5> Rs; 11367 let Inst{20-16} = Rs; 11368} 11369 11370class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 11371 bits<2> op2, string asm> 11372 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 11373 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 11374 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 11375 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 11376 Sched<[]> { 11377 bits<5> Rd; 11378 bits<5> Rs; 11379 bits<5> Rn; 11380 let Inst{31-27} = 0b00011; 11381 let Inst{26} = isMove; 11382 let Inst{25-24} = 0b01; 11383 let Inst{23-22} = opcode; 11384 let Inst{21} = 0b0; 11385 let Inst{20-16} = Rs; 11386 let Inst{15-14} = op2; 11387 let Inst{13-12} = op1; 11388 let Inst{11-10} = 0b01; 11389 let Inst{9-5} = Rn; 11390 let Inst{4-0} = Rd; 11391 11392 let DecoderMethod = "DecodeCPYMemOpInstruction"; 11393 let mayLoad = 1; 11394 let mayStore = 1; 11395} 11396 11397class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11398 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 11399 11400class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11401 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 11402 11403class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 11404 string asm> 11405 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 11406 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 11407 asm, "\t[$Rd]!, $Rn!, $Rm", 11408 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 11409 Sched<[]> { 11410 bits<5> Rd; 11411 bits<5> Rn; 11412 bits<5> Rm; 11413 let Inst{31-27} = 0b00011; 11414 let Inst{26} = isTagging; 11415 let Inst{25-21} = 0b01110; 11416 let Inst{20-16} = Rm; 11417 let Inst{15-14} = opcode; 11418 let Inst{13} = op2; 11419 let Inst{12} = op1; 11420 let Inst{11-10} = 0b01; 11421 let Inst{9-5} = Rn; 11422 let Inst{4-0} = Rd; 11423 11424 let DecoderMethod = "DecodeSETMemOpInstruction"; 11425 let mayLoad = 0; 11426 let mayStore = 1; 11427} 11428 11429class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 11430 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 11431 11432class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 11433 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 11434 11435multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 11436 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 11437 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 11438 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 11439 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 11440 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 11441 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 11442 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 11443 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 11444 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 11445 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 11446 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 11447 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 11448 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 11449 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 11450 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 11451 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 11452} 11453 11454multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 11455 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 11456 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 11457 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 11458 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 11459 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 11460 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 11461 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 11462 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 11463 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 11464 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 11465 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 11466 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 11467 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 11468 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 11469 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 11470 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 11471} 11472 11473multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 11474 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 11475 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 11476 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 11477 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 11478} 11479 11480multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 11481 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 11482 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 11483 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 11484 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 11485} 11486 11487//---------------------------------------------------------------------------- 11488// Allow the size specifier tokens to be upper case, not just lower. 11489def : TokenAlias<".4B", ".4b">; // Add dot product 11490def : TokenAlias<".8B", ".8b">; 11491def : TokenAlias<".4H", ".4h">; 11492def : TokenAlias<".2S", ".2s">; 11493def : TokenAlias<".1D", ".1d">; 11494def : TokenAlias<".16B", ".16b">; 11495def : TokenAlias<".8H", ".8h">; 11496def : TokenAlias<".4S", ".4s">; 11497def : TokenAlias<".2D", ".2d">; 11498def : TokenAlias<".1Q", ".1q">; 11499def : TokenAlias<".2H", ".2h">; 11500def : TokenAlias<".B", ".b">; 11501def : TokenAlias<".H", ".h">; 11502def : TokenAlias<".S", ".s">; 11503def : TokenAlias<".D", ".d">; 11504def : TokenAlias<".Q", ".q">; 11505