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// AArch64 Instruction Format 24class AArch64Inst<Format f, string cstr> : Instruction { 25 field bits<32> Inst; // Instruction encoding. 26 // Mask of bits that cause an encoding to be UNPREDICTABLE. 27 // If a bit is set, then if the corresponding bit in the 28 // target encoding differs from its value in the "Inst" field, 29 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 30 field bits<32> Unpredictable = 0; 31 // SoftFail is the generic name for this field, but we alias it so 32 // as to make it more obvious what it means in ARM-land. 33 field bits<32> SoftFail = Unpredictable; 34 let Namespace = "AArch64"; 35 Format F = f; 36 bits<2> Form = F.Value; 37 let Pattern = []; 38 let Constraints = cstr; 39} 40 41class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 42 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 43 44// Pseudo instructions (don't have encoding information) 45class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 46 : AArch64Inst<PseudoFrm, cstr> { 47 dag OutOperandList = oops; 48 dag InOperandList = iops; 49 let Pattern = pattern; 50 let isCodeGenOnly = 1; 51} 52 53// Real instructions (have encoding information) 54class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 55 let Pattern = pattern; 56 let Size = 4; 57} 58 59// Enum describing whether an instruction is 60// destructive in its first source operand. 61class DestructiveInstTypeEnum<bits<1> val> { 62 bits<1> Value = val; 63} 64def NotDestructive : DestructiveInstTypeEnum<0>; 65def Destructive : DestructiveInstTypeEnum<1>; 66 67// Normal instructions 68class I<dag oops, dag iops, string asm, string operands, string cstr, 69 list<dag> pattern> 70 : EncodedI<cstr, pattern> { 71 dag OutOperandList = oops; 72 dag InOperandList = iops; 73 let AsmString = !strconcat(asm, operands); 74 75 // Destructive operations (SVE) 76 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 77 ElementSizeEnum ElementSize = ElementSizeB; 78 79 let TSFlags{3} = DestructiveInstType.Value; 80 let TSFlags{2-0} = ElementSize.Value; 81} 82 83class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 84class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 85class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 86 87// Helper fragment for an extract of the high portion of a 128-bit vector. 88def extract_high_v16i8 : 89 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>; 90def extract_high_v8i16 : 91 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>; 92def extract_high_v4i32 : 93 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>; 94def extract_high_v2i64 : 95 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>; 96 97//===----------------------------------------------------------------------===// 98// Asm Operand Classes. 99// 100 101// Shifter operand for arithmetic shifted encodings. 102def ShifterOperand : AsmOperandClass { 103 let Name = "Shifter"; 104} 105 106// Shifter operand for mov immediate encodings. 107def MovImm32ShifterOperand : AsmOperandClass { 108 let SuperClasses = [ShifterOperand]; 109 let Name = "MovImm32Shifter"; 110 let RenderMethod = "addShifterOperands"; 111 let DiagnosticType = "InvalidMovImm32Shift"; 112} 113def MovImm64ShifterOperand : AsmOperandClass { 114 let SuperClasses = [ShifterOperand]; 115 let Name = "MovImm64Shifter"; 116 let RenderMethod = "addShifterOperands"; 117 let DiagnosticType = "InvalidMovImm64Shift"; 118} 119 120// Shifter operand for arithmetic register shifted encodings. 121class ArithmeticShifterOperand<int width> : AsmOperandClass { 122 let SuperClasses = [ShifterOperand]; 123 let Name = "ArithmeticShifter" # width; 124 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 125 let RenderMethod = "addShifterOperands"; 126 let DiagnosticType = "AddSubRegShift" # width; 127} 128 129def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 130def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 131 132// Shifter operand for logical register shifted encodings. 133class LogicalShifterOperand<int width> : AsmOperandClass { 134 let SuperClasses = [ShifterOperand]; 135 let Name = "LogicalShifter" # width; 136 let PredicateMethod = "isLogicalShifter<" # width # ">"; 137 let RenderMethod = "addShifterOperands"; 138 let DiagnosticType = "AddSubRegShift" # width; 139} 140 141def LogicalShifterOperand32 : LogicalShifterOperand<32>; 142def LogicalShifterOperand64 : LogicalShifterOperand<64>; 143 144// Shifter operand for logical vector 128/64-bit shifted encodings. 145def LogicalVecShifterOperand : AsmOperandClass { 146 let SuperClasses = [ShifterOperand]; 147 let Name = "LogicalVecShifter"; 148 let RenderMethod = "addShifterOperands"; 149} 150def LogicalVecHalfWordShifterOperand : AsmOperandClass { 151 let SuperClasses = [LogicalVecShifterOperand]; 152 let Name = "LogicalVecHalfWordShifter"; 153 let RenderMethod = "addShifterOperands"; 154} 155 156// The "MSL" shifter on the vector MOVI instruction. 157def MoveVecShifterOperand : AsmOperandClass { 158 let SuperClasses = [ShifterOperand]; 159 let Name = "MoveVecShifter"; 160 let RenderMethod = "addShifterOperands"; 161} 162 163// Extend operand for arithmetic encodings. 164def ExtendOperand : AsmOperandClass { 165 let Name = "Extend"; 166 let DiagnosticType = "AddSubRegExtendLarge"; 167} 168def ExtendOperand64 : AsmOperandClass { 169 let SuperClasses = [ExtendOperand]; 170 let Name = "Extend64"; 171 let DiagnosticType = "AddSubRegExtendSmall"; 172} 173// 'extend' that's a lsl of a 64-bit register. 174def ExtendOperandLSL64 : AsmOperandClass { 175 let SuperClasses = [ExtendOperand]; 176 let Name = "ExtendLSL64"; 177 let RenderMethod = "addExtend64Operands"; 178 let DiagnosticType = "AddSubRegExtendLarge"; 179} 180 181// 8-bit floating-point immediate encodings. 182def FPImmOperand : AsmOperandClass { 183 let Name = "FPImm"; 184 let ParserMethod = "tryParseFPImm<true>"; 185 let DiagnosticType = "InvalidFPImm"; 186} 187 188def CondCode : AsmOperandClass { 189 let Name = "CondCode"; 190 let DiagnosticType = "InvalidCondCode"; 191} 192 193// A 32-bit register pasrsed as 64-bit 194def GPR32as64Operand : AsmOperandClass { 195 let Name = "GPR32as64"; 196 let ParserMethod = 197 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 198} 199def GPR32as64 : RegisterOperand<GPR32> { 200 let ParserMatchClass = GPR32as64Operand; 201} 202 203// A 64-bit register pasrsed as 32-bit 204def GPR64as32Operand : AsmOperandClass { 205 let Name = "GPR64as32"; 206 let ParserMethod = 207 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 208} 209def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 210 let ParserMatchClass = GPR64as32Operand; 211} 212 213// 8-bit immediate for AdvSIMD where 64-bit values of the form: 214// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 215// are encoded as the eight bit value 'abcdefgh'. 216def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 217 218class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 219 let Name = "UImm" # Width # "s" # Scale; 220 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 221 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 222 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 223} 224 225class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 226 let Name = "SImm" # Width # "s" # Scale; 227 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 228 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 229 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 230} 231 232//===----------------------------------------------------------------------===// 233// Operand Definitions. 234// 235 236// ADR[P] instruction labels. 237def AdrpOperand : AsmOperandClass { 238 let Name = "AdrpLabel"; 239 let ParserMethod = "tryParseAdrpLabel"; 240 let DiagnosticType = "InvalidLabel"; 241} 242def adrplabel : Operand<i64> { 243 let EncoderMethod = "getAdrLabelOpValue"; 244 let PrintMethod = "printAdrpLabel"; 245 let ParserMatchClass = AdrpOperand; 246} 247 248def AdrOperand : AsmOperandClass { 249 let Name = "AdrLabel"; 250 let ParserMethod = "tryParseAdrLabel"; 251 let DiagnosticType = "InvalidLabel"; 252} 253def adrlabel : Operand<i64> { 254 let EncoderMethod = "getAdrLabelOpValue"; 255 let ParserMatchClass = AdrOperand; 256} 257 258class SImmOperand<int width> : AsmOperandClass { 259 let Name = "SImm" # width; 260 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 261 let RenderMethod = "addImmOperands"; 262 let PredicateMethod = "isSImm<" # width # ">"; 263} 264 265 266class AsmImmRange<int Low, int High> : AsmOperandClass { 267 let Name = "Imm" # Low # "_" # High; 268 let DiagnosticType = "InvalidImm" # Low # "_" # High; 269 let RenderMethod = "addImmOperands"; 270 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 271} 272 273// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 274def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 275def simm10Scaled : Operand<i64> { 276 let ParserMatchClass = SImm10s8Operand; 277 let DecoderMethod = "DecodeSImm<10>"; 278 let PrintMethod = "printImmScale<8>"; 279} 280 281def simm9s16 : Operand<i64> { 282 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 283 let DecoderMethod = "DecodeSImm<9>"; 284 let PrintMethod = "printImmScale<16>"; 285} 286 287// uimm6 predicate - True if the immediate is in the range [0, 63]. 288def UImm6Operand : AsmOperandClass { 289 let Name = "UImm6"; 290 let DiagnosticType = "InvalidImm0_63"; 291} 292 293def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 294 let ParserMatchClass = UImm6Operand; 295} 296 297def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 298 let ParserMatchClass = AsmImmRange<0, 65535>; 299} 300 301def SImm9Operand : SImmOperand<9>; 302def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 303 let ParserMatchClass = SImm9Operand; 304 let DecoderMethod = "DecodeSImm<9>"; 305} 306 307def SImm8Operand : SImmOperand<8>; 308def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 127; }]> { 309 let ParserMatchClass = SImm8Operand; 310 let DecoderMethod = "DecodeSImm<8>"; 311} 312 313def SImm6Operand : SImmOperand<6>; 314def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 315 let ParserMatchClass = SImm6Operand; 316 let DecoderMethod = "DecodeSImm<6>"; 317} 318 319def SImm5Operand : SImmOperand<5>; 320def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 321 let ParserMatchClass = SImm5Operand; 322 let DecoderMethod = "DecodeSImm<5>"; 323} 324 325def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 326 let ParserMatchClass = SImm5Operand; 327 let DecoderMethod = "DecodeSImm<5>"; 328} 329 330// simm7sN predicate - True if the immediate is a multiple of N in the range 331// [-64 * N, 63 * N]. 332 333def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 334def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 335def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 336 337def simm7s4 : Operand<i32> { 338 let ParserMatchClass = SImm7s4Operand; 339 let PrintMethod = "printImmScale<4>"; 340} 341 342def simm7s8 : Operand<i32> { 343 let ParserMatchClass = SImm7s8Operand; 344 let PrintMethod = "printImmScale<8>"; 345} 346 347def simm7s16 : Operand<i32> { 348 let ParserMatchClass = SImm7s16Operand; 349 let PrintMethod = "printImmScale<16>"; 350} 351 352def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>; 353def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>; 354def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>; 355def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>; 356def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>; 357 358def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>; 359def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>; 360 361def UImmS2XForm : SDNodeXForm<imm, [{ 362 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 363}]>; 364def UImmS4XForm : SDNodeXForm<imm, [{ 365 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 366}]>; 367def UImmS8XForm : SDNodeXForm<imm, [{ 368 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 369}]>; 370 371// uimm5sN predicate - True if the immediate is a multiple of N in the range 372// [0 * N, 32 * N]. 373def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 374def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 375def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 376 377def uimm5s2 : Operand<i64>, ImmLeaf<i64, 378 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 379 UImmS2XForm> { 380 let ParserMatchClass = UImm5s2Operand; 381 let PrintMethod = "printImmScale<2>"; 382} 383def uimm5s4 : Operand<i64>, ImmLeaf<i64, 384 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 385 UImmS4XForm> { 386 let ParserMatchClass = UImm5s4Operand; 387 let PrintMethod = "printImmScale<4>"; 388} 389def uimm5s8 : Operand<i64>, ImmLeaf<i64, 390 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 391 UImmS8XForm> { 392 let ParserMatchClass = UImm5s8Operand; 393 let PrintMethod = "printImmScale<8>"; 394} 395 396// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 397// instead of ImmLeaf (Constant) 398def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 399 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 400 UImmS2XForm> { 401 let ParserMatchClass = UImm5s2Operand; 402 let PrintMethod = "printImmScale<2>"; 403} 404def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 405 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 406 UImmS4XForm> { 407 let ParserMatchClass = UImm5s4Operand; 408 let PrintMethod = "printImmScale<4>"; 409} 410def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 411 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 412 UImmS8XForm> { 413 let ParserMatchClass = UImm5s8Operand; 414 let PrintMethod = "printImmScale<8>"; 415} 416 417// uimm6sN predicate - True if the immediate is a multiple of N in the range 418// [0 * N, 64 * N]. 419def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 420def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 421def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 422def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 423def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 424 425def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 426 let ParserMatchClass = UImm6s1Operand; 427} 428def uimm6s2 : Operand<i64>, ImmLeaf<i64, 429[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 430 let PrintMethod = "printImmScale<2>"; 431 let ParserMatchClass = UImm6s2Operand; 432} 433def uimm6s4 : Operand<i64>, ImmLeaf<i64, 434[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 435 let PrintMethod = "printImmScale<4>"; 436 let ParserMatchClass = UImm6s4Operand; 437} 438def uimm6s8 : Operand<i64>, ImmLeaf<i64, 439[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 440 let PrintMethod = "printImmScale<8>"; 441 let ParserMatchClass = UImm6s8Operand; 442} 443def uimm6s16 : Operand<i64>, ImmLeaf<i64, 444[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 445 let PrintMethod = "printImmScale<16>"; 446 let ParserMatchClass = UImm6s16Operand; 447} 448 449// simm6sN predicate - True if the immediate is a multiple of N in the range 450// [-32 * N, 31 * N]. 451def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 452def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 453 let ParserMatchClass = SImm6s1Operand; 454 let DecoderMethod = "DecodeSImm<6>"; 455} 456 457// simm4sN predicate - True if the immediate is a multiple of N in the range 458// [ -8* N, 7 * N]. 459def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 460def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 461def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 462def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 463def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 464 465def simm4s1 : Operand<i64>, ImmLeaf<i64, 466[{ return Imm >=-8 && Imm <= 7; }]> { 467 let ParserMatchClass = SImm4s1Operand; 468 let DecoderMethod = "DecodeSImm<4>"; 469} 470 471def simm4s2 : Operand<i64>, ImmLeaf<i64, 472[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }]> { 473 let PrintMethod = "printImmScale<2>"; 474 let ParserMatchClass = SImm4s2Operand; 475 let DecoderMethod = "DecodeSImm<4>"; 476} 477 478def simm4s3 : Operand<i64>, ImmLeaf<i64, 479[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }]> { 480 let PrintMethod = "printImmScale<3>"; 481 let ParserMatchClass = SImm4s3Operand; 482 let DecoderMethod = "DecodeSImm<4>"; 483} 484 485def simm4s4 : Operand<i64>, ImmLeaf<i64, 486[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }]> { 487 let PrintMethod = "printImmScale<4>"; 488 let ParserMatchClass = SImm4s4Operand; 489 let DecoderMethod = "DecodeSImm<4>"; 490} 491def simm4s16 : Operand<i64>, ImmLeaf<i64, 492[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }]> { 493 let PrintMethod = "printImmScale<16>"; 494 let ParserMatchClass = SImm4s16Operand; 495 let DecoderMethod = "DecodeSImm<4>"; 496} 497 498def Imm1_8Operand : AsmImmRange<1, 8>; 499def Imm1_16Operand : AsmImmRange<1, 16>; 500def Imm1_32Operand : AsmImmRange<1, 32>; 501def Imm1_64Operand : AsmImmRange<1, 64>; 502 503class BranchTarget<int N> : AsmOperandClass { 504 let Name = "BranchTarget" # N; 505 let DiagnosticType = "InvalidLabel"; 506 let PredicateMethod = "isBranchTarget<" # N # ">"; 507} 508 509class PCRelLabel<int N> : BranchTarget<N> { 510 let Name = "PCRelLabel" # N; 511} 512 513def BranchTarget14Operand : BranchTarget<14>; 514def BranchTarget26Operand : BranchTarget<26>; 515def PCRelLabel19Operand : PCRelLabel<19>; 516 517def MovWSymbolG3AsmOperand : AsmOperandClass { 518 let Name = "MovWSymbolG3"; 519 let RenderMethod = "addImmOperands"; 520} 521 522def movw_symbol_g3 : Operand<i32> { 523 let ParserMatchClass = MovWSymbolG3AsmOperand; 524} 525 526def MovWSymbolG2AsmOperand : AsmOperandClass { 527 let Name = "MovWSymbolG2"; 528 let RenderMethod = "addImmOperands"; 529} 530 531def movw_symbol_g2 : Operand<i32> { 532 let ParserMatchClass = MovWSymbolG2AsmOperand; 533} 534 535def MovWSymbolG1AsmOperand : AsmOperandClass { 536 let Name = "MovWSymbolG1"; 537 let RenderMethod = "addImmOperands"; 538} 539 540def movw_symbol_g1 : Operand<i32> { 541 let ParserMatchClass = MovWSymbolG1AsmOperand; 542} 543 544def MovWSymbolG0AsmOperand : AsmOperandClass { 545 let Name = "MovWSymbolG0"; 546 let RenderMethod = "addImmOperands"; 547} 548 549def movw_symbol_g0 : Operand<i32> { 550 let ParserMatchClass = MovWSymbolG0AsmOperand; 551} 552 553class fixedpoint_i32<ValueType FloatVT> 554 : Operand<FloatVT>, 555 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 556 let EncoderMethod = "getFixedPointScaleOpValue"; 557 let DecoderMethod = "DecodeFixedPointScaleImm32"; 558 let ParserMatchClass = Imm1_32Operand; 559} 560 561class fixedpoint_i64<ValueType FloatVT> 562 : Operand<FloatVT>, 563 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 564 let EncoderMethod = "getFixedPointScaleOpValue"; 565 let DecoderMethod = "DecodeFixedPointScaleImm64"; 566 let ParserMatchClass = Imm1_64Operand; 567} 568 569def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 570def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 571def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 572 573def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 574def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 575def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 576 577def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 578 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 579}]> { 580 let EncoderMethod = "getVecShiftR8OpValue"; 581 let DecoderMethod = "DecodeVecShiftR8Imm"; 582 let ParserMatchClass = Imm1_8Operand; 583} 584def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 585 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 586}]> { 587 let EncoderMethod = "getVecShiftR16OpValue"; 588 let DecoderMethod = "DecodeVecShiftR16Imm"; 589 let ParserMatchClass = Imm1_16Operand; 590} 591def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 592 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 593}]> { 594 let EncoderMethod = "getVecShiftR16OpValue"; 595 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 596 let ParserMatchClass = Imm1_8Operand; 597} 598def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 599 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 600}]> { 601 let EncoderMethod = "getVecShiftR32OpValue"; 602 let DecoderMethod = "DecodeVecShiftR32Imm"; 603 let ParserMatchClass = Imm1_32Operand; 604} 605def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 606 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 607}]> { 608 let EncoderMethod = "getVecShiftR32OpValue"; 609 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 610 let ParserMatchClass = Imm1_16Operand; 611} 612def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 613 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 614}]> { 615 let EncoderMethod = "getVecShiftR64OpValue"; 616 let DecoderMethod = "DecodeVecShiftR64Imm"; 617 let ParserMatchClass = Imm1_64Operand; 618} 619def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 620 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 621}]> { 622 let EncoderMethod = "getVecShiftR64OpValue"; 623 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 624 let ParserMatchClass = Imm1_32Operand; 625} 626 627// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 628// (ImmLeaf) 629def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 630 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 631}]> { 632 let EncoderMethod = "getVecShiftR8OpValue"; 633 let DecoderMethod = "DecodeVecShiftR8Imm"; 634 let ParserMatchClass = Imm1_8Operand; 635} 636def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 637 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 638}]> { 639 let EncoderMethod = "getVecShiftR16OpValue"; 640 let DecoderMethod = "DecodeVecShiftR16Imm"; 641 let ParserMatchClass = Imm1_16Operand; 642} 643def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 644 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 645}]> { 646 let EncoderMethod = "getVecShiftR32OpValue"; 647 let DecoderMethod = "DecodeVecShiftR32Imm"; 648 let ParserMatchClass = Imm1_32Operand; 649} 650 651def Imm0_1Operand : AsmImmRange<0, 1>; 652def Imm0_7Operand : AsmImmRange<0, 7>; 653def Imm0_15Operand : AsmImmRange<0, 15>; 654def Imm0_31Operand : AsmImmRange<0, 31>; 655def Imm0_63Operand : AsmImmRange<0, 63>; 656 657def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 658 return (((uint32_t)Imm) < 8); 659}]> { 660 let EncoderMethod = "getVecShiftL8OpValue"; 661 let DecoderMethod = "DecodeVecShiftL8Imm"; 662 let ParserMatchClass = Imm0_7Operand; 663} 664def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 665 return (((uint32_t)Imm) < 16); 666}]> { 667 let EncoderMethod = "getVecShiftL16OpValue"; 668 let DecoderMethod = "DecodeVecShiftL16Imm"; 669 let ParserMatchClass = Imm0_15Operand; 670} 671def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 672 return (((uint32_t)Imm) < 32); 673}]> { 674 let EncoderMethod = "getVecShiftL32OpValue"; 675 let DecoderMethod = "DecodeVecShiftL32Imm"; 676 let ParserMatchClass = Imm0_31Operand; 677} 678def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 679 return (((uint32_t)Imm) < 64); 680}]> { 681 let EncoderMethod = "getVecShiftL64OpValue"; 682 let DecoderMethod = "DecodeVecShiftL64Imm"; 683 let ParserMatchClass = Imm0_63Operand; 684} 685 686 687// Crazy immediate formats used by 32-bit and 64-bit logical immediate 688// instructions for splatting repeating bit patterns across the immediate. 689def logical_imm32_XFORM : SDNodeXForm<imm, [{ 690 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 691 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 692}]>; 693def logical_imm64_XFORM : SDNodeXForm<imm, [{ 694 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 695 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 696}]>; 697 698def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 699 GISDNodeXFormEquiv<logical_imm32_XFORM>; 700def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 701 GISDNodeXFormEquiv<logical_imm64_XFORM>; 702 703let DiagnosticType = "LogicalSecondSource" in { 704 def LogicalImm32Operand : AsmOperandClass { 705 let Name = "LogicalImm32"; 706 let PredicateMethod = "isLogicalImm<int32_t>"; 707 let RenderMethod = "addLogicalImmOperands<int32_t>"; 708 } 709 def LogicalImm64Operand : AsmOperandClass { 710 let Name = "LogicalImm64"; 711 let PredicateMethod = "isLogicalImm<int64_t>"; 712 let RenderMethod = "addLogicalImmOperands<int64_t>"; 713 } 714 def LogicalImm32NotOperand : AsmOperandClass { 715 let Name = "LogicalImm32Not"; 716 let PredicateMethod = "isLogicalImm<int32_t>"; 717 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 718 } 719 def LogicalImm64NotOperand : AsmOperandClass { 720 let Name = "LogicalImm64Not"; 721 let PredicateMethod = "isLogicalImm<int64_t>"; 722 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 723 } 724} 725def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 726 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 727}], logical_imm32_XFORM> { 728 let PrintMethod = "printLogicalImm<int32_t>"; 729 let ParserMatchClass = LogicalImm32Operand; 730} 731def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 732 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 733}], logical_imm64_XFORM> { 734 let PrintMethod = "printLogicalImm<int64_t>"; 735 let ParserMatchClass = LogicalImm64Operand; 736} 737def logical_imm32_not : Operand<i32> { 738 let ParserMatchClass = LogicalImm32NotOperand; 739} 740def logical_imm64_not : Operand<i64> { 741 let ParserMatchClass = LogicalImm64NotOperand; 742} 743 744// iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535]. 745let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 746def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{ 747 return ((uint32_t)Imm) < 65536; 748}]>; 749 750def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{ 751 return ((uint64_t)Imm) < 65536; 752}]>; 753} 754 755// imm0_255 predicate - True if the immediate is in the range [0,255]. 756def Imm0_255Operand : AsmImmRange<0,255>; 757 758def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 759 return ((uint32_t)Imm) < 256; 760}]> { 761 let ParserMatchClass = Imm0_255Operand; 762 let PrintMethod = "printImm"; 763} 764 765// imm0_127 predicate - True if the immediate is in the range [0,127] 766def Imm0_127Operand : AsmImmRange<0, 127>; 767def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 768 return ((uint32_t)Imm) < 128; 769}]> { 770 let ParserMatchClass = Imm0_127Operand; 771 let PrintMethod = "printImm"; 772} 773 774def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 775 return ((uint64_t)Imm) < 128; 776}]> { 777 let ParserMatchClass = Imm0_127Operand; 778 let PrintMethod = "printImm"; 779} 780 781// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 782// for all shift-amounts. 783 784// imm0_63 predicate - True if the immediate is in the range [0,63] 785def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 786 return ((uint64_t)Imm) < 64; 787}]> { 788 let ParserMatchClass = Imm0_63Operand; 789} 790 791// imm0_31 predicate - True if the immediate is in the range [0,31] 792def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 793 return ((uint64_t)Imm) < 32; 794}]> { 795 let ParserMatchClass = Imm0_31Operand; 796} 797 798// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 799// instead of Contant (ImmLeaf) 800def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 801 return ((uint64_t)Imm) < 32; 802}]> { 803 let ParserMatchClass = Imm0_31Operand; 804} 805 806// True if the 32-bit immediate is in the range [0,31] 807def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 808 return ((uint64_t)Imm) < 32; 809}]> { 810 let ParserMatchClass = Imm0_31Operand; 811} 812 813// imm0_1 predicate - True if the immediate is in the range [0,1] 814def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 815 return ((uint64_t)Imm) < 2; 816}]> { 817 let ParserMatchClass = Imm0_1Operand; 818} 819 820// imm0_15 predicate - True if the immediate is in the range [0,15] 821def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 822 return ((uint64_t)Imm) < 16; 823}]> { 824 let ParserMatchClass = Imm0_15Operand; 825} 826 827// imm0_7 predicate - True if the immediate is in the range [0,7] 828def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 829 return ((uint64_t)Imm) < 8; 830}]> { 831 let ParserMatchClass = Imm0_7Operand; 832} 833 834// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 835def imm32_0_7 : Operand<i32>, ImmLeaf<i32, [{ 836 return ((uint32_t)Imm) < 8; 837}]> { 838 let ParserMatchClass = Imm0_7Operand; 839} 840 841// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 842def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 843 return ((uint32_t)Imm) < 16; 844}]> { 845 let ParserMatchClass = Imm0_15Operand; 846} 847 848// An arithmetic shifter operand: 849// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 850// {5-0} - imm6 851class arith_shift<ValueType Ty, int width> : Operand<Ty> { 852 let PrintMethod = "printShifter"; 853 let ParserMatchClass = !cast<AsmOperandClass>( 854 "ArithmeticShifterOperand" # width); 855} 856 857def arith_shift32 : arith_shift<i32, 32>; 858def arith_shift64 : arith_shift<i64, 64>; 859 860class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 861 : Operand<Ty>, 862 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 863 let PrintMethod = "printShiftedRegister"; 864 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 865} 866 867def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 868def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 869 870def gi_arith_shifted_reg32 : 871 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 872 GIComplexPatternEquiv<arith_shifted_reg32>; 873 874def gi_arith_shifted_reg64 : 875 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 876 GIComplexPatternEquiv<arith_shifted_reg64>; 877 878// An arithmetic shifter operand: 879// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 880// {5-0} - imm6 881class logical_shift<int width> : Operand<i32> { 882 let PrintMethod = "printShifter"; 883 let ParserMatchClass = !cast<AsmOperandClass>( 884 "LogicalShifterOperand" # width); 885} 886 887def logical_shift32 : logical_shift<32>; 888def logical_shift64 : logical_shift<64>; 889 890class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 891 : Operand<Ty>, 892 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 893 let PrintMethod = "printShiftedRegister"; 894 let MIOperandInfo = (ops regclass, shiftop); 895} 896 897def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 898def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 899 900def gi_logical_shifted_reg32 : 901 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 902 GIComplexPatternEquiv<logical_shifted_reg32>; 903 904def gi_logical_shifted_reg64 : 905 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 906 GIComplexPatternEquiv<logical_shifted_reg64>; 907 908// A logical vector shifter operand: 909// {7-6} - shift type: 00 = lsl 910// {5-0} - imm6: #0, #8, #16, or #24 911def logical_vec_shift : Operand<i32> { 912 let PrintMethod = "printShifter"; 913 let EncoderMethod = "getVecShifterOpValue"; 914 let ParserMatchClass = LogicalVecShifterOperand; 915} 916 917// A logical vector half-word shifter operand: 918// {7-6} - shift type: 00 = lsl 919// {5-0} - imm6: #0 or #8 920def logical_vec_hw_shift : Operand<i32> { 921 let PrintMethod = "printShifter"; 922 let EncoderMethod = "getVecShifterOpValue"; 923 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 924} 925 926// A vector move shifter operand: 927// {0} - imm1: #8 or #16 928def move_vec_shift : Operand<i32> { 929 let PrintMethod = "printShifter"; 930 let EncoderMethod = "getMoveVecShifterOpValue"; 931 let ParserMatchClass = MoveVecShifterOperand; 932} 933 934let DiagnosticType = "AddSubSecondSource" in { 935 def AddSubImmOperand : AsmOperandClass { 936 let Name = "AddSubImm"; 937 let ParserMethod = "tryParseImmWithOptionalShift"; 938 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 939 } 940 def AddSubImmNegOperand : AsmOperandClass { 941 let Name = "AddSubImmNeg"; 942 let ParserMethod = "tryParseImmWithOptionalShift"; 943 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 944 } 945} 946// An ADD/SUB immediate shifter operand: 947// second operand: 948// {7-6} - shift type: 00 = lsl 949// {5-0} - imm6: #0 or #12 950class addsub_shifted_imm<ValueType Ty> 951 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 952 let PrintMethod = "printAddSubImm"; 953 let EncoderMethod = "getAddSubImmOpValue"; 954 let ParserMatchClass = AddSubImmOperand; 955 let MIOperandInfo = (ops i32imm, i32imm); 956} 957 958class addsub_shifted_imm_neg<ValueType Ty> 959 : Operand<Ty> { 960 let EncoderMethod = "getAddSubImmOpValue"; 961 let ParserMatchClass = AddSubImmNegOperand; 962 let MIOperandInfo = (ops i32imm, i32imm); 963} 964 965def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 966def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 967def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 968def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 969 970def gi_addsub_shifted_imm32 : 971 GIComplexOperandMatcher<s32, "selectArithImmed">, 972 GIComplexPatternEquiv<addsub_shifted_imm32>; 973 974def gi_addsub_shifted_imm64 : 975 GIComplexOperandMatcher<s64, "selectArithImmed">, 976 GIComplexPatternEquiv<addsub_shifted_imm64>; 977 978class neg_addsub_shifted_imm<ValueType Ty> 979 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 980 let PrintMethod = "printAddSubImm"; 981 let EncoderMethod = "getAddSubImmOpValue"; 982 let ParserMatchClass = AddSubImmOperand; 983 let MIOperandInfo = (ops i32imm, i32imm); 984} 985 986def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 987def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 988 989def gi_neg_addsub_shifted_imm32 : 990 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 991 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 992 993def gi_neg_addsub_shifted_imm64 : 994 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 995 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 996 997// An extend operand: 998// {5-3} - extend type 999// {2-0} - imm3 1000def arith_extend : Operand<i32> { 1001 let PrintMethod = "printArithExtend"; 1002 let ParserMatchClass = ExtendOperand; 1003} 1004def arith_extend64 : Operand<i32> { 1005 let PrintMethod = "printArithExtend"; 1006 let ParserMatchClass = ExtendOperand64; 1007} 1008 1009// 'extend' that's a lsl of a 64-bit register. 1010def arith_extendlsl64 : Operand<i32> { 1011 let PrintMethod = "printArithExtend"; 1012 let ParserMatchClass = ExtendOperandLSL64; 1013} 1014 1015class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1016 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1017 let PrintMethod = "printExtendedRegister"; 1018 let MIOperandInfo = (ops GPR32, arith_extend); 1019} 1020 1021class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1022 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1023 let PrintMethod = "printExtendedRegister"; 1024 let MIOperandInfo = (ops GPR32, arith_extend64); 1025} 1026 1027def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1028def gi_arith_extended_reg32_i32 : 1029 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1030 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1031 1032def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1033def gi_arith_extended_reg32_i64 : 1034 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1035 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1036 1037def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1038def gi_arith_extended_reg32to64_i64 : 1039 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1040 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1041 1042// Floating-point immediate. 1043def fpimm16 : Operand<f16>, 1044 FPImmLeaf<f16, [{ 1045 return AArch64_AM::getFP16Imm(Imm) != -1; 1046 }], SDNodeXForm<fpimm, [{ 1047 APFloat InVal = N->getValueAPF(); 1048 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1049 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1050 }]>> { 1051 let ParserMatchClass = FPImmOperand; 1052 let PrintMethod = "printFPImmOperand"; 1053} 1054def fpimm32 : Operand<f32>, 1055 FPImmLeaf<f32, [{ 1056 return AArch64_AM::getFP32Imm(Imm) != -1; 1057 }], SDNodeXForm<fpimm, [{ 1058 APFloat InVal = N->getValueAPF(); 1059 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1060 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1061 }]>> { 1062 let ParserMatchClass = FPImmOperand; 1063 let PrintMethod = "printFPImmOperand"; 1064} 1065def fpimm64 : Operand<f64>, 1066 FPImmLeaf<f64, [{ 1067 return AArch64_AM::getFP64Imm(Imm) != -1; 1068 }], SDNodeXForm<fpimm, [{ 1069 APFloat InVal = N->getValueAPF(); 1070 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1071 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1072 }]>> { 1073 let ParserMatchClass = FPImmOperand; 1074 let PrintMethod = "printFPImmOperand"; 1075} 1076 1077def fpimm8 : Operand<i32> { 1078 let ParserMatchClass = FPImmOperand; 1079 let PrintMethod = "printFPImmOperand"; 1080} 1081 1082def fpimm0 : FPImmLeaf<fAny, [{ 1083 return Imm.isExactlyValue(+0.0); 1084}]>; 1085 1086// Vector lane operands 1087class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1088 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1089 let DiagnosticType = "Invalid" # Name; 1090 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1091 let RenderMethod = "addVectorIndexOperands"; 1092} 1093 1094class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc, code pred> 1095 : Operand<ty>, ImmLeaf<ty, pred> { 1096 let ParserMatchClass = mc; 1097 let PrintMethod = "printVectorIndex"; 1098} 1099 1100def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1101def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1102def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1103def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1104def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1105 1106def VectorIndex1 : AsmVectorIndexOpnd<i64, VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>; 1107def VectorIndexB : AsmVectorIndexOpnd<i64, VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>; 1108def VectorIndexH : AsmVectorIndexOpnd<i64, VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>; 1109def VectorIndexS : AsmVectorIndexOpnd<i64, VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>; 1110def VectorIndexD : AsmVectorIndexOpnd<i64, VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>; 1111 1112def VectorIndex132b : AsmVectorIndexOpnd<i32, VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>; 1113def VectorIndexB32b : AsmVectorIndexOpnd<i32, VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>; 1114def VectorIndexH32b : AsmVectorIndexOpnd<i32, VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>; 1115def VectorIndexS32b : AsmVectorIndexOpnd<i32, VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>; 1116def VectorIndexD32b : AsmVectorIndexOpnd<i32, VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>; 1117 1118def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1119def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1120def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1121def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1122def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1123 1124def sve_elm_idx_extdup_b 1125 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupBOperand, [{ return ((uint64_t)Imm) < 64; }]>; 1126def sve_elm_idx_extdup_h 1127 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupHOperand, [{ return ((uint64_t)Imm) < 32; }]>; 1128def sve_elm_idx_extdup_s 1129 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupSOperand, [{ return ((uint64_t)Imm) < 16; }]>; 1130def sve_elm_idx_extdup_d 1131 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupDOperand, [{ return ((uint64_t)Imm) < 8; }]>; 1132def sve_elm_idx_extdup_q 1133 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupQOperand, [{ return ((uint64_t)Imm) < 4; }]>; 1134 1135// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1136// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1137// are encoded as the eight bit value 'abcdefgh'. 1138def simdimmtype10 : Operand<i32>, 1139 FPImmLeaf<f64, [{ 1140 return AArch64_AM::isAdvSIMDModImmType10( 1141 Imm.bitcastToAPInt().getZExtValue()); 1142 }], SDNodeXForm<fpimm, [{ 1143 APFloat InVal = N->getValueAPF(); 1144 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1145 .bitcastToAPInt() 1146 .getZExtValue()); 1147 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1148 }]>> { 1149 let ParserMatchClass = SIMDImmType10Operand; 1150 let PrintMethod = "printSIMDType10Operand"; 1151} 1152 1153 1154//--- 1155// System management 1156//--- 1157 1158// Base encoding for system instruction operands. 1159let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1160class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1161 list<dag> pattern = []> 1162 : I<oops, iops, asm, operands, "", pattern> { 1163 let Inst{31-22} = 0b1101010100; 1164 let Inst{21} = L; 1165} 1166 1167// System instructions which do not have an Rt register. 1168class SimpleSystemI<bit L, dag iops, string asm, string operands, 1169 list<dag> pattern = []> 1170 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1171 let Inst{4-0} = 0b11111; 1172} 1173 1174// System instructions which have an Rt register. 1175class RtSystemI<bit L, dag oops, dag iops, string asm, string operands> 1176 : BaseSystemI<L, oops, iops, asm, operands>, 1177 Sched<[WriteSys]> { 1178 bits<5> Rt; 1179 let Inst{4-0} = Rt; 1180} 1181 1182// System instructions for transactional memory extension 1183class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1184 string asm, string operands, list<dag> pattern> 1185 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1186 Sched<[WriteSys]> { 1187 let Inst{20-12} = 0b000110011; 1188 let Inst{11-8} = CRm; 1189 let Inst{7-5} = op2; 1190 let DecoderMethod = ""; 1191 1192 let mayLoad = 1; 1193 let mayStore = 1; 1194} 1195 1196// System instructions for transactional memory - single input operand 1197class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1198 : TMBaseSystemI<0b1, CRm, 0b011, 1199 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1200 bits<5> Rt; 1201 let Inst{4-0} = Rt; 1202} 1203 1204// System instructions for transactional memory - no operand 1205class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1206 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1207 let Inst{4-0} = 0b11111; 1208} 1209 1210// System instructions for exit from transactions 1211class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1212 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>, 1213 Sched<[WriteSys]> { 1214 bits<16> imm; 1215 let Inst{31-24} = 0b11010100; 1216 let Inst{23-21} = op1; 1217 let Inst{20-5} = imm; 1218 let Inst{4-0} = 0b00000; 1219} 1220 1221// Hint instructions that take both a CRm and a 3-bit immediate. 1222// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1223// model patterns with sufficiently fine granularity 1224let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1225 class HintI<string mnemonic> 1226 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1227 [(int_aarch64_hint imm0_127:$imm)]>, 1228 Sched<[WriteHint]> { 1229 bits <7> imm; 1230 let Inst{20-12} = 0b000110010; 1231 let Inst{11-5} = imm; 1232 } 1233 1234// System instructions taking a single literal operand which encodes into 1235// CRm. op2 differentiates the opcodes. 1236def BarrierAsmOperand : AsmOperandClass { 1237 let Name = "Barrier"; 1238 let ParserMethod = "tryParseBarrierOperand"; 1239} 1240def barrier_op : Operand<i32> { 1241 let PrintMethod = "printBarrierOption"; 1242 let ParserMatchClass = BarrierAsmOperand; 1243} 1244class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1245 list<dag> pattern = []> 1246 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1247 Sched<[WriteBarrier]> { 1248 bits<4> CRm; 1249 let Inst{20-12} = 0b000110011; 1250 let Inst{11-8} = CRm; 1251 let Inst{7-5} = opc; 1252} 1253 1254class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1255 : SimpleSystemI<0, (ins), asm, "", pattern>, 1256 Sched<[]> { 1257 bits<4> CRm; 1258 let CRm = 0b0011; 1259 let Inst{31-12} = 0b11010101000000110010; 1260 let Inst{11-8} = CRm; 1261 let Inst{7-5} = op2; 1262 let Inst{4-0} = 0b11111; 1263} 1264 1265// MRS/MSR system instructions. These have different operand classes because 1266// a different subset of registers can be accessed through each instruction. 1267def MRSSystemRegisterOperand : AsmOperandClass { 1268 let Name = "MRSSystemRegister"; 1269 let ParserMethod = "tryParseSysReg"; 1270 let DiagnosticType = "MRS"; 1271} 1272// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1273def mrs_sysreg_op : Operand<i32> { 1274 let ParserMatchClass = MRSSystemRegisterOperand; 1275 let DecoderMethod = "DecodeMRSSystemRegister"; 1276 let PrintMethod = "printMRSSystemRegister"; 1277} 1278 1279def MSRSystemRegisterOperand : AsmOperandClass { 1280 let Name = "MSRSystemRegister"; 1281 let ParserMethod = "tryParseSysReg"; 1282 let DiagnosticType = "MSR"; 1283} 1284def msr_sysreg_op : Operand<i32> { 1285 let ParserMatchClass = MSRSystemRegisterOperand; 1286 let DecoderMethod = "DecodeMSRSystemRegister"; 1287 let PrintMethod = "printMSRSystemRegister"; 1288} 1289 1290def PSBHintOperand : AsmOperandClass { 1291 let Name = "PSBHint"; 1292 let ParserMethod = "tryParsePSBHint"; 1293} 1294def psbhint_op : Operand<i32> { 1295 let ParserMatchClass = PSBHintOperand; 1296 let PrintMethod = "printPSBHintOp"; 1297 let MCOperandPredicate = [{ 1298 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1299 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1300 if (!MCOp.isImm()) 1301 return false; 1302 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1303 }]; 1304} 1305 1306def BTIHintOperand : AsmOperandClass { 1307 let Name = "BTIHint"; 1308 let ParserMethod = "tryParseBTIHint"; 1309} 1310def btihint_op : Operand<i32> { 1311 let ParserMatchClass = BTIHintOperand; 1312 let PrintMethod = "printBTIHintOp"; 1313 let MCOperandPredicate = [{ 1314 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1315 if (!MCOp.isImm()) 1316 return false; 1317 return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr; 1318 }]; 1319} 1320 1321class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1322 "mrs", "\t$Rt, $systemreg"> { 1323 bits<16> systemreg; 1324 let Inst{20-5} = systemreg; 1325} 1326 1327// FIXME: Some of these def NZCV, others don't. Best way to model that? 1328// Explicitly modeling each of the system register as a register class 1329// would do it, but feels like overkill at this point. 1330class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1331 "msr", "\t$systemreg, $Rt"> { 1332 bits<16> systemreg; 1333 let Inst{20-5} = systemreg; 1334} 1335 1336def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1337 let Name = "SystemPStateFieldWithImm0_15"; 1338 let ParserMethod = "tryParseSysReg"; 1339} 1340def pstatefield4_op : Operand<i32> { 1341 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1342 let PrintMethod = "printSystemPStateField"; 1343} 1344 1345// Instructions to modify PSTATE, no input reg 1346let Defs = [NZCV] in 1347class PstateWriteSimple<dag iops, string asm, string operands> 1348 : SimpleSystemI<0, iops, asm, operands> { 1349 1350 let Inst{20-19} = 0b00; 1351 let Inst{15-12} = 0b0100; 1352} 1353 1354class MSRpstateImm0_15 1355 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1356 "\t$pstatefield, $imm">, 1357 Sched<[WriteSys]> { 1358 1359 bits<6> pstatefield; 1360 bits<4> imm; 1361 let Inst{18-16} = pstatefield{5-3}; 1362 let Inst{11-8} = imm; 1363 let Inst{7-5} = pstatefield{2-0}; 1364 1365 let DecoderMethod = "DecodeSystemPStateInstruction"; 1366 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1367 // Fail the decoder should attempt to decode the instruction as MSRI. 1368 let hasCompleteDecoder = 0; 1369} 1370 1371def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1372 let Name = "SystemPStateFieldWithImm0_1"; 1373 let ParserMethod = "tryParseSysReg"; 1374} 1375def pstatefield1_op : Operand<i32> { 1376 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1377 let PrintMethod = "printSystemPStateField"; 1378} 1379 1380class MSRpstateImm0_1 1381 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1382 "\t$pstatefield, $imm">, 1383 Sched<[WriteSys]> { 1384 1385 bits<6> pstatefield; 1386 bit imm; 1387 let Inst{18-16} = pstatefield{5-3}; 1388 let Inst{11-9} = 0b000; 1389 let Inst{8} = imm; 1390 let Inst{7-5} = pstatefield{2-0}; 1391 1392 let DecoderMethod = "DecodeSystemPStateInstruction"; 1393 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1394 // Fail the decoder should attempt to decode the instruction as MSRI. 1395 let hasCompleteDecoder = 0; 1396} 1397 1398// SYS and SYSL generic system instructions. 1399def SysCRAsmOperand : AsmOperandClass { 1400 let Name = "SysCR"; 1401 let ParserMethod = "tryParseSysCROperand"; 1402} 1403 1404def sys_cr_op : Operand<i32> { 1405 let PrintMethod = "printSysCROperand"; 1406 let ParserMatchClass = SysCRAsmOperand; 1407} 1408 1409class SystemXtI<bit L, string asm> 1410 : RtSystemI<L, (outs), 1411 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1412 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1413 bits<3> op1; 1414 bits<4> Cn; 1415 bits<4> Cm; 1416 bits<3> op2; 1417 let Inst{20-19} = 0b01; 1418 let Inst{18-16} = op1; 1419 let Inst{15-12} = Cn; 1420 let Inst{11-8} = Cm; 1421 let Inst{7-5} = op2; 1422} 1423 1424class SystemLXtI<bit L, string asm> 1425 : RtSystemI<L, (outs), 1426 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1427 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1428 bits<3> op1; 1429 bits<4> Cn; 1430 bits<4> Cm; 1431 bits<3> op2; 1432 let Inst{20-19} = 0b01; 1433 let Inst{18-16} = op1; 1434 let Inst{15-12} = Cn; 1435 let Inst{11-8} = Cm; 1436 let Inst{7-5} = op2; 1437} 1438 1439 1440// Branch (register) instructions: 1441// 1442// case opc of 1443// 0001 blr 1444// 0000 br 1445// 0101 dret 1446// 0100 eret 1447// 0010 ret 1448// otherwise UNDEFINED 1449class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1450 string operands, list<dag> pattern> 1451 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1452 let Inst{31-25} = 0b1101011; 1453 let Inst{24-21} = opc; 1454 let Inst{20-16} = 0b11111; 1455 let Inst{15-10} = 0b000000; 1456 let Inst{4-0} = 0b00000; 1457} 1458 1459class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1460 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1461 bits<5> Rn; 1462 let Inst{9-5} = Rn; 1463} 1464 1465let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1466class SpecialReturn<bits<4> opc, string asm> 1467 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1468 let Inst{9-5} = 0b11111; 1469} 1470 1471let mayLoad = 1 in 1472class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1473 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1474 Sched<[]> { 1475 bits<5> Rn; 1476 bits<5> Rt; 1477 let Inst{31-30} = sz; 1478 let Inst{29-10} = 0b11100010111111110000; 1479 let Inst{9-5} = Rn; 1480 let Inst{4-0} = Rt; 1481} 1482 1483class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1484 list<dag> pattern> 1485 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1486 let isAuthenticated = 1; 1487 let Inst{31-25} = 0b1101011; 1488 let Inst{20-11} = 0b1111100001; 1489 let Inst{10} = M; 1490 let Inst{4-0} = 0b11111; 1491} 1492 1493class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1494 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1495 bits<5> Rn; 1496 bits<5> Rm; 1497 let Inst{24-22} = 0b100; 1498 let Inst{21} = op; 1499 let Inst{9-5} = Rn; 1500 let Inst{4-0} = Rm; 1501} 1502 1503class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1504 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1505 bits<5> Rn; 1506 let Inst{24} = 0; 1507 let Inst{23-21} = opc; 1508 let Inst{9-5} = Rn; 1509} 1510 1511let Uses = [LR,SP] in 1512class AuthReturn<bits<3> op, bits<1> M, string asm> 1513 : AuthBase<M, (outs), (ins), asm, "", []> { 1514 let Inst{24} = 0; 1515 let Inst{23-21} = op; 1516 let Inst{9-0} = 0b1111111111; 1517} 1518 1519let mayLoad = 1 in 1520class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1521 string operands, string cstr, Operand opr> 1522 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1523 bits<10> offset; 1524 bits<5> Rn; 1525 bits<5> Rt; 1526 let isAuthenticated = 1; 1527 let Inst{31-24} = 0b11111000; 1528 let Inst{23} = M; 1529 let Inst{22} = offset{9}; 1530 let Inst{21} = 1; 1531 let Inst{20-12} = offset{8-0}; 1532 let Inst{11} = W; 1533 let Inst{10} = 1; 1534 let Inst{9-5} = Rn; 1535 let Inst{4-0} = Rt; 1536} 1537 1538multiclass AuthLoad<bit M, string asm, Operand opr> { 1539 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1540 (ins GPR64sp:$Rn, opr:$offset), 1541 asm, "\t$Rt, [$Rn, $offset]", "", opr>; 1542 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1543 (ins GPR64sp:$Rn, opr:$offset), 1544 asm, "\t$Rt, [$Rn, $offset]!", 1545 "$Rn = $wback,@earlyclobber $wback", opr>; 1546 1547 def : InstAlias<asm # "\t$Rt, [$Rn]", 1548 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1549 1550 def : InstAlias<asm # "\t$Rt, [$wback]!", 1551 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1552} 1553 1554//--- 1555// Conditional branch instruction. 1556//--- 1557 1558// Condition code. 1559// 4-bit immediate. Pretty-printed as <cc> 1560def ccode : Operand<i32> { 1561 let PrintMethod = "printCondCode"; 1562 let ParserMatchClass = CondCode; 1563} 1564def inv_ccode : Operand<i32> { 1565 // AL and NV are invalid in the aliases which use inv_ccode 1566 let PrintMethod = "printInverseCondCode"; 1567 let ParserMatchClass = CondCode; 1568 let MCOperandPredicate = [{ 1569 return MCOp.isImm() && 1570 MCOp.getImm() != AArch64CC::AL && 1571 MCOp.getImm() != AArch64CC::NV; 1572 }]; 1573} 1574 1575// Conditional branch target. 19-bit immediate. The low two bits of the target 1576// offset are implied zero and so are not part of the immediate. 1577def am_brcond : Operand<OtherVT> { 1578 let EncoderMethod = "getCondBranchTargetOpValue"; 1579 let DecoderMethod = "DecodePCRelLabel19"; 1580 let PrintMethod = "printAlignedLabel"; 1581 let ParserMatchClass = PCRelLabel19Operand; 1582 let OperandType = "OPERAND_PCREL"; 1583} 1584 1585class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1586 "b", ".$cond\t$target", "", 1587 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1588 Sched<[WriteBr]> { 1589 let isBranch = 1; 1590 let isTerminator = 1; 1591 let Uses = [NZCV]; 1592 1593 bits<4> cond; 1594 bits<19> target; 1595 let Inst{31-24} = 0b01010100; 1596 let Inst{23-5} = target; 1597 let Inst{4} = 0; 1598 let Inst{3-0} = cond; 1599} 1600 1601//--- 1602// Compare-and-branch instructions. 1603//--- 1604class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1605 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1606 asm, "\t$Rt, $target", "", 1607 [(node regtype:$Rt, bb:$target)]>, 1608 Sched<[WriteBr]> { 1609 let isBranch = 1; 1610 let isTerminator = 1; 1611 1612 bits<5> Rt; 1613 bits<19> target; 1614 let Inst{30-25} = 0b011010; 1615 let Inst{24} = op; 1616 let Inst{23-5} = target; 1617 let Inst{4-0} = Rt; 1618} 1619 1620multiclass CmpBranch<bit op, string asm, SDNode node> { 1621 def W : BaseCmpBranch<GPR32, op, asm, node> { 1622 let Inst{31} = 0; 1623 } 1624 def X : BaseCmpBranch<GPR64, op, asm, node> { 1625 let Inst{31} = 1; 1626 } 1627} 1628 1629//--- 1630// Test-bit-and-branch instructions. 1631//--- 1632// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1633// the target offset are implied zero and so are not part of the immediate. 1634def am_tbrcond : Operand<OtherVT> { 1635 let EncoderMethod = "getTestBranchTargetOpValue"; 1636 let PrintMethod = "printAlignedLabel"; 1637 let ParserMatchClass = BranchTarget14Operand; 1638 let OperandType = "OPERAND_PCREL"; 1639} 1640 1641// AsmOperand classes to emit (or not) special diagnostics 1642def TBZImm0_31Operand : AsmOperandClass { 1643 let Name = "TBZImm0_31"; 1644 let PredicateMethod = "isImmInRange<0,31>"; 1645 let RenderMethod = "addImmOperands"; 1646} 1647def TBZImm32_63Operand : AsmOperandClass { 1648 let Name = "Imm32_63"; 1649 let PredicateMethod = "isImmInRange<32,63>"; 1650 let DiagnosticType = "InvalidImm0_63"; 1651 let RenderMethod = "addImmOperands"; 1652} 1653 1654class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1655 return (((uint32_t)Imm) < 32); 1656}]> { 1657 let ParserMatchClass = matcher; 1658} 1659 1660def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1661def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1662 1663def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1664 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1665}]> { 1666 let ParserMatchClass = TBZImm32_63Operand; 1667} 1668 1669class BaseTestBranch<RegisterClass regtype, Operand immtype, 1670 bit op, string asm, SDNode node> 1671 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1672 asm, "\t$Rt, $bit_off, $target", "", 1673 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1674 Sched<[WriteBr]> { 1675 let isBranch = 1; 1676 let isTerminator = 1; 1677 1678 bits<5> Rt; 1679 bits<6> bit_off; 1680 bits<14> target; 1681 1682 let Inst{30-25} = 0b011011; 1683 let Inst{24} = op; 1684 let Inst{23-19} = bit_off{4-0}; 1685 let Inst{18-5} = target; 1686 let Inst{4-0} = Rt; 1687 1688 let DecoderMethod = "DecodeTestAndBranch"; 1689} 1690 1691multiclass TestBranch<bit op, string asm, SDNode node> { 1692 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1693 let Inst{31} = 0; 1694 } 1695 1696 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1697 let Inst{31} = 1; 1698 } 1699 1700 // Alias X-reg with 0-31 imm to W-Reg. 1701 def : InstAlias<asm # "\t$Rd, $imm, $target", 1702 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1703 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1704 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1705 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1706 tbz_imm0_31_diag:$imm, bb:$target)>; 1707} 1708 1709//--- 1710// Unconditional branch (immediate) instructions. 1711//--- 1712def am_b_target : Operand<OtherVT> { 1713 let EncoderMethod = "getBranchTargetOpValue"; 1714 let PrintMethod = "printAlignedLabel"; 1715 let ParserMatchClass = BranchTarget26Operand; 1716 let OperandType = "OPERAND_PCREL"; 1717} 1718def am_bl_target : Operand<i64> { 1719 let EncoderMethod = "getBranchTargetOpValue"; 1720 let PrintMethod = "printAlignedLabel"; 1721 let ParserMatchClass = BranchTarget26Operand; 1722 let OperandType = "OPERAND_PCREL"; 1723} 1724 1725class BImm<bit op, dag iops, string asm, list<dag> pattern> 1726 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1727 bits<26> addr; 1728 let Inst{31} = op; 1729 let Inst{30-26} = 0b00101; 1730 let Inst{25-0} = addr; 1731 1732 let DecoderMethod = "DecodeUnconditionalBranch"; 1733} 1734 1735class BranchImm<bit op, string asm, list<dag> pattern> 1736 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1737class CallImm<bit op, string asm, list<dag> pattern> 1738 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1739 1740//--- 1741// Basic one-operand data processing instructions. 1742//--- 1743 1744let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1745class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1746 SDPatternOperator node> 1747 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1748 [(set regtype:$Rd, (node regtype:$Rn))]>, 1749 Sched<[WriteI, ReadI]> { 1750 bits<5> Rd; 1751 bits<5> Rn; 1752 1753 let Inst{30-13} = 0b101101011000000000; 1754 let Inst{12-10} = opc; 1755 let Inst{9-5} = Rn; 1756 let Inst{4-0} = Rd; 1757} 1758 1759let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1760multiclass OneOperandData<bits<3> opc, string asm, 1761 SDPatternOperator node = null_frag> { 1762 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1763 let Inst{31} = 0; 1764 } 1765 1766 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1767 let Inst{31} = 1; 1768 } 1769} 1770 1771class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1772 : BaseOneOperandData<opc, GPR32, asm, node> { 1773 let Inst{31} = 0; 1774} 1775 1776class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1777 : BaseOneOperandData<opc, GPR64, asm, node> { 1778 let Inst{31} = 1; 1779} 1780 1781class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm> 1782 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "", 1783 []>, 1784 Sched<[WriteI, ReadI]> { 1785 bits<5> Rd; 1786 bits<5> Rn; 1787 let Inst{31-15} = 0b11011010110000010; 1788 let Inst{14-12} = opcode_prefix; 1789 let Inst{11-10} = opcode; 1790 let Inst{9-5} = Rn; 1791 let Inst{4-0} = Rd; 1792} 1793 1794class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm> 1795 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> { 1796 bits<5> Rd; 1797 let Inst{31-15} = 0b11011010110000010; 1798 let Inst{14-12} = opcode_prefix; 1799 let Inst{11-10} = opcode; 1800 let Inst{9-5} = 0b11111; 1801 let Inst{4-0} = Rd; 1802} 1803 1804class SignAuthTwoOperand<bits<4> opc, string asm, 1805 SDPatternOperator OpNode> 1806 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 1807 asm, "\t$Rd, $Rn, $Rm", "", 1808 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 1809 Sched<[WriteI, ReadI, ReadI]> { 1810 bits<5> Rd; 1811 bits<5> Rn; 1812 bits<5> Rm; 1813 let Inst{31-21} = 0b10011010110; 1814 let Inst{20-16} = Rm; 1815 let Inst{15-14} = 0b00; 1816 let Inst{13-10} = opc; 1817 let Inst{9-5} = Rn; 1818 let Inst{4-0} = Rd; 1819} 1820 1821// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 1822class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 1823 : I<(outs), iops, asm, ops, "", []>, 1824 Sched<[WriteI, ReadI, ReadI]> { 1825 let Uses = [NZCV]; 1826 bits<5> Rn; 1827 let Inst{31} = sf; 1828 let Inst{30-15} = 0b0111010000000000; 1829 let Inst{14} = sz; 1830 let Inst{13-10} = 0b0010; 1831 let Inst{9-5} = Rn; 1832 let Inst{4-0} = 0b01101; 1833} 1834 1835class FlagRotate<dag iops, string asm, string ops> 1836 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 1837 bits<6> imm; 1838 bits<4> mask; 1839 let Inst{20-15} = imm; 1840 let Inst{13-10} = 0b0001; 1841 let Inst{4} = 0b0; 1842 let Inst{3-0} = mask; 1843} 1844 1845//--- 1846// Basic two-operand data processing instructions. 1847//--- 1848class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1849 list<dag> pattern> 1850 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1851 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1852 Sched<[WriteI, ReadI, ReadI]> { 1853 let Uses = [NZCV]; 1854 bits<5> Rd; 1855 bits<5> Rn; 1856 bits<5> Rm; 1857 let Inst{30} = isSub; 1858 let Inst{28-21} = 0b11010000; 1859 let Inst{20-16} = Rm; 1860 let Inst{15-10} = 0; 1861 let Inst{9-5} = Rn; 1862 let Inst{4-0} = Rd; 1863} 1864 1865class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1866 SDNode OpNode> 1867 : BaseBaseAddSubCarry<isSub, regtype, asm, 1868 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 1869 1870class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 1871 SDNode OpNode> 1872 : BaseBaseAddSubCarry<isSub, regtype, asm, 1873 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 1874 (implicit NZCV)]> { 1875 let Defs = [NZCV]; 1876} 1877 1878multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 1879 SDNode OpNode, SDNode OpNode_setflags> { 1880 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 1881 let Inst{31} = 0; 1882 let Inst{29} = 0; 1883 } 1884 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 1885 let Inst{31} = 1; 1886 let Inst{29} = 0; 1887 } 1888 1889 // Sets flags. 1890 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 1891 OpNode_setflags> { 1892 let Inst{31} = 0; 1893 let Inst{29} = 1; 1894 } 1895 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 1896 OpNode_setflags> { 1897 let Inst{31} = 1; 1898 let Inst{29} = 1; 1899 } 1900} 1901 1902class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 1903 SDPatternOperator OpNode, 1904 RegisterClass in1regtype = regtype, 1905 RegisterClass in2regtype = regtype> 1906 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 1907 asm, "\t$Rd, $Rn, $Rm", "", 1908 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 1909 bits<5> Rd; 1910 bits<5> Rn; 1911 bits<5> Rm; 1912 let Inst{30-21} = 0b0011010110; 1913 let Inst{20-16} = Rm; 1914 let Inst{15-14} = 0b00; 1915 let Inst{13-10} = opc; 1916 let Inst{9-5} = Rn; 1917 let Inst{4-0} = Rd; 1918} 1919 1920class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 1921 SDPatternOperator OpNode> 1922 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 1923 let Inst{10} = isSigned; 1924} 1925 1926multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 1927 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 1928 Sched<[WriteID32, ReadID, ReadID]> { 1929 let Inst{31} = 0; 1930 } 1931 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 1932 Sched<[WriteID64, ReadID, ReadID]> { 1933 let Inst{31} = 1; 1934 } 1935} 1936 1937class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 1938 SDPatternOperator OpNode = null_frag> 1939 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 1940 Sched<[WriteIS, ReadI]> { 1941 let Inst{11-10} = shift_type; 1942} 1943 1944multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 1945 def Wr : BaseShift<shift_type, GPR32, asm> { 1946 let Inst{31} = 0; 1947 } 1948 1949 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 1950 let Inst{31} = 1; 1951 } 1952 1953 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 1954 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 1955 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 1956 1957 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 1958 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1959 1960 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 1961 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1962 1963 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 1964 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1965 1966 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 1967 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 1968 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 1969 1970 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 1971 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 1972 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 1973} 1974 1975class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 1976 : InstAlias<asm#"\t$dst, $src1, $src2", 1977 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 1978 1979class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 1980 RegisterClass addtype, string asm, 1981 list<dag> pattern> 1982 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 1983 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 1984 bits<5> Rd; 1985 bits<5> Rn; 1986 bits<5> Rm; 1987 bits<5> Ra; 1988 let Inst{30-24} = 0b0011011; 1989 let Inst{23-21} = opc; 1990 let Inst{20-16} = Rm; 1991 let Inst{15} = isSub; 1992 let Inst{14-10} = Ra; 1993 let Inst{9-5} = Rn; 1994 let Inst{4-0} = Rd; 1995} 1996 1997multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 1998 // MADD/MSUB generation is decided by MachineCombiner.cpp 1999 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 2000 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 2001 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2002 let Inst{31} = 0; 2003 } 2004 2005 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 2006 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 2007 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2008 let Inst{31} = 1; 2009 } 2010} 2011 2012class WideMulAccum<bit isSub, bits<3> opc, string asm, 2013 SDNode AccNode, SDNode ExtNode> 2014 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2015 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2016 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2017 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2018 let Inst{31} = 1; 2019} 2020 2021class MulHi<bits<3> opc, string asm, SDNode OpNode> 2022 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2023 asm, "\t$Rd, $Rn, $Rm", "", 2024 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2025 Sched<[WriteIM64, ReadIM, ReadIM]> { 2026 bits<5> Rd; 2027 bits<5> Rn; 2028 bits<5> Rm; 2029 let Inst{31-24} = 0b10011011; 2030 let Inst{23-21} = opc; 2031 let Inst{20-16} = Rm; 2032 let Inst{15} = 0; 2033 let Inst{9-5} = Rn; 2034 let Inst{4-0} = Rd; 2035 2036 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2037 // (i.e. all bits 1) but is ignored by the processor. 2038 let PostEncoderMethod = "fixMulHigh"; 2039} 2040 2041class MulAccumWAlias<string asm, Instruction inst> 2042 : InstAlias<asm#"\t$dst, $src1, $src2", 2043 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2044class MulAccumXAlias<string asm, Instruction inst> 2045 : InstAlias<asm#"\t$dst, $src1, $src2", 2046 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2047class WideMulAccumAlias<string asm, Instruction inst> 2048 : InstAlias<asm#"\t$dst, $src1, $src2", 2049 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2050 2051class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2052 SDPatternOperator OpNode, string asm> 2053 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2054 asm, "\t$Rd, $Rn, $Rm", "", 2055 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2056 Sched<[WriteISReg, ReadI, ReadISReg]> { 2057 bits<5> Rd; 2058 bits<5> Rn; 2059 bits<5> Rm; 2060 2061 let Inst{31} = sf; 2062 let Inst{30-21} = 0b0011010110; 2063 let Inst{20-16} = Rm; 2064 let Inst{15-13} = 0b010; 2065 let Inst{12} = C; 2066 let Inst{11-10} = sz; 2067 let Inst{9-5} = Rn; 2068 let Inst{4-0} = Rd; 2069 let Predicates = [HasCRC]; 2070} 2071 2072//--- 2073// Address generation. 2074//--- 2075 2076class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2077 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2078 pattern>, 2079 Sched<[WriteI]> { 2080 bits<5> Xd; 2081 bits<21> label; 2082 let Inst{31} = page; 2083 let Inst{30-29} = label{1-0}; 2084 let Inst{28-24} = 0b10000; 2085 let Inst{23-5} = label{20-2}; 2086 let Inst{4-0} = Xd; 2087 2088 let DecoderMethod = "DecodeAdrInstruction"; 2089} 2090 2091//--- 2092// Move immediate. 2093//--- 2094 2095def movimm32_imm : Operand<i32> { 2096 let ParserMatchClass = AsmImmRange<0, 65535>; 2097 let EncoderMethod = "getMoveWideImmOpValue"; 2098 let PrintMethod = "printImm"; 2099} 2100def movimm32_shift : Operand<i32> { 2101 let PrintMethod = "printShifter"; 2102 let ParserMatchClass = MovImm32ShifterOperand; 2103} 2104def movimm64_shift : Operand<i32> { 2105 let PrintMethod = "printShifter"; 2106 let ParserMatchClass = MovImm64ShifterOperand; 2107} 2108 2109let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2110class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2111 string asm> 2112 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2113 asm, "\t$Rd, $imm$shift", "", []>, 2114 Sched<[WriteImm]> { 2115 bits<5> Rd; 2116 bits<16> imm; 2117 bits<6> shift; 2118 let Inst{30-29} = opc; 2119 let Inst{28-23} = 0b100101; 2120 let Inst{22-21} = shift{5-4}; 2121 let Inst{20-5} = imm; 2122 let Inst{4-0} = Rd; 2123 2124 let DecoderMethod = "DecodeMoveImmInstruction"; 2125} 2126 2127multiclass MoveImmediate<bits<2> opc, string asm> { 2128 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2129 let Inst{31} = 0; 2130 } 2131 2132 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2133 let Inst{31} = 1; 2134 } 2135} 2136 2137let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2138class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2139 string asm> 2140 : I<(outs regtype:$Rd), 2141 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2142 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2143 Sched<[WriteI, ReadI]> { 2144 bits<5> Rd; 2145 bits<16> imm; 2146 bits<6> shift; 2147 let Inst{30-29} = opc; 2148 let Inst{28-23} = 0b100101; 2149 let Inst{22-21} = shift{5-4}; 2150 let Inst{20-5} = imm; 2151 let Inst{4-0} = Rd; 2152 2153 let DecoderMethod = "DecodeMoveImmInstruction"; 2154} 2155 2156multiclass InsertImmediate<bits<2> opc, string asm> { 2157 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2158 let Inst{31} = 0; 2159 } 2160 2161 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2162 let Inst{31} = 1; 2163 } 2164} 2165 2166//--- 2167// Add/Subtract 2168//--- 2169 2170class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2171 string asm_inst, string asm_ops, 2172 dag inputs, dag pattern> 2173 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2174 Sched<[WriteI, ReadI]> { 2175 bits<5> Rd; 2176 bits<5> Rn; 2177 let Inst{30} = isSub; 2178 let Inst{29} = setFlags; 2179 let Inst{28-24} = 0b10001; 2180 let Inst{9-5} = Rn; 2181 let Inst{4-0} = Rd; 2182} 2183 2184class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2185 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2186 string asm_inst, SDPatternOperator OpNode> 2187 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2188 (ins srcRegtype:$Rn, immtype:$imm), 2189 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2190 bits<14> imm; 2191 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2192 let Inst{21-10} = imm{11-0}; 2193 let DecoderMethod = "DecodeAddSubImmShift"; 2194} 2195 2196class BaseAddSubRegPseudo<RegisterClass regtype, 2197 SDPatternOperator OpNode> 2198 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2199 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2200 Sched<[WriteI, ReadI, ReadI]>; 2201 2202class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2203 arith_shifted_reg shifted_regtype, string asm, 2204 SDPatternOperator OpNode> 2205 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2206 asm, "\t$Rd, $Rn, $Rm", "", 2207 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2208 Sched<[WriteISReg, ReadI, ReadISReg]> { 2209 // The operands are in order to match the 'addr' MI operands, so we 2210 // don't need an encoder method and by-name matching. Just use the default 2211 // in-order handling. Since we're using by-order, make sure the names 2212 // do not match. 2213 bits<5> dst; 2214 bits<5> src1; 2215 bits<5> src2; 2216 bits<8> shift; 2217 let Inst{30} = isSub; 2218 let Inst{29} = setFlags; 2219 let Inst{28-24} = 0b01011; 2220 let Inst{23-22} = shift{7-6}; 2221 let Inst{21} = 0; 2222 let Inst{20-16} = src2; 2223 let Inst{15-10} = shift{5-0}; 2224 let Inst{9-5} = src1; 2225 let Inst{4-0} = dst; 2226 2227 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2228} 2229 2230class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2231 RegisterClass src1Regtype, Operand src2Regtype, 2232 string asm, SDPatternOperator OpNode> 2233 : I<(outs dstRegtype:$R1), 2234 (ins src1Regtype:$R2, src2Regtype:$R3), 2235 asm, "\t$R1, $R2, $R3", "", 2236 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2237 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2238 bits<5> Rd; 2239 bits<5> Rn; 2240 bits<5> Rm; 2241 bits<6> ext; 2242 let Inst{30} = isSub; 2243 let Inst{29} = setFlags; 2244 let Inst{28-24} = 0b01011; 2245 let Inst{23-21} = 0b001; 2246 let Inst{20-16} = Rm; 2247 let Inst{15-13} = ext{5-3}; 2248 let Inst{12-10} = ext{2-0}; 2249 let Inst{9-5} = Rn; 2250 let Inst{4-0} = Rd; 2251 2252 let DecoderMethod = "DecodeAddSubERegInstruction"; 2253} 2254 2255let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2256class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2257 RegisterClass src1Regtype, RegisterClass src2Regtype, 2258 Operand ext_op, string asm> 2259 : I<(outs dstRegtype:$Rd), 2260 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2261 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2262 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2263 bits<5> Rd; 2264 bits<5> Rn; 2265 bits<5> Rm; 2266 bits<6> ext; 2267 let Inst{30} = isSub; 2268 let Inst{29} = setFlags; 2269 let Inst{28-24} = 0b01011; 2270 let Inst{23-21} = 0b001; 2271 let Inst{20-16} = Rm; 2272 let Inst{15} = ext{5}; 2273 let Inst{12-10} = ext{2-0}; 2274 let Inst{9-5} = Rn; 2275 let Inst{4-0} = Rd; 2276 2277 let DecoderMethod = "DecodeAddSubERegInstruction"; 2278} 2279 2280// Aliases for register+register add/subtract. 2281class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2282 RegisterClass src1Regtype, RegisterClass src2Regtype, 2283 int shiftExt> 2284 : InstAlias<asm#"\t$dst, $src1, $src2", 2285 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2286 shiftExt)>; 2287 2288multiclass AddSub<bit isSub, string mnemonic, string alias, 2289 SDPatternOperator OpNode = null_frag> { 2290 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2291 // Add/Subtract immediate 2292 // Increase the weight of the immediate variant to try to match it before 2293 // the extended register variant. 2294 // We used to match the register variant before the immediate when the 2295 // register argument could be implicitly zero-extended. 2296 let AddedComplexity = 6 in 2297 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2298 mnemonic, OpNode> { 2299 let Inst{31} = 0; 2300 } 2301 let AddedComplexity = 6 in 2302 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2303 mnemonic, OpNode> { 2304 let Inst{31} = 1; 2305 } 2306 2307 // Add/Subtract register - Only used for CodeGen 2308 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2309 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2310 2311 // Add/Subtract shifted register 2312 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2313 OpNode> { 2314 let Inst{31} = 0; 2315 } 2316 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2317 OpNode> { 2318 let Inst{31} = 1; 2319 } 2320 } 2321 2322 // Add/Subtract extended register 2323 let AddedComplexity = 1, hasSideEffects = 0 in { 2324 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2325 arith_extended_reg32_i32, mnemonic, OpNode> { 2326 let Inst{31} = 0; 2327 } 2328 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2329 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2330 let Inst{31} = 1; 2331 } 2332 } 2333 2334 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2335 arith_extendlsl64, mnemonic> { 2336 // UXTX and SXTX only. 2337 let Inst{14-13} = 0b11; 2338 let Inst{31} = 1; 2339 } 2340 2341 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2342 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2343 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2344 addsub_shifted_imm32_neg:$imm), 0>; 2345 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2346 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2347 addsub_shifted_imm64_neg:$imm), 0>; 2348 2349 // Register/register aliases with no shift when SP is not used. 2350 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2351 GPR32, GPR32, GPR32, 0>; 2352 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2353 GPR64, GPR64, GPR64, 0>; 2354 2355 // Register/register aliases with no shift when either the destination or 2356 // first source register is SP. 2357 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2358 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2359 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2360 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2361 def : AddSubRegAlias<mnemonic, 2362 !cast<Instruction>(NAME#"Xrx64"), 2363 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2364 def : AddSubRegAlias<mnemonic, 2365 !cast<Instruction>(NAME#"Xrx64"), 2366 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2367} 2368 2369multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2370 string alias, string cmpAlias> { 2371 let isCompare = 1, Defs = [NZCV] in { 2372 // Add/Subtract immediate 2373 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2374 mnemonic, OpNode> { 2375 let Inst{31} = 0; 2376 } 2377 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2378 mnemonic, OpNode> { 2379 let Inst{31} = 1; 2380 } 2381 2382 // Add/Subtract register 2383 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2384 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2385 2386 // Add/Subtract shifted register 2387 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2388 OpNode> { 2389 let Inst{31} = 0; 2390 } 2391 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2392 OpNode> { 2393 let Inst{31} = 1; 2394 } 2395 2396 // Add/Subtract extended register 2397 let AddedComplexity = 1 in { 2398 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2399 arith_extended_reg32_i32, mnemonic, OpNode> { 2400 let Inst{31} = 0; 2401 } 2402 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2403 arith_extended_reg32_i64, mnemonic, OpNode> { 2404 let Inst{31} = 1; 2405 } 2406 } 2407 2408 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2409 arith_extendlsl64, mnemonic> { 2410 // UXTX and SXTX only. 2411 let Inst{14-13} = 0b11; 2412 let Inst{31} = 1; 2413 } 2414 } // Defs = [NZCV] 2415 2416 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2417 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2418 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2419 addsub_shifted_imm32_neg:$imm), 0>; 2420 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2421 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2422 addsub_shifted_imm64_neg:$imm), 0>; 2423 2424 // Compare aliases 2425 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2426 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2427 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2428 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2429 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2430 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2431 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2432 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2433 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2434 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2435 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2436 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2437 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2438 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2439 2440 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2441 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2442 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2443 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2444 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2445 2446 // Compare shorthands 2447 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2448 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2449 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2450 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2451 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2452 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2453 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2454 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2455 2456 // Register/register aliases with no shift when SP is not used. 2457 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2458 GPR32, GPR32, GPR32, 0>; 2459 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2460 GPR64, GPR64, GPR64, 0>; 2461 2462 // Register/register aliases with no shift when the first source register 2463 // is SP. 2464 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2465 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2466 def : AddSubRegAlias<mnemonic, 2467 !cast<Instruction>(NAME#"Xrx64"), 2468 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2469} 2470 2471class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2472 : BaseAddSubImm< 2473 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2474 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2475 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2476 bits<6> imm6; 2477 bits<4> imm4; 2478 let Inst{31} = 1; 2479 let Inst{23-22} = 0b10; 2480 let Inst{21-16} = imm6; 2481 let Inst{15-14} = 0b00; 2482 let Inst{13-10} = imm4; 2483 let Unpredictable{15-14} = 0b11; 2484} 2485 2486class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2487 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2488 let Inst{31} = 1; 2489 let Inst{29} = setsFlags; 2490} 2491 2492//--- 2493// Extract 2494//--- 2495def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2496 SDTCisPtrTy<3>]>; 2497def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2498 2499class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2500 list<dag> patterns> 2501 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2502 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2503 Sched<[WriteExtr, ReadExtrHi]> { 2504 bits<5> Rd; 2505 bits<5> Rn; 2506 bits<5> Rm; 2507 bits<6> imm; 2508 2509 let Inst{30-23} = 0b00100111; 2510 let Inst{21} = 0; 2511 let Inst{20-16} = Rm; 2512 let Inst{15-10} = imm; 2513 let Inst{9-5} = Rn; 2514 let Inst{4-0} = Rd; 2515} 2516 2517multiclass ExtractImm<string asm> { 2518 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2519 [(set GPR32:$Rd, 2520 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2521 let Inst{31} = 0; 2522 let Inst{22} = 0; 2523 // imm<5> must be zero. 2524 let imm{5} = 0; 2525 } 2526 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2527 [(set GPR64:$Rd, 2528 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2529 2530 let Inst{31} = 1; 2531 let Inst{22} = 1; 2532 } 2533} 2534 2535//--- 2536// Bitfield 2537//--- 2538 2539let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2540class BaseBitfieldImm<bits<2> opc, 2541 RegisterClass regtype, Operand imm_type, string asm> 2542 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2543 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2544 Sched<[WriteIS, ReadI]> { 2545 bits<5> Rd; 2546 bits<5> Rn; 2547 bits<6> immr; 2548 bits<6> imms; 2549 2550 let Inst{30-29} = opc; 2551 let Inst{28-23} = 0b100110; 2552 let Inst{21-16} = immr; 2553 let Inst{15-10} = imms; 2554 let Inst{9-5} = Rn; 2555 let Inst{4-0} = Rd; 2556} 2557 2558multiclass BitfieldImm<bits<2> opc, string asm> { 2559 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2560 let Inst{31} = 0; 2561 let Inst{22} = 0; 2562 // imms<5> and immr<5> must be zero, else ReservedValue(). 2563 let Inst{21} = 0; 2564 let Inst{15} = 0; 2565 } 2566 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2567 let Inst{31} = 1; 2568 let Inst{22} = 1; 2569 } 2570} 2571 2572let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2573class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2574 RegisterClass regtype, Operand imm_type, string asm> 2575 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2576 imm_type:$imms), 2577 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2578 Sched<[WriteIS, ReadI]> { 2579 bits<5> Rd; 2580 bits<5> Rn; 2581 bits<6> immr; 2582 bits<6> imms; 2583 2584 let Inst{30-29} = opc; 2585 let Inst{28-23} = 0b100110; 2586 let Inst{21-16} = immr; 2587 let Inst{15-10} = imms; 2588 let Inst{9-5} = Rn; 2589 let Inst{4-0} = Rd; 2590} 2591 2592multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2593 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2594 let Inst{31} = 0; 2595 let Inst{22} = 0; 2596 // imms<5> and immr<5> must be zero, else ReservedValue(). 2597 let Inst{21} = 0; 2598 let Inst{15} = 0; 2599 } 2600 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2601 let Inst{31} = 1; 2602 let Inst{22} = 1; 2603 } 2604} 2605 2606//--- 2607// Logical 2608//--- 2609 2610// Logical (immediate) 2611class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2612 RegisterClass sregtype, Operand imm_type, string asm, 2613 list<dag> pattern> 2614 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2615 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2616 Sched<[WriteI, ReadI]> { 2617 bits<5> Rd; 2618 bits<5> Rn; 2619 bits<13> imm; 2620 let Inst{30-29} = opc; 2621 let Inst{28-23} = 0b100100; 2622 let Inst{22} = imm{12}; 2623 let Inst{21-16} = imm{11-6}; 2624 let Inst{15-10} = imm{5-0}; 2625 let Inst{9-5} = Rn; 2626 let Inst{4-0} = Rd; 2627 2628 let DecoderMethod = "DecodeLogicalImmInstruction"; 2629} 2630 2631// Logical (shifted register) 2632class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2633 logical_shifted_reg shifted_regtype, string asm, 2634 list<dag> pattern> 2635 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2636 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2637 Sched<[WriteISReg, ReadI, ReadISReg]> { 2638 // The operands are in order to match the 'addr' MI operands, so we 2639 // don't need an encoder method and by-name matching. Just use the default 2640 // in-order handling. Since we're using by-order, make sure the names 2641 // do not match. 2642 bits<5> dst; 2643 bits<5> src1; 2644 bits<5> src2; 2645 bits<8> shift; 2646 let Inst{30-29} = opc; 2647 let Inst{28-24} = 0b01010; 2648 let Inst{23-22} = shift{7-6}; 2649 let Inst{21} = N; 2650 let Inst{20-16} = src2; 2651 let Inst{15-10} = shift{5-0}; 2652 let Inst{9-5} = src1; 2653 let Inst{4-0} = dst; 2654 2655 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2656} 2657 2658// Aliases for register+register logical instructions. 2659class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2660 : InstAlias<asm#"\t$dst, $src1, $src2", 2661 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2662 2663multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2664 string Alias> { 2665 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2666 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2667 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2668 logical_imm32:$imm))]> { 2669 let Inst{31} = 0; 2670 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2671 } 2672 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2673 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2674 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2675 logical_imm64:$imm))]> { 2676 let Inst{31} = 1; 2677 } 2678 2679 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2680 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2681 logical_imm32_not:$imm), 0>; 2682 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2683 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2684 logical_imm64_not:$imm), 0>; 2685} 2686 2687multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2688 string Alias> { 2689 let isCompare = 1, Defs = [NZCV] in { 2690 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2691 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2692 let Inst{31} = 0; 2693 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2694 } 2695 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2696 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2697 let Inst{31} = 1; 2698 } 2699 } // end Defs = [NZCV] 2700 2701 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2702 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2703 logical_imm32_not:$imm), 0>; 2704 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2705 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2706 logical_imm64_not:$imm), 0>; 2707} 2708 2709class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2710 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2711 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2712 Sched<[WriteI, ReadI, ReadI]>; 2713 2714// Split from LogicalImm as not all instructions have both. 2715multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2716 SDPatternOperator OpNode> { 2717 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2718 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2719 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2720 } 2721 2722 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2723 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2724 logical_shifted_reg32:$Rm))]> { 2725 let Inst{31} = 0; 2726 } 2727 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2728 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2729 logical_shifted_reg64:$Rm))]> { 2730 let Inst{31} = 1; 2731 } 2732 2733 def : LogicalRegAlias<mnemonic, 2734 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2735 def : LogicalRegAlias<mnemonic, 2736 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2737} 2738 2739// Split from LogicalReg to allow setting NZCV Defs 2740multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2741 SDPatternOperator OpNode = null_frag> { 2742 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2743 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2744 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2745 2746 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2747 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2748 let Inst{31} = 0; 2749 } 2750 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2751 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2752 let Inst{31} = 1; 2753 } 2754 } // Defs = [NZCV] 2755 2756 def : LogicalRegAlias<mnemonic, 2757 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2758 def : LogicalRegAlias<mnemonic, 2759 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2760} 2761 2762//--- 2763// Conditionally set flags 2764//--- 2765 2766let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2767class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2768 string mnemonic, SDNode OpNode> 2769 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2770 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2771 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2772 (i32 imm:$cond), NZCV))]>, 2773 Sched<[WriteI, ReadI]> { 2774 let Uses = [NZCV]; 2775 let Defs = [NZCV]; 2776 2777 bits<5> Rn; 2778 bits<5> imm; 2779 bits<4> nzcv; 2780 bits<4> cond; 2781 2782 let Inst{30} = op; 2783 let Inst{29-21} = 0b111010010; 2784 let Inst{20-16} = imm; 2785 let Inst{15-12} = cond; 2786 let Inst{11-10} = 0b10; 2787 let Inst{9-5} = Rn; 2788 let Inst{4} = 0b0; 2789 let Inst{3-0} = nzcv; 2790} 2791 2792let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2793class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2794 SDNode OpNode> 2795 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2796 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2797 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2798 (i32 imm:$cond), NZCV))]>, 2799 Sched<[WriteI, ReadI, ReadI]> { 2800 let Uses = [NZCV]; 2801 let Defs = [NZCV]; 2802 2803 bits<5> Rn; 2804 bits<5> Rm; 2805 bits<4> nzcv; 2806 bits<4> cond; 2807 2808 let Inst{30} = op; 2809 let Inst{29-21} = 0b111010010; 2810 let Inst{20-16} = Rm; 2811 let Inst{15-12} = cond; 2812 let Inst{11-10} = 0b00; 2813 let Inst{9-5} = Rn; 2814 let Inst{4} = 0b0; 2815 let Inst{3-0} = nzcv; 2816} 2817 2818multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 2819 // immediate operand variants 2820 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 2821 let Inst{31} = 0; 2822 } 2823 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 2824 let Inst{31} = 1; 2825 } 2826 // register operand variants 2827 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 2828 let Inst{31} = 0; 2829 } 2830 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 2831 let Inst{31} = 1; 2832 } 2833} 2834 2835//--- 2836// Conditional select 2837//--- 2838 2839class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 2840 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2841 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2842 [(set regtype:$Rd, 2843 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 2844 Sched<[WriteI, ReadI, ReadI]> { 2845 let Uses = [NZCV]; 2846 2847 bits<5> Rd; 2848 bits<5> Rn; 2849 bits<5> Rm; 2850 bits<4> cond; 2851 2852 let Inst{30} = op; 2853 let Inst{29-21} = 0b011010100; 2854 let Inst{20-16} = Rm; 2855 let Inst{15-12} = cond; 2856 let Inst{11-10} = op2; 2857 let Inst{9-5} = Rn; 2858 let Inst{4-0} = Rd; 2859} 2860 2861multiclass CondSelect<bit op, bits<2> op2, string asm> { 2862 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 2863 let Inst{31} = 0; 2864 } 2865 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 2866 let Inst{31} = 1; 2867 } 2868} 2869 2870class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 2871 PatFrag frag> 2872 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2873 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2874 [(set regtype:$Rd, 2875 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 2876 (i32 imm:$cond), NZCV))]>, 2877 Sched<[WriteI, ReadI, ReadI]> { 2878 let Uses = [NZCV]; 2879 2880 bits<5> Rd; 2881 bits<5> Rn; 2882 bits<5> Rm; 2883 bits<4> cond; 2884 2885 let Inst{30} = op; 2886 let Inst{29-21} = 0b011010100; 2887 let Inst{20-16} = Rm; 2888 let Inst{15-12} = cond; 2889 let Inst{11-10} = op2; 2890 let Inst{9-5} = Rn; 2891 let Inst{4-0} = Rd; 2892} 2893 2894def inv_cond_XFORM : SDNodeXForm<imm, [{ 2895 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 2896 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 2897 MVT::i32); 2898}]>; 2899 2900multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 2901 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 2902 let Inst{31} = 0; 2903 } 2904 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 2905 let Inst{31} = 1; 2906 } 2907 2908 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 2909 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 2910 (inv_cond_XFORM imm:$cond))>; 2911 2912 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 2913 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 2914 (inv_cond_XFORM imm:$cond))>; 2915} 2916 2917//--- 2918// Special Mask Value 2919//--- 2920def maski8_or_more : Operand<i32>, 2921 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 2922} 2923def maski16_or_more : Operand<i32>, 2924 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 2925} 2926 2927 2928//--- 2929// Load/store 2930//--- 2931 2932// (unsigned immediate) 2933// Indexed for 8-bit registers. offset is in range [0,4095]. 2934def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 2935def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 2936def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 2937def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 2938def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 2939 2940def gi_am_indexed8 : 2941 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 2942 GIComplexPatternEquiv<am_indexed8>; 2943def gi_am_indexed16 : 2944 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 2945 GIComplexPatternEquiv<am_indexed16>; 2946def gi_am_indexed32 : 2947 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 2948 GIComplexPatternEquiv<am_indexed32>; 2949def gi_am_indexed64 : 2950 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 2951 GIComplexPatternEquiv<am_indexed64>; 2952def gi_am_indexed128 : 2953 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 2954 GIComplexPatternEquiv<am_indexed128>; 2955 2956class UImm12OffsetOperand<int Scale> : AsmOperandClass { 2957 let Name = "UImm12Offset" # Scale; 2958 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 2959 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 2960 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 2961} 2962 2963def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 2964def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 2965def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 2966def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 2967def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 2968 2969class uimm12_scaled<int Scale> : Operand<i64> { 2970 let ParserMatchClass 2971 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 2972 let EncoderMethod 2973 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 2974 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 2975} 2976 2977def uimm12s1 : uimm12_scaled<1>; 2978def uimm12s2 : uimm12_scaled<2>; 2979def uimm12s4 : uimm12_scaled<4>; 2980def uimm12s8 : uimm12_scaled<8>; 2981def uimm12s16 : uimm12_scaled<16>; 2982 2983class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2984 string asm, list<dag> pattern> 2985 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 2986 bits<5> Rt; 2987 2988 bits<5> Rn; 2989 bits<12> offset; 2990 2991 let Inst{31-30} = sz; 2992 let Inst{29-27} = 0b111; 2993 let Inst{26} = V; 2994 let Inst{25-24} = 0b01; 2995 let Inst{23-22} = opc; 2996 let Inst{21-10} = offset; 2997 let Inst{9-5} = Rn; 2998 let Inst{4-0} = Rt; 2999 3000 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3001} 3002 3003multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3004 Operand indextype, string asm, list<dag> pattern> { 3005 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3006 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3007 (ins GPR64sp:$Rn, indextype:$offset), 3008 asm, pattern>, 3009 Sched<[WriteLD]>; 3010 3011 def : InstAlias<asm # "\t$Rt, [$Rn]", 3012 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3013} 3014 3015multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3016 Operand indextype, string asm, list<dag> pattern> { 3017 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3018 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3019 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3020 asm, pattern>, 3021 Sched<[WriteST]>; 3022 3023 def : InstAlias<asm # "\t$Rt, [$Rn]", 3024 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3025} 3026 3027// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3028// substitute zero-registers automatically. 3029// 3030// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3031// into StoreUI. 3032multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3033 Operand indextype, string asm, list<dag> pattern> { 3034 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3035 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3036 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3037 asm, pattern>, 3038 Sched<[WriteST]>; 3039 3040 def : InstAlias<asm # "\t$Rt, [$Rn]", 3041 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3042} 3043 3044def PrefetchOperand : AsmOperandClass { 3045 let Name = "Prefetch"; 3046 let ParserMethod = "tryParsePrefetch"; 3047} 3048def prfop : Operand<i32> { 3049 let PrintMethod = "printPrefetchOp"; 3050 let ParserMatchClass = PrefetchOperand; 3051} 3052 3053let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3054class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3055 : BaseLoadStoreUI<sz, V, opc, 3056 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3057 asm, pat>, 3058 Sched<[WriteLD]>; 3059 3060//--- 3061// Load literal 3062//--- 3063 3064// Load literal address: 19-bit immediate. The low two bits of the target 3065// offset are implied zero and so are not part of the immediate. 3066def am_ldrlit : Operand<iPTR> { 3067 let EncoderMethod = "getLoadLiteralOpValue"; 3068 let DecoderMethod = "DecodePCRelLabel19"; 3069 let PrintMethod = "printAlignedLabel"; 3070 let ParserMatchClass = PCRelLabel19Operand; 3071 let OperandType = "OPERAND_PCREL"; 3072} 3073 3074let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3075class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3076 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3077 asm, "\t$Rt, $label", "", pat>, 3078 Sched<[WriteLD]> { 3079 bits<5> Rt; 3080 bits<19> label; 3081 let Inst{31-30} = opc; 3082 let Inst{29-27} = 0b011; 3083 let Inst{26} = V; 3084 let Inst{25-24} = 0b00; 3085 let Inst{23-5} = label; 3086 let Inst{4-0} = Rt; 3087} 3088 3089let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3090class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3091 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3092 asm, "\t$Rt, $label", "", pat>, 3093 Sched<[WriteLD]> { 3094 bits<5> Rt; 3095 bits<19> label; 3096 let Inst{31-30} = opc; 3097 let Inst{29-27} = 0b011; 3098 let Inst{26} = V; 3099 let Inst{25-24} = 0b00; 3100 let Inst{23-5} = label; 3101 let Inst{4-0} = Rt; 3102} 3103 3104//--- 3105// Load/store register offset 3106//--- 3107 3108def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 3109def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 3110def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 3111def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 3112def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 3113 3114def gi_ro_Xindexed8 : 3115 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3116 GIComplexPatternEquiv<ro_Xindexed8>; 3117def gi_ro_Xindexed16 : 3118 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3119 GIComplexPatternEquiv<ro_Xindexed16>; 3120def gi_ro_Xindexed32 : 3121 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3122 GIComplexPatternEquiv<ro_Xindexed32>; 3123def gi_ro_Xindexed64 : 3124 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3125 GIComplexPatternEquiv<ro_Xindexed64>; 3126def gi_ro_Xindexed128 : 3127 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3128 GIComplexPatternEquiv<ro_Xindexed128>; 3129 3130def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 3131def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 3132def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 3133def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 3134def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 3135 3136def gi_ro_Windexed8 : 3137 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3138 GIComplexPatternEquiv<ro_Windexed8>; 3139def gi_ro_Windexed16 : 3140 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3141 GIComplexPatternEquiv<ro_Windexed16>; 3142def gi_ro_Windexed32 : 3143 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3144 GIComplexPatternEquiv<ro_Windexed32>; 3145def gi_ro_Windexed64 : 3146 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3147 GIComplexPatternEquiv<ro_Windexed64>; 3148def gi_ro_Windexed128 : 3149 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3150 GIComplexPatternEquiv<ro_Windexed128>; 3151 3152class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3153 let Name = "Mem" # Reg # "Extend" # Width; 3154 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3155 let RenderMethod = "addMemExtendOperands"; 3156 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3157} 3158 3159def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3160 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3161 // the trivial shift. 3162 let RenderMethod = "addMemExtend8Operands"; 3163} 3164def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3165def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3166def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3167def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3168 3169def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3170 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3171 // the trivial shift. 3172 let RenderMethod = "addMemExtend8Operands"; 3173} 3174def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3175def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3176def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3177def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3178 3179class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3180 : Operand<i32> { 3181 let ParserMatchClass = ParserClass; 3182 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3183 let DecoderMethod = "DecodeMemExtend"; 3184 let EncoderMethod = "getMemExtendOpValue"; 3185 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3186} 3187 3188def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3189def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3190def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3191def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3192def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3193 3194def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3195def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3196def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3197def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3198def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3199 3200class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3201 Operand wextend, Operand xextend> { 3202 // CodeGen-level pattern covering the entire addressing mode. 3203 ComplexPattern Wpat = windex; 3204 ComplexPattern Xpat = xindex; 3205 3206 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3207 Operand Wext = wextend; 3208 Operand Xext = xextend; 3209} 3210 3211def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3212def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3213def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3214def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3215def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3216 ro_Xextend128>; 3217 3218class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3219 string asm, dag ins, dag outs, list<dag> pat> 3220 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3221 bits<5> Rt; 3222 bits<5> Rn; 3223 bits<5> Rm; 3224 bits<2> extend; 3225 let Inst{31-30} = sz; 3226 let Inst{29-27} = 0b111; 3227 let Inst{26} = V; 3228 let Inst{25-24} = 0b00; 3229 let Inst{23-22} = opc; 3230 let Inst{21} = 1; 3231 let Inst{20-16} = Rm; 3232 let Inst{15} = extend{1}; // sign extend Rm? 3233 let Inst{14} = 1; 3234 let Inst{12} = extend{0}; // do shift? 3235 let Inst{11-10} = 0b10; 3236 let Inst{9-5} = Rn; 3237 let Inst{4-0} = Rt; 3238} 3239 3240class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST> 3241 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3242 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3243 3244multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3245 string asm, ValueType Ty, SDPatternOperator loadop> { 3246 let AddedComplexity = 10 in 3247 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 3248 (outs regtype:$Rt), 3249 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3250 [(set (Ty regtype:$Rt), 3251 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3252 ro_Wextend8:$extend)))]>, 3253 Sched<[WriteLDIdx, ReadAdrBase]> { 3254 let Inst{13} = 0b0; 3255 } 3256 3257 let AddedComplexity = 10 in 3258 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 3259 (outs regtype:$Rt), 3260 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3261 [(set (Ty regtype:$Rt), 3262 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3263 ro_Xextend8:$extend)))]>, 3264 Sched<[WriteLDIdx, ReadAdrBase]> { 3265 let Inst{13} = 0b1; 3266 } 3267 3268 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3269} 3270 3271multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3272 string asm, ValueType Ty, SDPatternOperator storeop> { 3273 let AddedComplexity = 10 in 3274 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3275 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3276 [(storeop (Ty regtype:$Rt), 3277 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3278 ro_Wextend8:$extend))]>, 3279 Sched<[WriteSTIdx, ReadAdrBase]> { 3280 let Inst{13} = 0b0; 3281 } 3282 3283 let AddedComplexity = 10 in 3284 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3285 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3286 [(storeop (Ty regtype:$Rt), 3287 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3288 ro_Xextend8:$extend))]>, 3289 Sched<[WriteSTIdx, ReadAdrBase]> { 3290 let Inst{13} = 0b1; 3291 } 3292 3293 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3294} 3295 3296class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3297 string asm, dag ins, dag outs, list<dag> pat> 3298 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3299 bits<5> Rt; 3300 bits<5> Rn; 3301 bits<5> Rm; 3302 bits<2> extend; 3303 let Inst{31-30} = sz; 3304 let Inst{29-27} = 0b111; 3305 let Inst{26} = V; 3306 let Inst{25-24} = 0b00; 3307 let Inst{23-22} = opc; 3308 let Inst{21} = 1; 3309 let Inst{20-16} = Rm; 3310 let Inst{15} = extend{1}; // sign extend Rm? 3311 let Inst{14} = 1; 3312 let Inst{12} = extend{0}; // do shift? 3313 let Inst{11-10} = 0b10; 3314 let Inst{9-5} = Rn; 3315 let Inst{4-0} = Rt; 3316} 3317 3318multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3319 string asm, ValueType Ty, SDPatternOperator loadop> { 3320 let AddedComplexity = 10 in 3321 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3322 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3323 [(set (Ty regtype:$Rt), 3324 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3325 ro_Wextend16:$extend)))]>, 3326 Sched<[WriteLDIdx, ReadAdrBase]> { 3327 let Inst{13} = 0b0; 3328 } 3329 3330 let AddedComplexity = 10 in 3331 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3332 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3333 [(set (Ty regtype:$Rt), 3334 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3335 ro_Xextend16:$extend)))]>, 3336 Sched<[WriteLDIdx, ReadAdrBase]> { 3337 let Inst{13} = 0b1; 3338 } 3339 3340 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3341} 3342 3343multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3344 string asm, ValueType Ty, SDPatternOperator storeop> { 3345 let AddedComplexity = 10 in 3346 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3347 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3348 [(storeop (Ty regtype:$Rt), 3349 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3350 ro_Wextend16:$extend))]>, 3351 Sched<[WriteSTIdx, ReadAdrBase]> { 3352 let Inst{13} = 0b0; 3353 } 3354 3355 let AddedComplexity = 10 in 3356 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3357 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3358 [(storeop (Ty regtype:$Rt), 3359 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3360 ro_Xextend16:$extend))]>, 3361 Sched<[WriteSTIdx, ReadAdrBase]> { 3362 let Inst{13} = 0b1; 3363 } 3364 3365 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3366} 3367 3368class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3369 string asm, dag ins, dag outs, list<dag> pat> 3370 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3371 bits<5> Rt; 3372 bits<5> Rn; 3373 bits<5> Rm; 3374 bits<2> extend; 3375 let Inst{31-30} = sz; 3376 let Inst{29-27} = 0b111; 3377 let Inst{26} = V; 3378 let Inst{25-24} = 0b00; 3379 let Inst{23-22} = opc; 3380 let Inst{21} = 1; 3381 let Inst{20-16} = Rm; 3382 let Inst{15} = extend{1}; // sign extend Rm? 3383 let Inst{14} = 1; 3384 let Inst{12} = extend{0}; // do shift? 3385 let Inst{11-10} = 0b10; 3386 let Inst{9-5} = Rn; 3387 let Inst{4-0} = Rt; 3388} 3389 3390multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3391 string asm, ValueType Ty, SDPatternOperator loadop> { 3392 let AddedComplexity = 10 in 3393 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3394 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3395 [(set (Ty regtype:$Rt), 3396 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3397 ro_Wextend32:$extend)))]>, 3398 Sched<[WriteLDIdx, ReadAdrBase]> { 3399 let Inst{13} = 0b0; 3400 } 3401 3402 let AddedComplexity = 10 in 3403 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3404 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3405 [(set (Ty regtype:$Rt), 3406 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3407 ro_Xextend32:$extend)))]>, 3408 Sched<[WriteLDIdx, ReadAdrBase]> { 3409 let Inst{13} = 0b1; 3410 } 3411 3412 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3413} 3414 3415multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3416 string asm, ValueType Ty, SDPatternOperator storeop> { 3417 let AddedComplexity = 10 in 3418 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3419 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3420 [(storeop (Ty regtype:$Rt), 3421 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3422 ro_Wextend32:$extend))]>, 3423 Sched<[WriteSTIdx, ReadAdrBase]> { 3424 let Inst{13} = 0b0; 3425 } 3426 3427 let AddedComplexity = 10 in 3428 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3429 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3430 [(storeop (Ty regtype:$Rt), 3431 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3432 ro_Xextend32:$extend))]>, 3433 Sched<[WriteSTIdx, ReadAdrBase]> { 3434 let Inst{13} = 0b1; 3435 } 3436 3437 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3438} 3439 3440class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3441 string asm, dag ins, dag outs, list<dag> pat> 3442 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3443 bits<5> Rt; 3444 bits<5> Rn; 3445 bits<5> Rm; 3446 bits<2> extend; 3447 let Inst{31-30} = sz; 3448 let Inst{29-27} = 0b111; 3449 let Inst{26} = V; 3450 let Inst{25-24} = 0b00; 3451 let Inst{23-22} = opc; 3452 let Inst{21} = 1; 3453 let Inst{20-16} = Rm; 3454 let Inst{15} = extend{1}; // sign extend Rm? 3455 let Inst{14} = 1; 3456 let Inst{12} = extend{0}; // do shift? 3457 let Inst{11-10} = 0b10; 3458 let Inst{9-5} = Rn; 3459 let Inst{4-0} = Rt; 3460} 3461 3462multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3463 string asm, ValueType Ty, SDPatternOperator loadop> { 3464 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3465 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3466 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3467 [(set (Ty regtype:$Rt), 3468 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3469 ro_Wextend64:$extend)))]>, 3470 Sched<[WriteLDIdx, ReadAdrBase]> { 3471 let Inst{13} = 0b0; 3472 } 3473 3474 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3475 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3476 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3477 [(set (Ty regtype:$Rt), 3478 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3479 ro_Xextend64:$extend)))]>, 3480 Sched<[WriteLDIdx, ReadAdrBase]> { 3481 let Inst{13} = 0b1; 3482 } 3483 3484 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3485} 3486 3487multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3488 string asm, ValueType Ty, SDPatternOperator storeop> { 3489 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3490 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3491 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3492 [(storeop (Ty regtype:$Rt), 3493 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3494 ro_Wextend64:$extend))]>, 3495 Sched<[WriteSTIdx, ReadAdrBase]> { 3496 let Inst{13} = 0b0; 3497 } 3498 3499 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3500 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3501 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3502 [(storeop (Ty regtype:$Rt), 3503 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3504 ro_Xextend64:$extend))]>, 3505 Sched<[WriteSTIdx, ReadAdrBase]> { 3506 let Inst{13} = 0b1; 3507 } 3508 3509 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3510} 3511 3512class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3513 string asm, dag ins, dag outs, list<dag> pat> 3514 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3515 bits<5> Rt; 3516 bits<5> Rn; 3517 bits<5> Rm; 3518 bits<2> extend; 3519 let Inst{31-30} = sz; 3520 let Inst{29-27} = 0b111; 3521 let Inst{26} = V; 3522 let Inst{25-24} = 0b00; 3523 let Inst{23-22} = opc; 3524 let Inst{21} = 1; 3525 let Inst{20-16} = Rm; 3526 let Inst{15} = extend{1}; // sign extend Rm? 3527 let Inst{14} = 1; 3528 let Inst{12} = extend{0}; // do shift? 3529 let Inst{11-10} = 0b10; 3530 let Inst{9-5} = Rn; 3531 let Inst{4-0} = Rt; 3532} 3533 3534multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3535 string asm, ValueType Ty, SDPatternOperator loadop> { 3536 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3537 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3538 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3539 [(set (Ty regtype:$Rt), 3540 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3541 ro_Wextend128:$extend)))]>, 3542 Sched<[WriteLDIdx, ReadAdrBase]> { 3543 let Inst{13} = 0b0; 3544 } 3545 3546 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3547 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3548 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3549 [(set (Ty regtype:$Rt), 3550 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3551 ro_Xextend128:$extend)))]>, 3552 Sched<[WriteLDIdx, ReadAdrBase]> { 3553 let Inst{13} = 0b1; 3554 } 3555 3556 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3557} 3558 3559multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3560 string asm, ValueType Ty, SDPatternOperator storeop> { 3561 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3562 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3563 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3564 []>, 3565 Sched<[WriteSTIdx, ReadAdrBase]> { 3566 let Inst{13} = 0b0; 3567 } 3568 3569 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3570 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3571 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3572 []>, 3573 Sched<[WriteSTIdx, ReadAdrBase]> { 3574 let Inst{13} = 0b1; 3575 } 3576 3577 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3578} 3579 3580let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3581class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3582 string asm, list<dag> pat> 3583 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3584 Sched<[WriteLD]> { 3585 bits<5> Rt; 3586 bits<5> Rn; 3587 bits<5> Rm; 3588 bits<2> extend; 3589 let Inst{31-30} = sz; 3590 let Inst{29-27} = 0b111; 3591 let Inst{26} = V; 3592 let Inst{25-24} = 0b00; 3593 let Inst{23-22} = opc; 3594 let Inst{21} = 1; 3595 let Inst{20-16} = Rm; 3596 let Inst{15} = extend{1}; // sign extend Rm? 3597 let Inst{14} = 1; 3598 let Inst{12} = extend{0}; // do shift? 3599 let Inst{11-10} = 0b10; 3600 let Inst{9-5} = Rn; 3601 let Inst{4-0} = Rt; 3602} 3603 3604multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3605 def roW : BasePrefetchRO<sz, V, opc, (outs), 3606 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3607 asm, [(AArch64Prefetch imm:$Rt, 3608 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3609 ro_Wextend64:$extend))]> { 3610 let Inst{13} = 0b0; 3611 } 3612 3613 def roX : BasePrefetchRO<sz, V, opc, (outs), 3614 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3615 asm, [(AArch64Prefetch imm:$Rt, 3616 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3617 ro_Xextend64:$extend))]> { 3618 let Inst{13} = 0b1; 3619 } 3620 3621 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3622 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3623 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3624} 3625 3626//--- 3627// Load/store unscaled immediate 3628//--- 3629 3630def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 3631def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 3632def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 3633def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 3634def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3635 3636def gi_am_unscaled8 : 3637 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3638 GIComplexPatternEquiv<am_unscaled8>; 3639def gi_am_unscaled16 : 3640 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3641 GIComplexPatternEquiv<am_unscaled16>; 3642def gi_am_unscaled32 : 3643 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3644 GIComplexPatternEquiv<am_unscaled32>; 3645def gi_am_unscaled64 : 3646 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3647 GIComplexPatternEquiv<am_unscaled64>; 3648def gi_am_unscaled128 : 3649 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3650 GIComplexPatternEquiv<am_unscaled128>; 3651 3652 3653class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3654 string asm, list<dag> pattern> 3655 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3656 bits<5> Rt; 3657 bits<5> Rn; 3658 bits<9> offset; 3659 let Inst{31-30} = sz; 3660 let Inst{29-27} = 0b111; 3661 let Inst{26} = V; 3662 let Inst{25-24} = 0b00; 3663 let Inst{23-22} = opc; 3664 let Inst{21} = 0; 3665 let Inst{20-12} = offset; 3666 let Inst{11-10} = 0b00; 3667 let Inst{9-5} = Rn; 3668 let Inst{4-0} = Rt; 3669 3670 let DecoderMethod = "DecodeSignedLdStInstruction"; 3671} 3672 3673// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3674multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3675 RegisterOperand regtype > { 3676 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3677 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3678 Sched<[WriteST]> { 3679 let Inst{29} = 0; 3680 let Inst{24} = 1; 3681 } 3682 def : InstAlias<asm # "\t$Rt, [$Rn]", 3683 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3684} 3685 3686multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3687 RegisterOperand regtype > { 3688 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3689 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3690 asm, []>, 3691 Sched<[WriteST]> { 3692 let Inst{29} = 0; 3693 let Inst{24} = 1; 3694 } 3695 def : InstAlias<asm # "\t$Rt, [$Rn]", 3696 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3697} 3698 3699multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3700 string asm, list<dag> pattern> { 3701 let AddedComplexity = 1 in // try this before LoadUI 3702 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3703 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3704 Sched<[WriteLD]>; 3705 3706 def : InstAlias<asm # "\t$Rt, [$Rn]", 3707 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3708} 3709 3710multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3711 string asm, list<dag> pattern> { 3712 let AddedComplexity = 1 in // try this before StoreUI 3713 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3714 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3715 asm, pattern>, 3716 Sched<[WriteST]>; 3717 3718 def : InstAlias<asm # "\t$Rt, [$Rn]", 3719 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3720} 3721 3722multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3723 list<dag> pat> { 3724 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3725 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3726 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3727 asm, pat>, 3728 Sched<[WriteLD]>; 3729 3730 def : InstAlias<asm # "\t$Rt, [$Rn]", 3731 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3732} 3733 3734//--- 3735// Load/store unscaled immediate, unprivileged 3736//--- 3737 3738class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3739 dag oops, dag iops, string asm> 3740 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3741 bits<5> Rt; 3742 bits<5> Rn; 3743 bits<9> offset; 3744 let Inst{31-30} = sz; 3745 let Inst{29-27} = 0b111; 3746 let Inst{26} = V; 3747 let Inst{25-24} = 0b00; 3748 let Inst{23-22} = opc; 3749 let Inst{21} = 0; 3750 let Inst{20-12} = offset; 3751 let Inst{11-10} = 0b10; 3752 let Inst{9-5} = Rn; 3753 let Inst{4-0} = Rt; 3754 3755 let DecoderMethod = "DecodeSignedLdStInstruction"; 3756} 3757 3758multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3759 RegisterClass regtype, string asm> { 3760 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3761 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3762 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3763 Sched<[WriteLD]>; 3764 3765 def : InstAlias<asm # "\t$Rt, [$Rn]", 3766 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3767} 3768 3769multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3770 RegisterClass regtype, string asm> { 3771 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3772 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3773 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3774 asm>, 3775 Sched<[WriteST]>; 3776 3777 def : InstAlias<asm # "\t$Rt, [$Rn]", 3778 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3779} 3780 3781//--- 3782// Load/store pre-indexed 3783//--- 3784 3785class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3786 string asm, string cstr, list<dag> pat> 3787 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3788 bits<5> Rt; 3789 bits<5> Rn; 3790 bits<9> offset; 3791 let Inst{31-30} = sz; 3792 let Inst{29-27} = 0b111; 3793 let Inst{26} = V; 3794 let Inst{25-24} = 0; 3795 let Inst{23-22} = opc; 3796 let Inst{21} = 0; 3797 let Inst{20-12} = offset; 3798 let Inst{11-10} = 0b11; 3799 let Inst{9-5} = Rn; 3800 let Inst{4-0} = Rt; 3801 3802 let DecoderMethod = "DecodeSignedLdStInstruction"; 3803} 3804 3805let hasSideEffects = 0 in { 3806let mayStore = 0, mayLoad = 1 in 3807class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3808 string asm> 3809 : BaseLoadStorePreIdx<sz, V, opc, 3810 (outs GPR64sp:$wback, regtype:$Rt), 3811 (ins GPR64sp:$Rn, simm9:$offset), asm, 3812 "$Rn = $wback,@earlyclobber $wback", []>, 3813 Sched<[WriteLD, WriteAdr]>; 3814 3815let mayStore = 1, mayLoad = 0 in 3816class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3817 string asm, SDPatternOperator storeop, ValueType Ty> 3818 : BaseLoadStorePreIdx<sz, V, opc, 3819 (outs GPR64sp:$wback), 3820 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3821 asm, "$Rn = $wback,@earlyclobber $wback", 3822 [(set GPR64sp:$wback, 3823 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3824 Sched<[WriteAdr, WriteST]>; 3825} // hasSideEffects = 0 3826 3827//--- 3828// Load/store post-indexed 3829//--- 3830 3831class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3832 string asm, string cstr, list<dag> pat> 3833 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3834 bits<5> Rt; 3835 bits<5> Rn; 3836 bits<9> offset; 3837 let Inst{31-30} = sz; 3838 let Inst{29-27} = 0b111; 3839 let Inst{26} = V; 3840 let Inst{25-24} = 0b00; 3841 let Inst{23-22} = opc; 3842 let Inst{21} = 0b0; 3843 let Inst{20-12} = offset; 3844 let Inst{11-10} = 0b01; 3845 let Inst{9-5} = Rn; 3846 let Inst{4-0} = Rt; 3847 3848 let DecoderMethod = "DecodeSignedLdStInstruction"; 3849} 3850 3851let hasSideEffects = 0 in { 3852let mayStore = 0, mayLoad = 1 in 3853class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3854 string asm> 3855 : BaseLoadStorePostIdx<sz, V, opc, 3856 (outs GPR64sp:$wback, regtype:$Rt), 3857 (ins GPR64sp:$Rn, simm9:$offset), 3858 asm, "$Rn = $wback,@earlyclobber $wback", []>, 3859 Sched<[WriteLD, WriteAdr]>; 3860 3861let mayStore = 1, mayLoad = 0 in 3862class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3863 string asm, SDPatternOperator storeop, ValueType Ty> 3864 : BaseLoadStorePostIdx<sz, V, opc, 3865 (outs GPR64sp:$wback), 3866 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3867 asm, "$Rn = $wback,@earlyclobber $wback", 3868 [(set GPR64sp:$wback, 3869 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3870 Sched<[WriteAdr, WriteST]>; 3871} // hasSideEffects = 0 3872 3873 3874//--- 3875// Load/store pair 3876//--- 3877 3878// (indexed, offset) 3879 3880class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 3881 string asm> 3882 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3883 bits<5> Rt; 3884 bits<5> Rt2; 3885 bits<5> Rn; 3886 bits<7> offset; 3887 let Inst{31-30} = opc; 3888 let Inst{29-27} = 0b101; 3889 let Inst{26} = V; 3890 let Inst{25-23} = 0b010; 3891 let Inst{22} = L; 3892 let Inst{21-15} = offset; 3893 let Inst{14-10} = Rt2; 3894 let Inst{9-5} = Rn; 3895 let Inst{4-0} = Rt; 3896 3897 let DecoderMethod = "DecodePairLdStInstruction"; 3898} 3899 3900multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 3901 Operand indextype, string asm> { 3902 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3903 def i : BaseLoadStorePairOffset<opc, V, 1, 3904 (outs regtype:$Rt, regtype:$Rt2), 3905 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3906 Sched<[WriteLD, WriteLDHi]>; 3907 3908 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3909 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3910 GPR64sp:$Rn, 0)>; 3911} 3912 3913 3914multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 3915 Operand indextype, string asm> { 3916 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 3917 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 3918 (ins regtype:$Rt, regtype:$Rt2, 3919 GPR64sp:$Rn, indextype:$offset), 3920 asm>, 3921 Sched<[WriteSTP]>; 3922 3923 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3924 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3925 GPR64sp:$Rn, 0)>; 3926} 3927 3928// (pre-indexed) 3929class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3930 string asm> 3931 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 3932 bits<5> Rt; 3933 bits<5> Rt2; 3934 bits<5> Rn; 3935 bits<7> offset; 3936 let Inst{31-30} = opc; 3937 let Inst{29-27} = 0b101; 3938 let Inst{26} = V; 3939 let Inst{25-23} = 0b011; 3940 let Inst{22} = L; 3941 let Inst{21-15} = offset; 3942 let Inst{14-10} = Rt2; 3943 let Inst{9-5} = Rn; 3944 let Inst{4-0} = Rt; 3945 3946 let DecoderMethod = "DecodePairLdStInstruction"; 3947} 3948 3949let hasSideEffects = 0 in { 3950let mayStore = 0, mayLoad = 1 in 3951class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 3952 Operand indextype, string asm> 3953 : BaseLoadStorePairPreIdx<opc, V, 1, 3954 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3955 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3956 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3957 3958let mayStore = 1, mayLoad = 0 in 3959class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 3960 Operand indextype, string asm> 3961 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 3962 (ins regtype:$Rt, regtype:$Rt2, 3963 GPR64sp:$Rn, indextype:$offset), 3964 asm>, 3965 Sched<[WriteAdr, WriteSTP]>; 3966} // hasSideEffects = 0 3967 3968// (post-indexed) 3969 3970class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3971 string asm> 3972 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 3973 bits<5> Rt; 3974 bits<5> Rt2; 3975 bits<5> Rn; 3976 bits<7> offset; 3977 let Inst{31-30} = opc; 3978 let Inst{29-27} = 0b101; 3979 let Inst{26} = V; 3980 let Inst{25-23} = 0b001; 3981 let Inst{22} = L; 3982 let Inst{21-15} = offset; 3983 let Inst{14-10} = Rt2; 3984 let Inst{9-5} = Rn; 3985 let Inst{4-0} = Rt; 3986 3987 let DecoderMethod = "DecodePairLdStInstruction"; 3988} 3989 3990let hasSideEffects = 0 in { 3991let mayStore = 0, mayLoad = 1 in 3992class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 3993 Operand idxtype, string asm> 3994 : BaseLoadStorePairPostIdx<opc, V, 1, 3995 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3996 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 3997 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3998 3999let mayStore = 1, mayLoad = 0 in 4000class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4001 Operand idxtype, string asm> 4002 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4003 (ins regtype:$Rt, regtype:$Rt2, 4004 GPR64sp:$Rn, idxtype:$offset), 4005 asm>, 4006 Sched<[WriteAdr, WriteSTP]>; 4007} // hasSideEffects = 0 4008 4009// (no-allocate) 4010 4011class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4012 string asm> 4013 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4014 bits<5> Rt; 4015 bits<5> Rt2; 4016 bits<5> Rn; 4017 bits<7> offset; 4018 let Inst{31-30} = opc; 4019 let Inst{29-27} = 0b101; 4020 let Inst{26} = V; 4021 let Inst{25-23} = 0b000; 4022 let Inst{22} = L; 4023 let Inst{21-15} = offset; 4024 let Inst{14-10} = Rt2; 4025 let Inst{9-5} = Rn; 4026 let Inst{4-0} = Rt; 4027 4028 let DecoderMethod = "DecodePairLdStInstruction"; 4029} 4030 4031multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4032 Operand indextype, string asm> { 4033 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4034 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4035 (outs regtype:$Rt, regtype:$Rt2), 4036 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4037 Sched<[WriteLD, WriteLDHi]>; 4038 4039 4040 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4041 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4042 GPR64sp:$Rn, 0)>; 4043} 4044 4045multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4046 Operand indextype, string asm> { 4047 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4048 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4049 (ins regtype:$Rt, regtype:$Rt2, 4050 GPR64sp:$Rn, indextype:$offset), 4051 asm>, 4052 Sched<[WriteSTP]>; 4053 4054 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4055 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4056 GPR64sp:$Rn, 0)>; 4057} 4058 4059//--- 4060// Load/store exclusive 4061//--- 4062 4063// True exclusive operations write to and/or read from the system's exclusive 4064// monitors, which as far as a compiler is concerned can be modelled as a 4065// random shared memory address. Hence LoadExclusive mayStore. 4066// 4067// Since these instructions have the undefined register bits set to 1 in 4068// their canonical form, we need a post encoder method to set those bits 4069// to 1 when encoding these instructions. We do this using the 4070// fixLoadStoreExclusive function. This function has template parameters: 4071// 4072// fixLoadStoreExclusive<int hasRs, int hasRt2> 4073// 4074// hasRs indicates that the instruction uses the Rs field, so we won't set 4075// it to 1 (and the same for Rt2). We don't need template parameters for 4076// the other register fields since Rt and Rn are always used. 4077// 4078let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4079class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4080 dag oops, dag iops, string asm, string operands> 4081 : I<oops, iops, asm, operands, "", []> { 4082 let Inst{31-30} = sz; 4083 let Inst{29-24} = 0b001000; 4084 let Inst{23} = o2; 4085 let Inst{22} = L; 4086 let Inst{21} = o1; 4087 let Inst{15} = o0; 4088 4089 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4090} 4091 4092// Neither Rs nor Rt2 operands. 4093class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4094 dag oops, dag iops, string asm, string operands> 4095 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4096 bits<5> Rt; 4097 bits<5> Rn; 4098 let Inst{20-16} = 0b11111; 4099 let Unpredictable{20-16} = 0b11111; 4100 let Inst{14-10} = 0b11111; 4101 let Unpredictable{14-10} = 0b11111; 4102 let Inst{9-5} = Rn; 4103 let Inst{4-0} = Rt; 4104 4105 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4106} 4107 4108// Simple load acquires don't set the exclusive monitor 4109let mayLoad = 1, mayStore = 0 in 4110class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4111 RegisterClass regtype, string asm> 4112 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4113 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4114 Sched<[WriteLD]>; 4115 4116class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4117 RegisterClass regtype, string asm> 4118 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4119 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4120 Sched<[WriteLD]>; 4121 4122class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4123 RegisterClass regtype, string asm> 4124 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4125 (outs regtype:$Rt, regtype:$Rt2), 4126 (ins GPR64sp0:$Rn), asm, 4127 "\t$Rt, $Rt2, [$Rn]">, 4128 Sched<[WriteLD, WriteLDHi]> { 4129 bits<5> Rt; 4130 bits<5> Rt2; 4131 bits<5> Rn; 4132 let Inst{14-10} = Rt2; 4133 let Inst{9-5} = Rn; 4134 let Inst{4-0} = Rt; 4135 4136 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4137} 4138 4139// Simple store release operations do not check the exclusive monitor. 4140let mayLoad = 0, mayStore = 1 in 4141class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4142 RegisterClass regtype, string asm> 4143 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4144 (ins regtype:$Rt, GPR64sp0:$Rn), 4145 asm, "\t$Rt, [$Rn]">, 4146 Sched<[WriteST]>; 4147 4148let mayLoad = 1, mayStore = 1 in 4149class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4150 RegisterClass regtype, string asm> 4151 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4152 (ins regtype:$Rt, GPR64sp0:$Rn), 4153 asm, "\t$Ws, $Rt, [$Rn]">, 4154 Sched<[WriteSTX]> { 4155 bits<5> Ws; 4156 bits<5> Rt; 4157 bits<5> Rn; 4158 let Inst{20-16} = Ws; 4159 let Inst{9-5} = Rn; 4160 let Inst{4-0} = Rt; 4161 4162 let Constraints = "@earlyclobber $Ws"; 4163 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4164} 4165 4166class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4167 RegisterClass regtype, string asm> 4168 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4169 (outs GPR32:$Ws), 4170 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4171 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4172 Sched<[WriteSTX]> { 4173 bits<5> Ws; 4174 bits<5> Rt; 4175 bits<5> Rt2; 4176 bits<5> Rn; 4177 let Inst{20-16} = Ws; 4178 let Inst{14-10} = Rt2; 4179 let Inst{9-5} = Rn; 4180 let Inst{4-0} = Rt; 4181 4182 let Constraints = "@earlyclobber $Ws"; 4183} 4184 4185// Armv8.5-A Memory Tagging Extension 4186class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4187 string asm_opnds, string cstr, dag oops, dag iops> 4188 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4189 Sched<[]> { 4190 bits<5> Rn; 4191 4192 let Inst{31-24} = 0b11011001; 4193 let Inst{23-22} = opc1; 4194 let Inst{21} = 1; 4195 // Inst{20-12} defined by subclass 4196 let Inst{11-10} = opc2; 4197 let Inst{9-5} = Rn; 4198 // Inst{4-0} defined by subclass 4199} 4200 4201class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4202 dag oops, dag iops> 4203 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4204 "", oops, iops> { 4205 bits<5> Rt; 4206 4207 let Inst{20-12} = 0b000000000; 4208 let Inst{4-0} = Rt; 4209 4210 let mayLoad = Load; 4211} 4212 4213class MemTagLoad<string asm_insn, string asm_opnds> 4214 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4215 (outs GPR64:$wback), 4216 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4217 bits<5> Rt; 4218 bits<9> offset; 4219 4220 let Inst{20-12} = offset; 4221 let Inst{4-0} = Rt; 4222 4223 let mayLoad = 1; 4224} 4225 4226class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4227 string asm_opnds, string cstr, dag oops, dag iops> 4228 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4229 bits<5> Rt; 4230 bits<9> offset; 4231 4232 let Inst{20-12} = offset; 4233 let Inst{4-0} = Rt; 4234 4235 let mayStore = 1; 4236} 4237 4238multiclass MemTagStore<bits<2> opc1, string insn> { 4239 def Offset : 4240 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4241 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4242 def PreIndex : 4243 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4244 "$Rn = $wback", 4245 (outs GPR64sp:$wback), 4246 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4247 def PostIndex : 4248 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4249 "$Rn = $wback", 4250 (outs GPR64sp:$wback), 4251 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4252 4253 def : InstAlias<insn # "\t$Rt, [$Rn]", 4254 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4255} 4256 4257//--- 4258// Exception generation 4259//--- 4260 4261let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4262class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4263 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>, 4264 Sched<[WriteSys]> { 4265 bits<16> imm; 4266 let Inst{31-24} = 0b11010100; 4267 let Inst{23-21} = op1; 4268 let Inst{20-5} = imm; 4269 let Inst{4-2} = 0b000; 4270 let Inst{1-0} = ll; 4271} 4272 4273//--- 4274// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4275//-- 4276let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4277class UDFType<bits<16> opc, string asm> 4278 : I<(outs), (ins uimm16:$imm), 4279 asm, "\t$imm", "", []>, 4280 Sched<[]> { 4281 bits<16> imm; 4282 let Inst{31-16} = opc; 4283 let Inst{15-0} = imm; 4284} 4285} 4286let Predicates = [HasFPARMv8] in { 4287 4288//--- 4289// Floating point to integer conversion 4290//--- 4291 4292class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4293 RegisterClass srcType, RegisterClass dstType, 4294 string asm, list<dag> pattern> 4295 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4296 asm, "\t$Rd, $Rn", "", pattern>, 4297 Sched<[WriteFCvt]> { 4298 bits<5> Rd; 4299 bits<5> Rn; 4300 let Inst{30-29} = 0b00; 4301 let Inst{28-24} = 0b11110; 4302 let Inst{23-22} = type; 4303 let Inst{21} = 1; 4304 let Inst{20-19} = rmode; 4305 let Inst{18-16} = opcode; 4306 let Inst{15-10} = 0; 4307 let Inst{9-5} = Rn; 4308 let Inst{4-0} = Rd; 4309} 4310 4311let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4312class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4313 RegisterClass srcType, RegisterClass dstType, 4314 Operand immType, string asm, list<dag> pattern> 4315 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4316 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4317 Sched<[WriteFCvt]> { 4318 bits<5> Rd; 4319 bits<5> Rn; 4320 bits<6> scale; 4321 let Inst{30-29} = 0b00; 4322 let Inst{28-24} = 0b11110; 4323 let Inst{23-22} = type; 4324 let Inst{21} = 0; 4325 let Inst{20-19} = rmode; 4326 let Inst{18-16} = opcode; 4327 let Inst{15-10} = scale; 4328 let Inst{9-5} = Rn; 4329 let Inst{4-0} = Rd; 4330} 4331 4332multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4333 SDPatternOperator OpN> { 4334 // Unscaled half-precision to 32-bit 4335 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4336 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> { 4337 let Inst{31} = 0; // 32-bit GPR flag 4338 let Predicates = [HasFullFP16]; 4339 } 4340 4341 // Unscaled half-precision to 64-bit 4342 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4343 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> { 4344 let Inst{31} = 1; // 64-bit GPR flag 4345 let Predicates = [HasFullFP16]; 4346 } 4347 4348 // Unscaled single-precision to 32-bit 4349 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4350 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4351 let Inst{31} = 0; // 32-bit GPR flag 4352 } 4353 4354 // Unscaled single-precision to 64-bit 4355 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4356 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4357 let Inst{31} = 1; // 64-bit GPR flag 4358 } 4359 4360 // Unscaled double-precision to 32-bit 4361 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4362 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4363 let Inst{31} = 0; // 32-bit GPR flag 4364 } 4365 4366 // Unscaled double-precision to 64-bit 4367 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4368 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4369 let Inst{31} = 1; // 64-bit GPR flag 4370 } 4371} 4372 4373multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4374 SDPatternOperator OpN> { 4375 // Scaled half-precision to 32-bit 4376 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4377 fixedpoint_f16_i32, asm, 4378 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn, 4379 fixedpoint_f16_i32:$scale)))]> { 4380 let Inst{31} = 0; // 32-bit GPR flag 4381 let scale{5} = 1; 4382 let Predicates = [HasFullFP16]; 4383 } 4384 4385 // Scaled half-precision to 64-bit 4386 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4387 fixedpoint_f16_i64, asm, 4388 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn, 4389 fixedpoint_f16_i64:$scale)))]> { 4390 let Inst{31} = 1; // 64-bit GPR flag 4391 let Predicates = [HasFullFP16]; 4392 } 4393 4394 // Scaled single-precision to 32-bit 4395 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4396 fixedpoint_f32_i32, asm, 4397 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4398 fixedpoint_f32_i32:$scale)))]> { 4399 let Inst{31} = 0; // 32-bit GPR flag 4400 let scale{5} = 1; 4401 } 4402 4403 // Scaled single-precision to 64-bit 4404 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4405 fixedpoint_f32_i64, asm, 4406 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4407 fixedpoint_f32_i64:$scale)))]> { 4408 let Inst{31} = 1; // 64-bit GPR flag 4409 } 4410 4411 // Scaled double-precision to 32-bit 4412 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4413 fixedpoint_f64_i32, asm, 4414 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4415 fixedpoint_f64_i32:$scale)))]> { 4416 let Inst{31} = 0; // 32-bit GPR flag 4417 let scale{5} = 1; 4418 } 4419 4420 // Scaled double-precision to 64-bit 4421 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4422 fixedpoint_f64_i64, asm, 4423 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4424 fixedpoint_f64_i64:$scale)))]> { 4425 let Inst{31} = 1; // 64-bit GPR flag 4426 } 4427} 4428 4429//--- 4430// Integer to floating point conversion 4431//--- 4432 4433let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4434class BaseIntegerToFP<bit isUnsigned, 4435 RegisterClass srcType, RegisterClass dstType, 4436 Operand immType, string asm, list<dag> pattern> 4437 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4438 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4439 Sched<[WriteFCvt]> { 4440 bits<5> Rd; 4441 bits<5> Rn; 4442 bits<6> scale; 4443 let Inst{30-24} = 0b0011110; 4444 let Inst{21-17} = 0b00001; 4445 let Inst{16} = isUnsigned; 4446 let Inst{15-10} = scale; 4447 let Inst{9-5} = Rn; 4448 let Inst{4-0} = Rd; 4449} 4450 4451class BaseIntegerToFPUnscaled<bit isUnsigned, 4452 RegisterClass srcType, RegisterClass dstType, 4453 ValueType dvt, string asm, SDNode node> 4454 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4455 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4456 Sched<[WriteFCvt]> { 4457 bits<5> Rd; 4458 bits<5> Rn; 4459 bits<6> scale; 4460 let Inst{30-24} = 0b0011110; 4461 let Inst{21-17} = 0b10001; 4462 let Inst{16} = isUnsigned; 4463 let Inst{15-10} = 0b000000; 4464 let Inst{9-5} = Rn; 4465 let Inst{4-0} = Rd; 4466} 4467 4468multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 4469 // Unscaled 4470 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4471 let Inst{31} = 0; // 32-bit GPR flag 4472 let Inst{23-22} = 0b11; // 16-bit FPR flag 4473 let Predicates = [HasFullFP16]; 4474 } 4475 4476 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4477 let Inst{31} = 0; // 32-bit GPR flag 4478 let Inst{23-22} = 0b00; // 32-bit FPR flag 4479 } 4480 4481 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4482 let Inst{31} = 0; // 32-bit GPR flag 4483 let Inst{23-22} = 0b01; // 64-bit FPR flag 4484 } 4485 4486 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4487 let Inst{31} = 1; // 64-bit GPR flag 4488 let Inst{23-22} = 0b11; // 16-bit FPR flag 4489 let Predicates = [HasFullFP16]; 4490 } 4491 4492 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4493 let Inst{31} = 1; // 64-bit GPR flag 4494 let Inst{23-22} = 0b00; // 32-bit FPR flag 4495 } 4496 4497 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4498 let Inst{31} = 1; // 64-bit GPR flag 4499 let Inst{23-22} = 0b01; // 64-bit FPR flag 4500 } 4501 4502 // Scaled 4503 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4504 [(set FPR16:$Rd, 4505 (fdiv (node GPR32:$Rn), 4506 fixedpoint_f16_i32:$scale))]> { 4507 let Inst{31} = 0; // 32-bit GPR flag 4508 let Inst{23-22} = 0b11; // 16-bit FPR flag 4509 let scale{5} = 1; 4510 let Predicates = [HasFullFP16]; 4511 } 4512 4513 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4514 [(set FPR32:$Rd, 4515 (fdiv (node GPR32:$Rn), 4516 fixedpoint_f32_i32:$scale))]> { 4517 let Inst{31} = 0; // 32-bit GPR flag 4518 let Inst{23-22} = 0b00; // 32-bit FPR flag 4519 let scale{5} = 1; 4520 } 4521 4522 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4523 [(set FPR64:$Rd, 4524 (fdiv (node GPR32:$Rn), 4525 fixedpoint_f64_i32:$scale))]> { 4526 let Inst{31} = 0; // 32-bit GPR flag 4527 let Inst{23-22} = 0b01; // 64-bit FPR flag 4528 let scale{5} = 1; 4529 } 4530 4531 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4532 [(set FPR16:$Rd, 4533 (fdiv (node GPR64:$Rn), 4534 fixedpoint_f16_i64:$scale))]> { 4535 let Inst{31} = 1; // 64-bit GPR flag 4536 let Inst{23-22} = 0b11; // 16-bit FPR flag 4537 let Predicates = [HasFullFP16]; 4538 } 4539 4540 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4541 [(set FPR32:$Rd, 4542 (fdiv (node GPR64:$Rn), 4543 fixedpoint_f32_i64:$scale))]> { 4544 let Inst{31} = 1; // 64-bit GPR flag 4545 let Inst{23-22} = 0b00; // 32-bit FPR flag 4546 } 4547 4548 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4549 [(set FPR64:$Rd, 4550 (fdiv (node GPR64:$Rn), 4551 fixedpoint_f64_i64:$scale))]> { 4552 let Inst{31} = 1; // 64-bit GPR flag 4553 let Inst{23-22} = 0b01; // 64-bit FPR flag 4554 } 4555} 4556 4557//--- 4558// Unscaled integer <-> floating point conversion (i.e. FMOV) 4559//--- 4560 4561let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4562class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4563 RegisterClass srcType, RegisterClass dstType, 4564 string asm> 4565 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4566 // We use COPY_TO_REGCLASS for these bitconvert operations. 4567 // copyPhysReg() expands the resultant COPY instructions after 4568 // regalloc is done. This gives greater freedom for the allocator 4569 // and related passes (coalescing, copy propagation, et. al.) to 4570 // be more effective. 4571 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4572 Sched<[WriteFCopy]> { 4573 bits<5> Rd; 4574 bits<5> Rn; 4575 let Inst{30-24} = 0b0011110; 4576 let Inst{21} = 1; 4577 let Inst{20-19} = rmode; 4578 let Inst{18-16} = opcode; 4579 let Inst{15-10} = 0b000000; 4580 let Inst{9-5} = Rn; 4581 let Inst{4-0} = Rd; 4582} 4583 4584let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4585class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4586 RegisterClass srcType, RegisterOperand dstType, string asm, 4587 string kind> 4588 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4589 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4590 Sched<[WriteFCopy]> { 4591 bits<5> Rd; 4592 bits<5> Rn; 4593 let Inst{30-23} = 0b00111101; 4594 let Inst{21} = 1; 4595 let Inst{20-19} = rmode; 4596 let Inst{18-16} = opcode; 4597 let Inst{15-10} = 0b000000; 4598 let Inst{9-5} = Rn; 4599 let Inst{4-0} = Rd; 4600 4601 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4602} 4603 4604let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4605class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4606 RegisterOperand srcType, RegisterClass dstType, string asm, 4607 string kind> 4608 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4609 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4610 Sched<[WriteFCopy]> { 4611 bits<5> Rd; 4612 bits<5> Rn; 4613 let Inst{30-23} = 0b00111101; 4614 let Inst{21} = 1; 4615 let Inst{20-19} = rmode; 4616 let Inst{18-16} = opcode; 4617 let Inst{15-10} = 0b000000; 4618 let Inst{9-5} = Rn; 4619 let Inst{4-0} = Rd; 4620 4621 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4622} 4623 4624 4625multiclass UnscaledConversion<string asm> { 4626 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4627 let Inst{31} = 0; // 32-bit GPR flag 4628 let Inst{23-22} = 0b11; // 16-bit FPR flag 4629 let Predicates = [HasFullFP16]; 4630 } 4631 4632 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4633 let Inst{31} = 1; // 64-bit GPR flag 4634 let Inst{23-22} = 0b11; // 16-bit FPR flag 4635 let Predicates = [HasFullFP16]; 4636 } 4637 4638 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4639 let Inst{31} = 0; // 32-bit GPR flag 4640 let Inst{23-22} = 0b00; // 32-bit FPR flag 4641 } 4642 4643 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4644 let Inst{31} = 1; // 64-bit GPR flag 4645 let Inst{23-22} = 0b01; // 64-bit FPR flag 4646 } 4647 4648 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4649 let Inst{31} = 0; // 32-bit GPR flag 4650 let Inst{23-22} = 0b11; // 16-bit FPR flag 4651 let Predicates = [HasFullFP16]; 4652 } 4653 4654 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4655 let Inst{31} = 1; // 64-bit GPR flag 4656 let Inst{23-22} = 0b11; // 16-bit FPR flag 4657 let Predicates = [HasFullFP16]; 4658 } 4659 4660 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4661 let Inst{31} = 0; // 32-bit GPR flag 4662 let Inst{23-22} = 0b00; // 32-bit FPR flag 4663 } 4664 4665 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4666 let Inst{31} = 1; // 64-bit GPR flag 4667 let Inst{23-22} = 0b01; // 64-bit FPR flag 4668 } 4669 4670 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4671 asm, ".d"> { 4672 let Inst{31} = 1; 4673 let Inst{22} = 0; 4674 } 4675 4676 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4677 asm, ".d"> { 4678 let Inst{31} = 1; 4679 let Inst{22} = 0; 4680 } 4681} 4682 4683//--- 4684// Floating point conversion 4685//--- 4686 4687class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4688 RegisterClass srcType, string asm, list<dag> pattern> 4689 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4690 Sched<[WriteFCvt]> { 4691 bits<5> Rd; 4692 bits<5> Rn; 4693 let Inst{31-24} = 0b00011110; 4694 let Inst{23-22} = type; 4695 let Inst{21-17} = 0b10001; 4696 let Inst{16-15} = opcode; 4697 let Inst{14-10} = 0b10000; 4698 let Inst{9-5} = Rn; 4699 let Inst{4-0} = Rd; 4700} 4701 4702multiclass FPConversion<string asm> { 4703 // Double-precision to Half-precision 4704 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4705 [(set FPR16:$Rd, (any_fpround FPR64:$Rn))]>; 4706 4707 // Double-precision to Single-precision 4708 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4709 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4710 4711 // Half-precision to Double-precision 4712 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4713 [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>; 4714 4715 // Half-precision to Single-precision 4716 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4717 [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>; 4718 4719 // Single-precision to Double-precision 4720 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4721 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4722 4723 // Single-precision to Half-precision 4724 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4725 [(set FPR16:$Rd, (any_fpround FPR32:$Rn))]>; 4726} 4727 4728//--- 4729// Single operand floating point data processing 4730//--- 4731 4732let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4733class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4734 ValueType vt, string asm, SDPatternOperator node> 4735 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4736 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4737 Sched<[WriteF]> { 4738 bits<5> Rd; 4739 bits<5> Rn; 4740 let Inst{31-24} = 0b00011110; 4741 let Inst{21} = 0b1; 4742 let Inst{20-15} = opcode; 4743 let Inst{14-10} = 0b10000; 4744 let Inst{9-5} = Rn; 4745 let Inst{4-0} = Rd; 4746} 4747 4748multiclass SingleOperandFPData<bits<4> opcode, string asm, 4749 SDPatternOperator node = null_frag> { 4750 4751 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 4752 let Inst{23-22} = 0b11; // 16-bit size flag 4753 let Predicates = [HasFullFP16]; 4754 } 4755 4756 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 4757 let Inst{23-22} = 0b00; // 32-bit size flag 4758 } 4759 4760 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 4761 let Inst{23-22} = 0b01; // 64-bit size flag 4762 } 4763} 4764 4765multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 4766 SDPatternOperator node = null_frag>{ 4767 4768 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 4769 let Inst{23-22} = 0b00; // 32-bit registers 4770 } 4771 4772 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 4773 let Inst{23-22} = 0b01; // 64-bit registers 4774 } 4775} 4776 4777// FRInt[32|64][Z|N] instructions 4778multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 4779 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 4780 4781//--- 4782// Two operand floating point data processing 4783//--- 4784 4785let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4786class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4787 string asm, list<dag> pat> 4788 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4789 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4790 Sched<[WriteF]> { 4791 bits<5> Rd; 4792 bits<5> Rn; 4793 bits<5> Rm; 4794 let Inst{31-24} = 0b00011110; 4795 let Inst{21} = 1; 4796 let Inst{20-16} = Rm; 4797 let Inst{15-12} = opcode; 4798 let Inst{11-10} = 0b10; 4799 let Inst{9-5} = Rn; 4800 let Inst{4-0} = Rd; 4801} 4802 4803multiclass TwoOperandFPData<bits<4> opcode, string asm, 4804 SDPatternOperator node = null_frag> { 4805 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4806 [(set (f16 FPR16:$Rd), 4807 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4808 let Inst{23-22} = 0b11; // 16-bit size flag 4809 let Predicates = [HasFullFP16]; 4810 } 4811 4812 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4813 [(set (f32 FPR32:$Rd), 4814 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 4815 let Inst{23-22} = 0b00; // 32-bit size flag 4816 } 4817 4818 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4819 [(set (f64 FPR64:$Rd), 4820 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 4821 let Inst{23-22} = 0b01; // 64-bit size flag 4822 } 4823} 4824 4825multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 4826 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4827 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> { 4828 let Inst{23-22} = 0b11; // 16-bit size flag 4829 let Predicates = [HasFullFP16]; 4830 } 4831 4832 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4833 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 4834 let Inst{23-22} = 0b00; // 32-bit size flag 4835 } 4836 4837 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4838 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 4839 let Inst{23-22} = 0b01; // 64-bit size flag 4840 } 4841} 4842 4843 4844//--- 4845// Three operand floating point data processing 4846//--- 4847 4848class BaseThreeOperandFPData<bit isNegated, bit isSub, 4849 RegisterClass regtype, string asm, list<dag> pat> 4850 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 4851 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 4852 Sched<[WriteFMul]> { 4853 bits<5> Rd; 4854 bits<5> Rn; 4855 bits<5> Rm; 4856 bits<5> Ra; 4857 let Inst{31-24} = 0b00011111; 4858 let Inst{21} = isNegated; 4859 let Inst{20-16} = Rm; 4860 let Inst{15} = isSub; 4861 let Inst{14-10} = Ra; 4862 let Inst{9-5} = Rn; 4863 let Inst{4-0} = Rd; 4864} 4865 4866multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 4867 SDPatternOperator node> { 4868 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 4869 [(set FPR16:$Rd, 4870 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 4871 let Inst{23-22} = 0b11; // 16-bit size flag 4872 let Predicates = [HasFullFP16]; 4873 } 4874 4875 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 4876 [(set FPR32:$Rd, 4877 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 4878 let Inst{23-22} = 0b00; // 32-bit size flag 4879 } 4880 4881 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 4882 [(set FPR64:$Rd, 4883 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 4884 let Inst{23-22} = 0b01; // 64-bit size flag 4885 } 4886} 4887 4888//--- 4889// Floating point data comparisons 4890//--- 4891 4892let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4893class BaseOneOperandFPComparison<bit signalAllNans, 4894 RegisterClass regtype, string asm, 4895 list<dag> pat> 4896 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 4897 Sched<[WriteFCmp]> { 4898 bits<5> Rn; 4899 let Inst{31-24} = 0b00011110; 4900 let Inst{21} = 1; 4901 4902 let Inst{15-10} = 0b001000; 4903 let Inst{9-5} = Rn; 4904 let Inst{4} = signalAllNans; 4905 let Inst{3-0} = 0b1000; 4906 4907 // Rm should be 0b00000 canonically, but we need to accept any value. 4908 let PostEncoderMethod = "fixOneOperandFPComparison"; 4909} 4910 4911let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4912class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 4913 string asm, list<dag> pat> 4914 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 4915 Sched<[WriteFCmp]> { 4916 bits<5> Rm; 4917 bits<5> Rn; 4918 let Inst{31-24} = 0b00011110; 4919 let Inst{21} = 1; 4920 let Inst{20-16} = Rm; 4921 let Inst{15-10} = 0b001000; 4922 let Inst{9-5} = Rn; 4923 let Inst{4} = signalAllNans; 4924 let Inst{3-0} = 0b0000; 4925} 4926 4927multiclass FPComparison<bit signalAllNans, string asm, 4928 SDPatternOperator OpNode = null_frag> { 4929 let Defs = [NZCV] in { 4930 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 4931 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> { 4932 let Inst{23-22} = 0b11; 4933 let Predicates = [HasFullFP16]; 4934 } 4935 4936 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 4937 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 4938 let Inst{23-22} = 0b11; 4939 let Predicates = [HasFullFP16]; 4940 } 4941 4942 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 4943 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 4944 let Inst{23-22} = 0b00; 4945 } 4946 4947 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 4948 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 4949 let Inst{23-22} = 0b00; 4950 } 4951 4952 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 4953 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 4954 let Inst{23-22} = 0b01; 4955 } 4956 4957 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 4958 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 4959 let Inst{23-22} = 0b01; 4960 } 4961 } // Defs = [NZCV] 4962} 4963 4964//--- 4965// Floating point conditional comparisons 4966//--- 4967 4968let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4969class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 4970 string mnemonic, list<dag> pat> 4971 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 4972 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 4973 Sched<[WriteFCmp]> { 4974 let Uses = [NZCV]; 4975 let Defs = [NZCV]; 4976 4977 bits<5> Rn; 4978 bits<5> Rm; 4979 bits<4> nzcv; 4980 bits<4> cond; 4981 4982 let Inst{31-24} = 0b00011110; 4983 let Inst{21} = 1; 4984 let Inst{20-16} = Rm; 4985 let Inst{15-12} = cond; 4986 let Inst{11-10} = 0b01; 4987 let Inst{9-5} = Rn; 4988 let Inst{4} = signalAllNans; 4989 let Inst{3-0} = nzcv; 4990} 4991 4992multiclass FPCondComparison<bit signalAllNans, string mnemonic, 4993 SDPatternOperator OpNode = null_frag> { 4994 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 4995 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 4996 (i32 imm:$cond), NZCV))]> { 4997 let Inst{23-22} = 0b11; 4998 let Predicates = [HasFullFP16]; 4999 } 5000 5001 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5002 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5003 (i32 imm:$cond), NZCV))]> { 5004 let Inst{23-22} = 0b00; 5005 } 5006 5007 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5008 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5009 (i32 imm:$cond), NZCV))]> { 5010 let Inst{23-22} = 0b01; 5011 } 5012} 5013 5014//--- 5015// Floating point conditional select 5016//--- 5017 5018class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5019 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5020 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5021 [(set regtype:$Rd, 5022 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5023 (i32 imm:$cond), NZCV))]>, 5024 Sched<[WriteF]> { 5025 bits<5> Rd; 5026 bits<5> Rn; 5027 bits<5> Rm; 5028 bits<4> cond; 5029 5030 let Inst{31-24} = 0b00011110; 5031 let Inst{21} = 1; 5032 let Inst{20-16} = Rm; 5033 let Inst{15-12} = cond; 5034 let Inst{11-10} = 0b11; 5035 let Inst{9-5} = Rn; 5036 let Inst{4-0} = Rd; 5037} 5038 5039multiclass FPCondSelect<string asm> { 5040 let Uses = [NZCV] in { 5041 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5042 let Inst{23-22} = 0b11; 5043 let Predicates = [HasFullFP16]; 5044 } 5045 5046 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5047 let Inst{23-22} = 0b00; 5048 } 5049 5050 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5051 let Inst{23-22} = 0b01; 5052 } 5053 } // Uses = [NZCV] 5054} 5055 5056//--- 5057// Floating move immediate 5058//--- 5059 5060class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5061 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5062 [(set regtype:$Rd, fpimmtype:$imm)]>, 5063 Sched<[WriteFImm]> { 5064 bits<5> Rd; 5065 bits<8> imm; 5066 let Inst{31-24} = 0b00011110; 5067 let Inst{21} = 1; 5068 let Inst{20-13} = imm; 5069 let Inst{12-5} = 0b10000000; 5070 let Inst{4-0} = Rd; 5071} 5072 5073multiclass FPMoveImmediate<string asm> { 5074 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5075 let Inst{23-22} = 0b11; 5076 let Predicates = [HasFullFP16]; 5077 } 5078 5079 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5080 let Inst{23-22} = 0b00; 5081 } 5082 5083 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5084 let Inst{23-22} = 0b01; 5085 } 5086} 5087} // end of 'let Predicates = [HasFPARMv8]' 5088 5089//---------------------------------------------------------------------------- 5090// AdvSIMD 5091//---------------------------------------------------------------------------- 5092 5093let Predicates = [HasNEON] in { 5094 5095//---------------------------------------------------------------------------- 5096// AdvSIMD three register vector instructions 5097//---------------------------------------------------------------------------- 5098 5099let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5100class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5101 RegisterOperand regtype, string asm, string kind, 5102 list<dag> pattern> 5103 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5104 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5105 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5106 Sched<[WriteV]> { 5107 bits<5> Rd; 5108 bits<5> Rn; 5109 bits<5> Rm; 5110 let Inst{31} = 0; 5111 let Inst{30} = Q; 5112 let Inst{29} = U; 5113 let Inst{28-24} = 0b01110; 5114 let Inst{23-21} = size; 5115 let Inst{20-16} = Rm; 5116 let Inst{15-11} = opcode; 5117 let Inst{10} = 1; 5118 let Inst{9-5} = Rn; 5119 let Inst{4-0} = Rd; 5120} 5121 5122let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5123class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5124 RegisterOperand regtype, string asm, string kind, 5125 list<dag> pattern> 5126 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5127 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5128 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5129 Sched<[WriteV]> { 5130 bits<5> Rd; 5131 bits<5> Rn; 5132 bits<5> Rm; 5133 let Inst{31} = 0; 5134 let Inst{30} = Q; 5135 let Inst{29} = U; 5136 let Inst{28-24} = 0b01110; 5137 let Inst{23-21} = size; 5138 let Inst{20-16} = Rm; 5139 let Inst{15-11} = opcode; 5140 let Inst{10} = 1; 5141 let Inst{9-5} = Rn; 5142 let Inst{4-0} = Rd; 5143} 5144 5145// All operand sizes distinguished in the encoding. 5146multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5147 SDPatternOperator OpNode> { 5148 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5149 asm, ".8b", 5150 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5151 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5152 asm, ".16b", 5153 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5154 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5155 asm, ".4h", 5156 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5157 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5158 asm, ".8h", 5159 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5160 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5161 asm, ".2s", 5162 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5163 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5164 asm, ".4s", 5165 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5166 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5167 asm, ".2d", 5168 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5169} 5170 5171multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5172 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5173 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5174 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5175 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5176 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5177 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5178 5179 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5180 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5181 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5182 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5183 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5184 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5185 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5186 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5187} 5188 5189// As above, but D sized elements unsupported. 5190multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5191 SDPatternOperator OpNode> { 5192 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5193 asm, ".8b", 5194 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5195 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5196 asm, ".16b", 5197 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5198 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5199 asm, ".4h", 5200 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5201 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5202 asm, ".8h", 5203 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5204 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5205 asm, ".2s", 5206 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5207 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5208 asm, ".4s", 5209 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5210} 5211 5212multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5213 SDPatternOperator OpNode> { 5214 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5215 asm, ".8b", 5216 [(set (v8i8 V64:$dst), 5217 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5218 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5219 asm, ".16b", 5220 [(set (v16i8 V128:$dst), 5221 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5222 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5223 asm, ".4h", 5224 [(set (v4i16 V64:$dst), 5225 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5226 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5227 asm, ".8h", 5228 [(set (v8i16 V128:$dst), 5229 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5230 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5231 asm, ".2s", 5232 [(set (v2i32 V64:$dst), 5233 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5234 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5235 asm, ".4s", 5236 [(set (v4i32 V128:$dst), 5237 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5238} 5239 5240// As above, but only B sized elements supported. 5241multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5242 SDPatternOperator OpNode> { 5243 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5244 asm, ".8b", 5245 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5246 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5247 asm, ".16b", 5248 [(set (v16i8 V128:$Rd), 5249 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5250} 5251 5252// As above, but only floating point elements supported. 5253multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5254 string asm, SDPatternOperator OpNode> { 5255 let Predicates = [HasNEON, HasFullFP16] in { 5256 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5257 asm, ".4h", 5258 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5259 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5260 asm, ".8h", 5261 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5262 } // Predicates = [HasNEON, HasFullFP16] 5263 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5264 asm, ".2s", 5265 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5266 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5267 asm, ".4s", 5268 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5269 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5270 asm, ".2d", 5271 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5272} 5273 5274multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5275 string asm, 5276 SDPatternOperator OpNode> { 5277 let Predicates = [HasNEON, HasFullFP16] in { 5278 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5279 asm, ".4h", 5280 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5281 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5282 asm, ".8h", 5283 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5284 } // Predicates = [HasNEON, HasFullFP16] 5285 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5286 asm, ".2s", 5287 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5288 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5289 asm, ".4s", 5290 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5291 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5292 asm, ".2d", 5293 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5294} 5295 5296multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5297 string asm, SDPatternOperator OpNode> { 5298 let Predicates = [HasNEON, HasFullFP16] in { 5299 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5300 asm, ".4h", 5301 [(set (v4f16 V64:$dst), 5302 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5303 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5304 asm, ".8h", 5305 [(set (v8f16 V128:$dst), 5306 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5307 } // Predicates = [HasNEON, HasFullFP16] 5308 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5309 asm, ".2s", 5310 [(set (v2f32 V64:$dst), 5311 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5312 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5313 asm, ".4s", 5314 [(set (v4f32 V128:$dst), 5315 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5316 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5317 asm, ".2d", 5318 [(set (v2f64 V128:$dst), 5319 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5320} 5321 5322// As above, but D and B sized elements unsupported. 5323multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5324 SDPatternOperator OpNode> { 5325 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5326 asm, ".4h", 5327 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5328 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5329 asm, ".8h", 5330 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5331 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5332 asm, ".2s", 5333 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5334 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5335 asm, ".4s", 5336 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5337} 5338 5339// Logical three vector ops share opcode bits, and only use B sized elements. 5340multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5341 SDPatternOperator OpNode = null_frag> { 5342 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5343 asm, ".8b", 5344 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5345 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5346 asm, ".16b", 5347 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5348 5349 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5350 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5351 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5352 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5353 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5354 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5355 5356 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5357 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5358 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5359 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5360 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5361 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5362} 5363 5364multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5365 string asm, SDPatternOperator OpNode> { 5366 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5367 asm, ".8b", 5368 [(set (v8i8 V64:$dst), 5369 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5370 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5371 asm, ".16b", 5372 [(set (v16i8 V128:$dst), 5373 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5374 (v16i8 V128:$Rm)))]>; 5375 5376 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5377 (v4i16 V64:$RHS))), 5378 (!cast<Instruction>(NAME#"v8i8") 5379 V64:$LHS, V64:$MHS, V64:$RHS)>; 5380 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5381 (v2i32 V64:$RHS))), 5382 (!cast<Instruction>(NAME#"v8i8") 5383 V64:$LHS, V64:$MHS, V64:$RHS)>; 5384 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5385 (v1i64 V64:$RHS))), 5386 (!cast<Instruction>(NAME#"v8i8") 5387 V64:$LHS, V64:$MHS, V64:$RHS)>; 5388 5389 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5390 (v8i16 V128:$RHS))), 5391 (!cast<Instruction>(NAME#"v16i8") 5392 V128:$LHS, V128:$MHS, V128:$RHS)>; 5393 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5394 (v4i32 V128:$RHS))), 5395 (!cast<Instruction>(NAME#"v16i8") 5396 V128:$LHS, V128:$MHS, V128:$RHS)>; 5397 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5398 (v2i64 V128:$RHS))), 5399 (!cast<Instruction>(NAME#"v16i8") 5400 V128:$LHS, V128:$MHS, V128:$RHS)>; 5401} 5402 5403// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5404// bytes from S-sized elements. 5405class BaseSIMDThreeSameVectorDot<bit Q, bit U, string asm, string kind1, 5406 string kind2, RegisterOperand RegType, 5407 ValueType AccumType, ValueType InputType, 5408 SDPatternOperator OpNode> : 5409 BaseSIMDThreeSameVectorTied<Q, U, 0b100, 0b10010, RegType, asm, kind1, 5410 [(set (AccumType RegType:$dst), 5411 (OpNode (AccumType RegType:$Rd), 5412 (InputType RegType:$Rn), 5413 (InputType RegType:$Rm)))]> { 5414 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5415} 5416 5417multiclass SIMDThreeSameVectorDot<bit U, string asm, SDPatternOperator OpNode> { 5418 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, asm, ".2s", ".8b", V64, 5419 v2i32, v8i8, OpNode>; 5420 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, asm, ".4s", ".16b", V128, 5421 v4i32, v16i8, OpNode>; 5422} 5423 5424// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5425// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5426// 8H to 4S, when Q=1). 5427class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5428 string kind2, RegisterOperand RegType, 5429 ValueType AccumType, ValueType InputType, 5430 SDPatternOperator OpNode> : 5431 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5432 [(set (AccumType RegType:$dst), 5433 (OpNode (AccumType RegType:$Rd), 5434 (InputType RegType:$Rn), 5435 (InputType RegType:$Rm)))]> { 5436 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5437 let Inst{13} = b13; 5438} 5439 5440multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5441 SDPatternOperator OpNode> { 5442 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5443 v2f32, v4f16, OpNode>; 5444 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5445 v4f32, v8f16, OpNode>; 5446} 5447 5448 5449//---------------------------------------------------------------------------- 5450// AdvSIMD two register vector instructions. 5451//---------------------------------------------------------------------------- 5452 5453let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5454class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5455 bits<2> size2, RegisterOperand regtype, string asm, 5456 string dstkind, string srckind, list<dag> pattern> 5457 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5458 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5459 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5460 Sched<[WriteV]> { 5461 bits<5> Rd; 5462 bits<5> Rn; 5463 let Inst{31} = 0; 5464 let Inst{30} = Q; 5465 let Inst{29} = U; 5466 let Inst{28-24} = 0b01110; 5467 let Inst{23-22} = size; 5468 let Inst{21} = 0b1; 5469 let Inst{20-19} = size2; 5470 let Inst{18-17} = 0b00; 5471 let Inst{16-12} = opcode; 5472 let Inst{11-10} = 0b10; 5473 let Inst{9-5} = Rn; 5474 let Inst{4-0} = Rd; 5475} 5476 5477let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5478class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5479 bits<2> size2, RegisterOperand regtype, 5480 string asm, string dstkind, string srckind, 5481 list<dag> pattern> 5482 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5483 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5484 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5485 Sched<[WriteV]> { 5486 bits<5> Rd; 5487 bits<5> Rn; 5488 let Inst{31} = 0; 5489 let Inst{30} = Q; 5490 let Inst{29} = U; 5491 let Inst{28-24} = 0b01110; 5492 let Inst{23-22} = size; 5493 let Inst{21} = 0b1; 5494 let Inst{20-19} = size2; 5495 let Inst{18-17} = 0b00; 5496 let Inst{16-12} = opcode; 5497 let Inst{11-10} = 0b10; 5498 let Inst{9-5} = Rn; 5499 let Inst{4-0} = Rd; 5500} 5501 5502// Supports B, H, and S element sizes. 5503multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5504 SDPatternOperator OpNode> { 5505 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5506 asm, ".8b", ".8b", 5507 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5508 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5509 asm, ".16b", ".16b", 5510 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5511 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5512 asm, ".4h", ".4h", 5513 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5514 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5515 asm, ".8h", ".8h", 5516 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5517 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5518 asm, ".2s", ".2s", 5519 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5520 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5521 asm, ".4s", ".4s", 5522 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5523} 5524 5525class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5526 RegisterOperand regtype, string asm, string dstkind, 5527 string srckind, string amount> 5528 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5529 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5530 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5531 Sched<[WriteV]> { 5532 bits<5> Rd; 5533 bits<5> Rn; 5534 let Inst{31} = 0; 5535 let Inst{30} = Q; 5536 let Inst{29-24} = 0b101110; 5537 let Inst{23-22} = size; 5538 let Inst{21-10} = 0b100001001110; 5539 let Inst{9-5} = Rn; 5540 let Inst{4-0} = Rd; 5541} 5542 5543multiclass SIMDVectorLShiftLongBySizeBHS { 5544 let hasSideEffects = 0 in { 5545 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5546 "shll", ".8h", ".8b", "8">; 5547 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5548 "shll2", ".8h", ".16b", "8">; 5549 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5550 "shll", ".4s", ".4h", "16">; 5551 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5552 "shll2", ".4s", ".8h", "16">; 5553 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5554 "shll", ".2d", ".2s", "32">; 5555 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5556 "shll2", ".2d", ".4s", "32">; 5557 } 5558} 5559 5560// Supports all element sizes. 5561multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5562 SDPatternOperator OpNode> { 5563 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5564 asm, ".4h", ".8b", 5565 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5566 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5567 asm, ".8h", ".16b", 5568 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5569 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5570 asm, ".2s", ".4h", 5571 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5572 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5573 asm, ".4s", ".8h", 5574 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5575 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5576 asm, ".1d", ".2s", 5577 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5578 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5579 asm, ".2d", ".4s", 5580 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5581} 5582 5583multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5584 SDPatternOperator OpNode> { 5585 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5586 asm, ".4h", ".8b", 5587 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5588 (v8i8 V64:$Rn)))]>; 5589 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5590 asm, ".8h", ".16b", 5591 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5592 (v16i8 V128:$Rn)))]>; 5593 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5594 asm, ".2s", ".4h", 5595 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5596 (v4i16 V64:$Rn)))]>; 5597 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5598 asm, ".4s", ".8h", 5599 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5600 (v8i16 V128:$Rn)))]>; 5601 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5602 asm, ".1d", ".2s", 5603 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5604 (v2i32 V64:$Rn)))]>; 5605 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5606 asm, ".2d", ".4s", 5607 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5608 (v4i32 V128:$Rn)))]>; 5609} 5610 5611// Supports all element sizes, except 1xD. 5612multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5613 SDPatternOperator OpNode> { 5614 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5615 asm, ".8b", ".8b", 5616 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5617 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5618 asm, ".16b", ".16b", 5619 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5620 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5621 asm, ".4h", ".4h", 5622 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5623 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5624 asm, ".8h", ".8h", 5625 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5626 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5627 asm, ".2s", ".2s", 5628 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5629 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5630 asm, ".4s", ".4s", 5631 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5632 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5633 asm, ".2d", ".2d", 5634 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5635} 5636 5637multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5638 SDPatternOperator OpNode = null_frag> { 5639 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5640 asm, ".8b", ".8b", 5641 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5642 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5643 asm, ".16b", ".16b", 5644 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5645 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5646 asm, ".4h", ".4h", 5647 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5648 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5649 asm, ".8h", ".8h", 5650 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5651 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5652 asm, ".2s", ".2s", 5653 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5654 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5655 asm, ".4s", ".4s", 5656 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5657 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5658 asm, ".2d", ".2d", 5659 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5660} 5661 5662 5663// Supports only B element sizes. 5664multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5665 SDPatternOperator OpNode> { 5666 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5667 asm, ".8b", ".8b", 5668 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5669 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5670 asm, ".16b", ".16b", 5671 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5672 5673} 5674 5675// Supports only B and H element sizes. 5676multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5677 SDPatternOperator OpNode> { 5678 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5679 asm, ".8b", ".8b", 5680 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5681 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5682 asm, ".16b", ".16b", 5683 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5684 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5685 asm, ".4h", ".4h", 5686 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5687 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5688 asm, ".8h", ".8h", 5689 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5690} 5691 5692// Supports H, S and D element sizes, uses high bit of the size field 5693// as an extra opcode bit. 5694multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5695 SDPatternOperator OpNode> { 5696 let Predicates = [HasNEON, HasFullFP16] in { 5697 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5698 asm, ".4h", ".4h", 5699 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5700 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5701 asm, ".8h", ".8h", 5702 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5703 } // Predicates = [HasNEON, HasFullFP16] 5704 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5705 asm, ".2s", ".2s", 5706 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5707 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5708 asm, ".4s", ".4s", 5709 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5710 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5711 asm, ".2d", ".2d", 5712 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5713} 5714 5715// Supports only S and D element sizes 5716multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 5717 SDPatternOperator OpNode = null_frag> { 5718 5719 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 5720 asm, ".2s", ".2s", 5721 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5722 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 5723 asm, ".4s", ".4s", 5724 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5725 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 5726 asm, ".2d", ".2d", 5727 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5728} 5729 5730multiclass FRIntNNTVector<bit U, bit op, string asm, 5731 SDPatternOperator OpNode = null_frag> : 5732 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 5733 5734// Supports only S element size. 5735multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 5736 SDPatternOperator OpNode> { 5737 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5738 asm, ".2s", ".2s", 5739 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5740 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5741 asm, ".4s", ".4s", 5742 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5743} 5744 5745 5746multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 5747 SDPatternOperator OpNode> { 5748 let Predicates = [HasNEON, HasFullFP16] in { 5749 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5750 asm, ".4h", ".4h", 5751 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5752 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5753 asm, ".8h", ".8h", 5754 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5755 } // Predicates = [HasNEON, HasFullFP16] 5756 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5757 asm, ".2s", ".2s", 5758 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5759 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5760 asm, ".4s", ".4s", 5761 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5762 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5763 asm, ".2d", ".2d", 5764 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5765} 5766 5767multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 5768 SDPatternOperator OpNode> { 5769 let Predicates = [HasNEON, HasFullFP16] in { 5770 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5771 asm, ".4h", ".4h", 5772 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5773 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5774 asm, ".8h", ".8h", 5775 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5776 } // Predicates = [HasNEON, HasFullFP16] 5777 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5778 asm, ".2s", ".2s", 5779 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5780 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5781 asm, ".4s", ".4s", 5782 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5783 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5784 asm, ".2d", ".2d", 5785 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5786} 5787 5788 5789class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5790 RegisterOperand inreg, RegisterOperand outreg, 5791 string asm, string outkind, string inkind, 5792 list<dag> pattern> 5793 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 5794 "{\t$Rd" # outkind # ", $Rn" # inkind # 5795 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 5796 Sched<[WriteV]> { 5797 bits<5> Rd; 5798 bits<5> Rn; 5799 let Inst{31} = 0; 5800 let Inst{30} = Q; 5801 let Inst{29} = U; 5802 let Inst{28-24} = 0b01110; 5803 let Inst{23-22} = size; 5804 let Inst{21-17} = 0b10000; 5805 let Inst{16-12} = opcode; 5806 let Inst{11-10} = 0b10; 5807 let Inst{9-5} = Rn; 5808 let Inst{4-0} = Rd; 5809} 5810 5811class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5812 RegisterOperand inreg, RegisterOperand outreg, 5813 string asm, string outkind, string inkind, 5814 list<dag> pattern> 5815 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 5816 "{\t$Rd" # outkind # ", $Rn" # inkind # 5817 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5818 Sched<[WriteV]> { 5819 bits<5> Rd; 5820 bits<5> Rn; 5821 let Inst{31} = 0; 5822 let Inst{30} = Q; 5823 let Inst{29} = U; 5824 let Inst{28-24} = 0b01110; 5825 let Inst{23-22} = size; 5826 let Inst{21-17} = 0b10000; 5827 let Inst{16-12} = opcode; 5828 let Inst{11-10} = 0b10; 5829 let Inst{9-5} = Rn; 5830 let Inst{4-0} = Rd; 5831} 5832 5833multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 5834 SDPatternOperator OpNode> { 5835 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 5836 asm, ".8b", ".8h", 5837 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5838 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 5839 asm#"2", ".16b", ".8h", []>; 5840 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 5841 asm, ".4h", ".4s", 5842 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5843 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 5844 asm#"2", ".8h", ".4s", []>; 5845 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 5846 asm, ".2s", ".2d", 5847 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5848 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 5849 asm#"2", ".4s", ".2d", []>; 5850 5851 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 5852 (!cast<Instruction>(NAME # "v16i8") 5853 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5854 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 5855 (!cast<Instruction>(NAME # "v8i16") 5856 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5857 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 5858 (!cast<Instruction>(NAME # "v4i32") 5859 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5860} 5861 5862class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 5863 bits<5> opcode, RegisterOperand regtype, string asm, 5864 string kind, string zero, ValueType dty, 5865 ValueType sty, SDNode OpNode> 5866 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5867 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 5868 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 5869 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 5870 Sched<[WriteV]> { 5871 bits<5> Rd; 5872 bits<5> Rn; 5873 let Inst{31} = 0; 5874 let Inst{30} = Q; 5875 let Inst{29} = U; 5876 let Inst{28-24} = 0b01110; 5877 let Inst{23-22} = size; 5878 let Inst{21} = 0b1; 5879 let Inst{20-19} = size2; 5880 let Inst{18-17} = 0b00; 5881 let Inst{16-12} = opcode; 5882 let Inst{11-10} = 0b10; 5883 let Inst{9-5} = Rn; 5884 let Inst{4-0} = Rd; 5885} 5886 5887// Comparisons support all element sizes, except 1xD. 5888multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 5889 SDNode OpNode> { 5890 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 5891 asm, ".8b", "0", 5892 v8i8, v8i8, OpNode>; 5893 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 5894 asm, ".16b", "0", 5895 v16i8, v16i8, OpNode>; 5896 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 5897 asm, ".4h", "0", 5898 v4i16, v4i16, OpNode>; 5899 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 5900 asm, ".8h", "0", 5901 v8i16, v8i16, OpNode>; 5902 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 5903 asm, ".2s", "0", 5904 v2i32, v2i32, OpNode>; 5905 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 5906 asm, ".4s", "0", 5907 v4i32, v4i32, OpNode>; 5908 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 5909 asm, ".2d", "0", 5910 v2i64, v2i64, OpNode>; 5911} 5912 5913// FP Comparisons support only S and D element sizes (and H for v8.2a). 5914multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 5915 string asm, SDNode OpNode> { 5916 5917 let Predicates = [HasNEON, HasFullFP16] in { 5918 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 5919 asm, ".4h", "0.0", 5920 v4i16, v4f16, OpNode>; 5921 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 5922 asm, ".8h", "0.0", 5923 v8i16, v8f16, OpNode>; 5924 } // Predicates = [HasNEON, HasFullFP16] 5925 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 5926 asm, ".2s", "0.0", 5927 v2i32, v2f32, OpNode>; 5928 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 5929 asm, ".4s", "0.0", 5930 v4i32, v4f32, OpNode>; 5931 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 5932 asm, ".2d", "0.0", 5933 v2i64, v2f64, OpNode>; 5934 5935 let Predicates = [HasNEON, HasFullFP16] in { 5936 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 5937 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5938 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 5939 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5940 } 5941 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 5942 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5943 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 5944 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5945 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 5946 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5947 let Predicates = [HasNEON, HasFullFP16] in { 5948 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 5949 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5950 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 5951 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5952 } 5953 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 5954 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5955 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 5956 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5957 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 5958 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5959} 5960 5961let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5962class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5963 RegisterOperand outtype, RegisterOperand intype, 5964 string asm, string VdTy, string VnTy, 5965 list<dag> pattern> 5966 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 5967 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 5968 Sched<[WriteV]> { 5969 bits<5> Rd; 5970 bits<5> Rn; 5971 let Inst{31} = 0; 5972 let Inst{30} = Q; 5973 let Inst{29} = U; 5974 let Inst{28-24} = 0b01110; 5975 let Inst{23-22} = size; 5976 let Inst{21-17} = 0b10000; 5977 let Inst{16-12} = opcode; 5978 let Inst{11-10} = 0b10; 5979 let Inst{9-5} = Rn; 5980 let Inst{4-0} = Rd; 5981} 5982 5983class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5984 RegisterOperand outtype, RegisterOperand intype, 5985 string asm, string VdTy, string VnTy, 5986 list<dag> pattern> 5987 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 5988 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 5989 Sched<[WriteV]> { 5990 bits<5> Rd; 5991 bits<5> Rn; 5992 let Inst{31} = 0; 5993 let Inst{30} = Q; 5994 let Inst{29} = U; 5995 let Inst{28-24} = 0b01110; 5996 let Inst{23-22} = size; 5997 let Inst{21-17} = 0b10000; 5998 let Inst{16-12} = opcode; 5999 let Inst{11-10} = 0b10; 6000 let Inst{9-5} = Rn; 6001 let Inst{4-0} = Rd; 6002} 6003 6004multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6005 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6006 asm, ".4s", ".4h", []>; 6007 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6008 asm#"2", ".4s", ".8h", []>; 6009 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6010 asm, ".2d", ".2s", []>; 6011 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6012 asm#"2", ".2d", ".4s", []>; 6013} 6014 6015multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6016 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6017 asm, ".4h", ".4s", []>; 6018 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6019 asm#"2", ".8h", ".4s", []>; 6020 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6021 asm, ".2s", ".2d", []>; 6022 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6023 asm#"2", ".4s", ".2d", []>; 6024} 6025 6026multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6027 Intrinsic OpNode> { 6028 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6029 asm, ".2s", ".2d", 6030 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6031 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6032 asm#"2", ".4s", ".2d", []>; 6033 6034 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6035 (!cast<Instruction>(NAME # "v4f32") 6036 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6037} 6038 6039//---------------------------------------------------------------------------- 6040// AdvSIMD three register different-size vector instructions. 6041//---------------------------------------------------------------------------- 6042 6043let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6044class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6045 RegisterOperand outtype, RegisterOperand intype1, 6046 RegisterOperand intype2, string asm, 6047 string outkind, string inkind1, string inkind2, 6048 list<dag> pattern> 6049 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6050 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6051 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6052 Sched<[WriteV]> { 6053 bits<5> Rd; 6054 bits<5> Rn; 6055 bits<5> Rm; 6056 let Inst{31} = 0; 6057 let Inst{30} = size{0}; 6058 let Inst{29} = U; 6059 let Inst{28-24} = 0b01110; 6060 let Inst{23-22} = size{2-1}; 6061 let Inst{21} = 1; 6062 let Inst{20-16} = Rm; 6063 let Inst{15-12} = opcode; 6064 let Inst{11-10} = 0b00; 6065 let Inst{9-5} = Rn; 6066 let Inst{4-0} = Rd; 6067} 6068 6069let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6070class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6071 RegisterOperand outtype, RegisterOperand intype1, 6072 RegisterOperand intype2, string asm, 6073 string outkind, string inkind1, string inkind2, 6074 list<dag> pattern> 6075 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6076 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6077 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6078 Sched<[WriteV]> { 6079 bits<5> Rd; 6080 bits<5> Rn; 6081 bits<5> Rm; 6082 let Inst{31} = 0; 6083 let Inst{30} = size{0}; 6084 let Inst{29} = U; 6085 let Inst{28-24} = 0b01110; 6086 let Inst{23-22} = size{2-1}; 6087 let Inst{21} = 1; 6088 let Inst{20-16} = Rm; 6089 let Inst{15-12} = opcode; 6090 let Inst{11-10} = 0b00; 6091 let Inst{9-5} = Rn; 6092 let Inst{4-0} = Rd; 6093} 6094 6095// FIXME: TableGen doesn't know how to deal with expanded types that also 6096// change the element count (in this case, placing the results in 6097// the high elements of the result register rather than the low 6098// elements). Until that's fixed, we can't code-gen those. 6099multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6100 Intrinsic IntOp> { 6101 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6102 V64, V128, V128, 6103 asm, ".8b", ".8h", ".8h", 6104 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6105 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6106 V128, V128, V128, 6107 asm#"2", ".16b", ".8h", ".8h", 6108 []>; 6109 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6110 V64, V128, V128, 6111 asm, ".4h", ".4s", ".4s", 6112 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6113 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6114 V128, V128, V128, 6115 asm#"2", ".8h", ".4s", ".4s", 6116 []>; 6117 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6118 V64, V128, V128, 6119 asm, ".2s", ".2d", ".2d", 6120 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6121 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6122 V128, V128, V128, 6123 asm#"2", ".4s", ".2d", ".2d", 6124 []>; 6125 6126 6127 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6128 // a version attached to an instruction. 6129 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6130 (v8i16 V128:$Rm))), 6131 (!cast<Instruction>(NAME # "v8i16_v16i8") 6132 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6133 V128:$Rn, V128:$Rm)>; 6134 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6135 (v4i32 V128:$Rm))), 6136 (!cast<Instruction>(NAME # "v4i32_v8i16") 6137 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6138 V128:$Rn, V128:$Rm)>; 6139 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6140 (v2i64 V128:$Rm))), 6141 (!cast<Instruction>(NAME # "v2i64_v4i32") 6142 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6143 V128:$Rn, V128:$Rm)>; 6144} 6145 6146multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6147 Intrinsic IntOp> { 6148 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6149 V128, V64, V64, 6150 asm, ".8h", ".8b", ".8b", 6151 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6152 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6153 V128, V128, V128, 6154 asm#"2", ".8h", ".16b", ".16b", []>; 6155 let Predicates = [HasAES] in { 6156 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6157 V128, V64, V64, 6158 asm, ".1q", ".1d", ".1d", []>; 6159 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6160 V128, V128, V128, 6161 asm#"2", ".1q", ".2d", ".2d", []>; 6162 } 6163 6164 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6165 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6166 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6167} 6168 6169multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6170 SDPatternOperator OpNode> { 6171 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6172 V128, V64, V64, 6173 asm, ".4s", ".4h", ".4h", 6174 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6175 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6176 V128, V128, V128, 6177 asm#"2", ".4s", ".8h", ".8h", 6178 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6179 (extract_high_v8i16 V128:$Rm)))]>; 6180 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6181 V128, V64, V64, 6182 asm, ".2d", ".2s", ".2s", 6183 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6184 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6185 V128, V128, V128, 6186 asm#"2", ".2d", ".4s", ".4s", 6187 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6188 (extract_high_v4i32 V128:$Rm)))]>; 6189} 6190 6191multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6192 SDPatternOperator OpNode = null_frag> { 6193 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6194 V128, V64, V64, 6195 asm, ".8h", ".8b", ".8b", 6196 [(set (v8i16 V128:$Rd), 6197 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6198 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6199 V128, V128, V128, 6200 asm#"2", ".8h", ".16b", ".16b", 6201 [(set (v8i16 V128:$Rd), 6202 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6203 (extract_high_v16i8 V128:$Rm)))))]>; 6204 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6205 V128, V64, V64, 6206 asm, ".4s", ".4h", ".4h", 6207 [(set (v4i32 V128:$Rd), 6208 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6209 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6210 V128, V128, V128, 6211 asm#"2", ".4s", ".8h", ".8h", 6212 [(set (v4i32 V128:$Rd), 6213 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6214 (extract_high_v8i16 V128:$Rm)))))]>; 6215 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6216 V128, V64, V64, 6217 asm, ".2d", ".2s", ".2s", 6218 [(set (v2i64 V128:$Rd), 6219 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6220 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6221 V128, V128, V128, 6222 asm#"2", ".2d", ".4s", ".4s", 6223 [(set (v2i64 V128:$Rd), 6224 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6225 (extract_high_v4i32 V128:$Rm)))))]>; 6226} 6227 6228multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6229 string asm, 6230 SDPatternOperator OpNode> { 6231 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6232 V128, V64, V64, 6233 asm, ".8h", ".8b", ".8b", 6234 [(set (v8i16 V128:$dst), 6235 (add (v8i16 V128:$Rd), 6236 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6237 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6238 V128, V128, V128, 6239 asm#"2", ".8h", ".16b", ".16b", 6240 [(set (v8i16 V128:$dst), 6241 (add (v8i16 V128:$Rd), 6242 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6243 (extract_high_v16i8 V128:$Rm))))))]>; 6244 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6245 V128, V64, V64, 6246 asm, ".4s", ".4h", ".4h", 6247 [(set (v4i32 V128:$dst), 6248 (add (v4i32 V128:$Rd), 6249 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6250 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6251 V128, V128, V128, 6252 asm#"2", ".4s", ".8h", ".8h", 6253 [(set (v4i32 V128:$dst), 6254 (add (v4i32 V128:$Rd), 6255 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6256 (extract_high_v8i16 V128:$Rm))))))]>; 6257 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6258 V128, V64, V64, 6259 asm, ".2d", ".2s", ".2s", 6260 [(set (v2i64 V128:$dst), 6261 (add (v2i64 V128:$Rd), 6262 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6263 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6264 V128, V128, V128, 6265 asm#"2", ".2d", ".4s", ".4s", 6266 [(set (v2i64 V128:$dst), 6267 (add (v2i64 V128:$Rd), 6268 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6269 (extract_high_v4i32 V128:$Rm))))))]>; 6270} 6271 6272multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6273 SDPatternOperator OpNode = null_frag> { 6274 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6275 V128, V64, V64, 6276 asm, ".8h", ".8b", ".8b", 6277 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6278 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6279 V128, V128, V128, 6280 asm#"2", ".8h", ".16b", ".16b", 6281 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6282 (extract_high_v16i8 V128:$Rm)))]>; 6283 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6284 V128, V64, V64, 6285 asm, ".4s", ".4h", ".4h", 6286 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6287 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6288 V128, V128, V128, 6289 asm#"2", ".4s", ".8h", ".8h", 6290 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6291 (extract_high_v8i16 V128:$Rm)))]>; 6292 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6293 V128, V64, V64, 6294 asm, ".2d", ".2s", ".2s", 6295 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6296 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6297 V128, V128, V128, 6298 asm#"2", ".2d", ".4s", ".4s", 6299 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6300 (extract_high_v4i32 V128:$Rm)))]>; 6301} 6302 6303multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6304 string asm, 6305 SDPatternOperator OpNode> { 6306 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6307 V128, V64, V64, 6308 asm, ".8h", ".8b", ".8b", 6309 [(set (v8i16 V128:$dst), 6310 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6311 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6312 V128, V128, V128, 6313 asm#"2", ".8h", ".16b", ".16b", 6314 [(set (v8i16 V128:$dst), 6315 (OpNode (v8i16 V128:$Rd), 6316 (extract_high_v16i8 V128:$Rn), 6317 (extract_high_v16i8 V128:$Rm)))]>; 6318 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6319 V128, V64, V64, 6320 asm, ".4s", ".4h", ".4h", 6321 [(set (v4i32 V128:$dst), 6322 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6323 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6324 V128, V128, V128, 6325 asm#"2", ".4s", ".8h", ".8h", 6326 [(set (v4i32 V128:$dst), 6327 (OpNode (v4i32 V128:$Rd), 6328 (extract_high_v8i16 V128:$Rn), 6329 (extract_high_v8i16 V128:$Rm)))]>; 6330 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6331 V128, V64, V64, 6332 asm, ".2d", ".2s", ".2s", 6333 [(set (v2i64 V128:$dst), 6334 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6335 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6336 V128, V128, V128, 6337 asm#"2", ".2d", ".4s", ".4s", 6338 [(set (v2i64 V128:$dst), 6339 (OpNode (v2i64 V128:$Rd), 6340 (extract_high_v4i32 V128:$Rn), 6341 (extract_high_v4i32 V128:$Rm)))]>; 6342} 6343 6344multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6345 SDPatternOperator Accum> { 6346 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6347 V128, V64, V64, 6348 asm, ".4s", ".4h", ".4h", 6349 [(set (v4i32 V128:$dst), 6350 (Accum (v4i32 V128:$Rd), 6351 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6352 (v4i16 V64:$Rm)))))]>; 6353 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6354 V128, V128, V128, 6355 asm#"2", ".4s", ".8h", ".8h", 6356 [(set (v4i32 V128:$dst), 6357 (Accum (v4i32 V128:$Rd), 6358 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6359 (extract_high_v8i16 V128:$Rm)))))]>; 6360 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6361 V128, V64, V64, 6362 asm, ".2d", ".2s", ".2s", 6363 [(set (v2i64 V128:$dst), 6364 (Accum (v2i64 V128:$Rd), 6365 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6366 (v2i32 V64:$Rm)))))]>; 6367 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6368 V128, V128, V128, 6369 asm#"2", ".2d", ".4s", ".4s", 6370 [(set (v2i64 V128:$dst), 6371 (Accum (v2i64 V128:$Rd), 6372 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6373 (extract_high_v4i32 V128:$Rm)))))]>; 6374} 6375 6376multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6377 SDPatternOperator OpNode> { 6378 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6379 V128, V128, V64, 6380 asm, ".8h", ".8h", ".8b", 6381 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6382 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6383 V128, V128, V128, 6384 asm#"2", ".8h", ".8h", ".16b", 6385 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6386 (extract_high_v16i8 V128:$Rm)))]>; 6387 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6388 V128, V128, V64, 6389 asm, ".4s", ".4s", ".4h", 6390 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6391 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6392 V128, V128, V128, 6393 asm#"2", ".4s", ".4s", ".8h", 6394 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6395 (extract_high_v8i16 V128:$Rm)))]>; 6396 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6397 V128, V128, V64, 6398 asm, ".2d", ".2d", ".2s", 6399 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6400 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6401 V128, V128, V128, 6402 asm#"2", ".2d", ".2d", ".4s", 6403 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6404 (extract_high_v4i32 V128:$Rm)))]>; 6405} 6406 6407//---------------------------------------------------------------------------- 6408// AdvSIMD bitwise extract from vector 6409//---------------------------------------------------------------------------- 6410 6411class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6412 string asm, string kind> 6413 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6414 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6415 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6416 [(set (vty regtype:$Rd), 6417 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6418 Sched<[WriteV]> { 6419 bits<5> Rd; 6420 bits<5> Rn; 6421 bits<5> Rm; 6422 bits<4> imm; 6423 let Inst{31} = 0; 6424 let Inst{30} = size; 6425 let Inst{29-21} = 0b101110000; 6426 let Inst{20-16} = Rm; 6427 let Inst{15} = 0; 6428 let Inst{14-11} = imm; 6429 let Inst{10} = 0; 6430 let Inst{9-5} = Rn; 6431 let Inst{4-0} = Rd; 6432} 6433 6434 6435multiclass SIMDBitwiseExtract<string asm> { 6436 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6437 let imm{3} = 0; 6438 } 6439 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6440} 6441 6442//---------------------------------------------------------------------------- 6443// AdvSIMD zip vector 6444//---------------------------------------------------------------------------- 6445 6446class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6447 string asm, string kind, SDNode OpNode, ValueType valty> 6448 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6449 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6450 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6451 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6452 Sched<[WriteV]> { 6453 bits<5> Rd; 6454 bits<5> Rn; 6455 bits<5> Rm; 6456 let Inst{31} = 0; 6457 let Inst{30} = size{0}; 6458 let Inst{29-24} = 0b001110; 6459 let Inst{23-22} = size{2-1}; 6460 let Inst{21} = 0; 6461 let Inst{20-16} = Rm; 6462 let Inst{15} = 0; 6463 let Inst{14-12} = opc; 6464 let Inst{11-10} = 0b10; 6465 let Inst{9-5} = Rn; 6466 let Inst{4-0} = Rd; 6467} 6468 6469multiclass SIMDZipVector<bits<3>opc, string asm, 6470 SDNode OpNode> { 6471 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6472 asm, ".8b", OpNode, v8i8>; 6473 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6474 asm, ".16b", OpNode, v16i8>; 6475 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6476 asm, ".4h", OpNode, v4i16>; 6477 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6478 asm, ".8h", OpNode, v8i16>; 6479 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6480 asm, ".2s", OpNode, v2i32>; 6481 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6482 asm, ".4s", OpNode, v4i32>; 6483 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6484 asm, ".2d", OpNode, v2i64>; 6485 6486 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6487 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6488 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6489 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6490 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6491 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6492 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6493 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6494 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6495 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6496} 6497 6498//---------------------------------------------------------------------------- 6499// AdvSIMD three register scalar instructions 6500//---------------------------------------------------------------------------- 6501 6502let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6503class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6504 RegisterClass regtype, string asm, 6505 list<dag> pattern> 6506 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6507 "\t$Rd, $Rn, $Rm", "", pattern>, 6508 Sched<[WriteV]> { 6509 bits<5> Rd; 6510 bits<5> Rn; 6511 bits<5> Rm; 6512 let Inst{31-30} = 0b01; 6513 let Inst{29} = U; 6514 let Inst{28-24} = 0b11110; 6515 let Inst{23-21} = size; 6516 let Inst{20-16} = Rm; 6517 let Inst{15-11} = opcode; 6518 let Inst{10} = 1; 6519 let Inst{9-5} = Rn; 6520 let Inst{4-0} = Rd; 6521} 6522 6523let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6524class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6525 dag oops, dag iops, string asm, 6526 list<dag> pattern> 6527 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6528 Sched<[WriteV]> { 6529 bits<5> Rd; 6530 bits<5> Rn; 6531 bits<5> Rm; 6532 let Inst{31-30} = 0b01; 6533 let Inst{29} = U; 6534 let Inst{28-24} = 0b11110; 6535 let Inst{23-22} = size; 6536 let Inst{21} = R; 6537 let Inst{20-16} = Rm; 6538 let Inst{15-11} = opcode; 6539 let Inst{10} = 1; 6540 let Inst{9-5} = Rn; 6541 let Inst{4-0} = Rd; 6542} 6543 6544multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6545 SDPatternOperator OpNode> { 6546 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6547 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6548} 6549 6550multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6551 SDPatternOperator OpNode> { 6552 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6553 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6554 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6555 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6556 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6557 6558 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6559 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6560 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6561 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6562} 6563 6564multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6565 SDPatternOperator OpNode> { 6566 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6567 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6568 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6569} 6570 6571multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 6572 SDPatternOperator OpNode = null_frag> { 6573 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6574 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6575 asm, []>; 6576 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6577 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6578 asm, []>; 6579} 6580 6581multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6582 SDPatternOperator OpNode = null_frag> { 6583 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6584 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6585 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6586 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6587 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6588 let Predicates = [HasNEON, HasFullFP16] in { 6589 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6590 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>; 6591 } // Predicates = [HasNEON, HasFullFP16] 6592 } 6593 6594 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6595 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6596} 6597 6598multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6599 SDPatternOperator OpNode = null_frag> { 6600 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6601 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6602 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6603 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6604 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6605 let Predicates = [HasNEON, HasFullFP16] in { 6606 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6607 []>; 6608 } // Predicates = [HasNEON, HasFullFP16] 6609 } 6610 6611 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6612 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6613} 6614 6615class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6616 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6617 : I<oops, iops, asm, 6618 "\t$Rd, $Rn, $Rm", cstr, pat>, 6619 Sched<[WriteV]> { 6620 bits<5> Rd; 6621 bits<5> Rn; 6622 bits<5> Rm; 6623 let Inst{31-30} = 0b01; 6624 let Inst{29} = U; 6625 let Inst{28-24} = 0b11110; 6626 let Inst{23-22} = size; 6627 let Inst{21} = 1; 6628 let Inst{20-16} = Rm; 6629 let Inst{15-11} = opcode; 6630 let Inst{10} = 0; 6631 let Inst{9-5} = Rn; 6632 let Inst{4-0} = Rd; 6633} 6634 6635let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6636multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6637 SDPatternOperator OpNode = null_frag> { 6638 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6639 (outs FPR32:$Rd), 6640 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6641 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6642 (outs FPR64:$Rd), 6643 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6644 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6645} 6646 6647let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6648multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6649 SDPatternOperator OpNode = null_frag> { 6650 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6651 (outs FPR32:$dst), 6652 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6653 asm, "$Rd = $dst", []>; 6654 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6655 (outs FPR64:$dst), 6656 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6657 asm, "$Rd = $dst", 6658 [(set (i64 FPR64:$dst), 6659 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6660} 6661 6662//---------------------------------------------------------------------------- 6663// AdvSIMD two register scalar instructions 6664//---------------------------------------------------------------------------- 6665 6666let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6667class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6668 RegisterClass regtype, RegisterClass regtype2, 6669 string asm, list<dag> pat> 6670 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6671 "\t$Rd, $Rn", "", pat>, 6672 Sched<[WriteV]> { 6673 bits<5> Rd; 6674 bits<5> Rn; 6675 let Inst{31-30} = 0b01; 6676 let Inst{29} = U; 6677 let Inst{28-24} = 0b11110; 6678 let Inst{23-22} = size; 6679 let Inst{21} = 0b1; 6680 let Inst{20-19} = size2; 6681 let Inst{18-17} = 0b00; 6682 let Inst{16-12} = opcode; 6683 let Inst{11-10} = 0b10; 6684 let Inst{9-5} = Rn; 6685 let Inst{4-0} = Rd; 6686} 6687 6688let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6689class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6690 RegisterClass regtype, RegisterClass regtype2, 6691 string asm, list<dag> pat> 6692 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6693 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6694 Sched<[WriteV]> { 6695 bits<5> Rd; 6696 bits<5> Rn; 6697 let Inst{31-30} = 0b01; 6698 let Inst{29} = U; 6699 let Inst{28-24} = 0b11110; 6700 let Inst{23-22} = size; 6701 let Inst{21-17} = 0b10000; 6702 let Inst{16-12} = opcode; 6703 let Inst{11-10} = 0b10; 6704 let Inst{9-5} = Rn; 6705 let Inst{4-0} = Rd; 6706} 6707 6708 6709let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6710class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6711 RegisterClass regtype, string asm, string zero> 6712 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6713 "\t$Rd, $Rn, #" # zero, "", []>, 6714 Sched<[WriteV]> { 6715 bits<5> Rd; 6716 bits<5> Rn; 6717 let Inst{31-30} = 0b01; 6718 let Inst{29} = U; 6719 let Inst{28-24} = 0b11110; 6720 let Inst{23-22} = size; 6721 let Inst{21} = 0b1; 6722 let Inst{20-19} = size2; 6723 let Inst{18-17} = 0b00; 6724 let Inst{16-12} = opcode; 6725 let Inst{11-10} = 0b10; 6726 let Inst{9-5} = Rn; 6727 let Inst{4-0} = Rd; 6728} 6729 6730class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 6731 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 6732 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 6733 Sched<[WriteV]> { 6734 bits<5> Rd; 6735 bits<5> Rn; 6736 let Inst{31-17} = 0b011111100110000; 6737 let Inst{16-12} = opcode; 6738 let Inst{11-10} = 0b10; 6739 let Inst{9-5} = Rn; 6740 let Inst{4-0} = Rd; 6741} 6742 6743multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 6744 SDPatternOperator OpNode> { 6745 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 6746 6747 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 6748 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6749} 6750 6751multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 6752 SDPatternOperator OpNode> { 6753 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 6754 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 6755 let Predicates = [HasNEON, HasFullFP16] in { 6756 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 6757 } 6758 6759 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6760 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 6761 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6762 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 6763 let Predicates = [HasNEON, HasFullFP16] in { 6764 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6765 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 6766 } 6767 6768 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 6769 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6770} 6771 6772multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 6773 SDPatternOperator OpNode = null_frag> { 6774 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6775 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 6776 6777 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 6778 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 6779} 6780 6781multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 6782 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 6783 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 6784 let Predicates = [HasNEON, HasFullFP16] in { 6785 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 6786 } 6787} 6788 6789multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 6790 SDPatternOperator OpNode> { 6791 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 6792 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 6793 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 6794 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 6795 let Predicates = [HasNEON, HasFullFP16] in { 6796 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 6797 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>; 6798 } 6799} 6800 6801multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 6802 SDPatternOperator OpNode = null_frag> { 6803 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6804 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6805 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 6806 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 6807 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 6808 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 6809 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 6810 } 6811 6812 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 6813 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 6814} 6815 6816multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 6817 Intrinsic OpNode> { 6818 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6819 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 6820 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 6821 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 6822 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 6823 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 6824 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 6825 } 6826 6827 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 6828 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 6829} 6830 6831 6832 6833let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6834multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 6835 SDPatternOperator OpNode = null_frag> { 6836 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 6837 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 6838 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 6839 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 6840} 6841 6842//---------------------------------------------------------------------------- 6843// AdvSIMD scalar pairwise instructions 6844//---------------------------------------------------------------------------- 6845 6846let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6847class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 6848 RegisterOperand regtype, RegisterOperand vectype, 6849 string asm, string kind> 6850 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 6851 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 6852 Sched<[WriteV]> { 6853 bits<5> Rd; 6854 bits<5> Rn; 6855 let Inst{31-30} = 0b01; 6856 let Inst{29} = U; 6857 let Inst{28-24} = 0b11110; 6858 let Inst{23-22} = size; 6859 let Inst{21-17} = 0b11000; 6860 let Inst{16-12} = opcode; 6861 let Inst{11-10} = 0b10; 6862 let Inst{9-5} = Rn; 6863 let Inst{4-0} = Rd; 6864} 6865 6866multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 6867 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 6868 asm, ".2d">; 6869} 6870 6871multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 6872 let Predicates = [HasNEON, HasFullFP16] in { 6873 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 6874 asm, ".2h">; 6875 } 6876 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 6877 asm, ".2s">; 6878 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 6879 asm, ".2d">; 6880} 6881 6882//---------------------------------------------------------------------------- 6883// AdvSIMD across lanes instructions 6884//---------------------------------------------------------------------------- 6885 6886let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6887class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 6888 RegisterClass regtype, RegisterOperand vectype, 6889 string asm, string kind, list<dag> pattern> 6890 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 6891 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 6892 Sched<[WriteV]> { 6893 bits<5> Rd; 6894 bits<5> Rn; 6895 let Inst{31} = 0; 6896 let Inst{30} = Q; 6897 let Inst{29} = U; 6898 let Inst{28-24} = 0b01110; 6899 let Inst{23-22} = size; 6900 let Inst{21-17} = 0b11000; 6901 let Inst{16-12} = opcode; 6902 let Inst{11-10} = 0b10; 6903 let Inst{9-5} = Rn; 6904 let Inst{4-0} = Rd; 6905} 6906 6907multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 6908 string asm> { 6909 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 6910 asm, ".8b", []>; 6911 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 6912 asm, ".16b", []>; 6913 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 6914 asm, ".4h", []>; 6915 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 6916 asm, ".8h", []>; 6917 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 6918 asm, ".4s", []>; 6919} 6920 6921multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 6922 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 6923 asm, ".8b", []>; 6924 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 6925 asm, ".16b", []>; 6926 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 6927 asm, ".4h", []>; 6928 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 6929 asm, ".8h", []>; 6930 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 6931 asm, ".4s", []>; 6932} 6933 6934multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 6935 Intrinsic intOp> { 6936 let Predicates = [HasNEON, HasFullFP16] in { 6937 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 6938 asm, ".4h", 6939 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>; 6940 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 6941 asm, ".8h", 6942 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>; 6943 } // Predicates = [HasNEON, HasFullFP16] 6944 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 6945 asm, ".4s", 6946 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 6947} 6948 6949//---------------------------------------------------------------------------- 6950// AdvSIMD INS/DUP instructions 6951//---------------------------------------------------------------------------- 6952 6953// FIXME: There has got to be a better way to factor these. ugh. 6954 6955class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 6956 string operands, string constraints, list<dag> pattern> 6957 : I<outs, ins, asm, operands, constraints, pattern>, 6958 Sched<[WriteV]> { 6959 bits<5> Rd; 6960 bits<5> Rn; 6961 let Inst{31} = 0; 6962 let Inst{30} = Q; 6963 let Inst{29} = op; 6964 let Inst{28-21} = 0b01110000; 6965 let Inst{15} = 0; 6966 let Inst{10} = 1; 6967 let Inst{9-5} = Rn; 6968 let Inst{4-0} = Rd; 6969} 6970 6971class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 6972 RegisterOperand vecreg, RegisterClass regtype> 6973 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 6974 "{\t$Rd" # size # ", $Rn" # 6975 "|" # size # "\t$Rd, $Rn}", "", 6976 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 6977 let Inst{20-16} = imm5; 6978 let Inst{14-11} = 0b0001; 6979} 6980 6981class SIMDDupFromElement<bit Q, string dstkind, string srckind, 6982 ValueType vectype, ValueType insreg, 6983 RegisterOperand vecreg, Operand idxtype, 6984 ValueType elttype, SDNode OpNode> 6985 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 6986 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 6987 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 6988 [(set (vectype vecreg:$Rd), 6989 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 6990 let Inst{14-11} = 0b0000; 6991} 6992 6993class SIMDDup64FromElement 6994 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 6995 VectorIndexD, i64, AArch64duplane64> { 6996 bits<1> idx; 6997 let Inst{20} = idx; 6998 let Inst{19-16} = 0b1000; 6999} 7000 7001class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7002 RegisterOperand vecreg> 7003 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7004 VectorIndexS, i64, AArch64duplane32> { 7005 bits<2> idx; 7006 let Inst{20-19} = idx; 7007 let Inst{18-16} = 0b100; 7008} 7009 7010class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7011 RegisterOperand vecreg> 7012 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7013 VectorIndexH, i64, AArch64duplane16> { 7014 bits<3> idx; 7015 let Inst{20-18} = idx; 7016 let Inst{17-16} = 0b10; 7017} 7018 7019class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7020 RegisterOperand vecreg> 7021 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7022 VectorIndexB, i64, AArch64duplane8> { 7023 bits<4> idx; 7024 let Inst{20-17} = idx; 7025 let Inst{16} = 1; 7026} 7027 7028class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7029 Operand idxtype, string asm, list<dag> pattern> 7030 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7031 "{\t$Rd, $Rn" # size # "$idx" # 7032 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7033 let Inst{14-11} = imm4; 7034} 7035 7036class SIMDSMov<bit Q, string size, RegisterClass regtype, 7037 Operand idxtype> 7038 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7039class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7040 Operand idxtype> 7041 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7042 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7043 7044class SIMDMovAlias<string asm, string size, Instruction inst, 7045 RegisterClass regtype, Operand idxtype> 7046 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7047 "|" # size # "\t$dst, $src$idx}", 7048 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7049 7050multiclass SMov { 7051 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7052 bits<4> idx; 7053 let Inst{20-17} = idx; 7054 let Inst{16} = 1; 7055 } 7056 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7057 bits<4> idx; 7058 let Inst{20-17} = idx; 7059 let Inst{16} = 1; 7060 } 7061 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7062 bits<3> idx; 7063 let Inst{20-18} = idx; 7064 let Inst{17-16} = 0b10; 7065 } 7066 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7067 bits<3> idx; 7068 let Inst{20-18} = idx; 7069 let Inst{17-16} = 0b10; 7070 } 7071 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7072 bits<2> idx; 7073 let Inst{20-19} = idx; 7074 let Inst{18-16} = 0b100; 7075 } 7076} 7077 7078multiclass UMov { 7079 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7080 bits<4> idx; 7081 let Inst{20-17} = idx; 7082 let Inst{16} = 1; 7083 } 7084 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7085 bits<3> idx; 7086 let Inst{20-18} = idx; 7087 let Inst{17-16} = 0b10; 7088 } 7089 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7090 bits<2> idx; 7091 let Inst{20-19} = idx; 7092 let Inst{18-16} = 0b100; 7093 } 7094 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7095 bits<1> idx; 7096 let Inst{20} = idx; 7097 let Inst{19-16} = 0b1000; 7098 } 7099 def : SIMDMovAlias<"mov", ".s", 7100 !cast<Instruction>(NAME#"vi32"), 7101 GPR32, VectorIndexS>; 7102 def : SIMDMovAlias<"mov", ".d", 7103 !cast<Instruction>(NAME#"vi64"), 7104 GPR64, VectorIndexD>; 7105} 7106 7107class SIMDInsFromMain<string size, ValueType vectype, 7108 RegisterClass regtype, Operand idxtype> 7109 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7110 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7111 "{\t$Rd" # size # "$idx, $Rn" # 7112 "|" # size # "\t$Rd$idx, $Rn}", 7113 "$Rd = $dst", 7114 [(set V128:$dst, 7115 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7116 let Inst{14-11} = 0b0011; 7117} 7118 7119class SIMDInsFromElement<string size, ValueType vectype, 7120 ValueType elttype, Operand idxtype> 7121 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7122 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7123 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7124 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7125 "$Rd = $dst", 7126 [(set V128:$dst, 7127 (vector_insert 7128 (vectype V128:$Rd), 7129 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7130 idxtype:$idx))]>; 7131 7132class SIMDInsMainMovAlias<string size, Instruction inst, 7133 RegisterClass regtype, Operand idxtype> 7134 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7135 "|" # size #"\t$dst$idx, $src}", 7136 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7137class SIMDInsElementMovAlias<string size, Instruction inst, 7138 Operand idxtype> 7139 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" # 7140 # "|" # size #"\t$dst$idx, $src$idx2}", 7141 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7142 7143 7144multiclass SIMDIns { 7145 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7146 bits<4> idx; 7147 let Inst{20-17} = idx; 7148 let Inst{16} = 1; 7149 } 7150 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7151 bits<3> idx; 7152 let Inst{20-18} = idx; 7153 let Inst{17-16} = 0b10; 7154 } 7155 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7156 bits<2> idx; 7157 let Inst{20-19} = idx; 7158 let Inst{18-16} = 0b100; 7159 } 7160 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7161 bits<1> idx; 7162 let Inst{20} = idx; 7163 let Inst{19-16} = 0b1000; 7164 } 7165 7166 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7167 bits<4> idx; 7168 bits<4> idx2; 7169 let Inst{20-17} = idx; 7170 let Inst{16} = 1; 7171 let Inst{14-11} = idx2; 7172 } 7173 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7174 bits<3> idx; 7175 bits<3> idx2; 7176 let Inst{20-18} = idx; 7177 let Inst{17-16} = 0b10; 7178 let Inst{14-12} = idx2; 7179 let Inst{11} = {?}; 7180 } 7181 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7182 bits<2> idx; 7183 bits<2> idx2; 7184 let Inst{20-19} = idx; 7185 let Inst{18-16} = 0b100; 7186 let Inst{14-13} = idx2; 7187 let Inst{12-11} = {?,?}; 7188 } 7189 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7190 bits<1> idx; 7191 bits<1> idx2; 7192 let Inst{20} = idx; 7193 let Inst{19-16} = 0b1000; 7194 let Inst{14} = idx2; 7195 let Inst{13-11} = {?,?,?}; 7196 } 7197 7198 // For all forms of the INS instruction, the "mov" mnemonic is the 7199 // preferred alias. Why they didn't just call the instruction "mov" in 7200 // the first place is a very good question indeed... 7201 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7202 GPR32, VectorIndexB>; 7203 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7204 GPR32, VectorIndexH>; 7205 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7206 GPR32, VectorIndexS>; 7207 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7208 GPR64, VectorIndexD>; 7209 7210 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7211 VectorIndexB>; 7212 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7213 VectorIndexH>; 7214 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7215 VectorIndexS>; 7216 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7217 VectorIndexD>; 7218} 7219 7220//---------------------------------------------------------------------------- 7221// AdvSIMD TBL/TBX 7222//---------------------------------------------------------------------------- 7223 7224let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7225class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7226 RegisterOperand listtype, string asm, string kind> 7227 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7228 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7229 Sched<[WriteV]> { 7230 bits<5> Vd; 7231 bits<5> Vn; 7232 bits<5> Vm; 7233 let Inst{31} = 0; 7234 let Inst{30} = Q; 7235 let Inst{29-21} = 0b001110000; 7236 let Inst{20-16} = Vm; 7237 let Inst{15} = 0; 7238 let Inst{14-13} = len; 7239 let Inst{12} = op; 7240 let Inst{11-10} = 0b00; 7241 let Inst{9-5} = Vn; 7242 let Inst{4-0} = Vd; 7243} 7244 7245let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7246class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7247 RegisterOperand listtype, string asm, string kind> 7248 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7249 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7250 Sched<[WriteV]> { 7251 bits<5> Vd; 7252 bits<5> Vn; 7253 bits<5> Vm; 7254 let Inst{31} = 0; 7255 let Inst{30} = Q; 7256 let Inst{29-21} = 0b001110000; 7257 let Inst{20-16} = Vm; 7258 let Inst{15} = 0; 7259 let Inst{14-13} = len; 7260 let Inst{12} = op; 7261 let Inst{11-10} = 0b00; 7262 let Inst{9-5} = Vn; 7263 let Inst{4-0} = Vd; 7264} 7265 7266class SIMDTableLookupAlias<string asm, Instruction inst, 7267 RegisterOperand vectype, RegisterOperand listtype> 7268 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7269 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7270 7271multiclass SIMDTableLookup<bit op, string asm> { 7272 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7273 asm, ".8b">; 7274 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7275 asm, ".8b">; 7276 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7277 asm, ".8b">; 7278 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7279 asm, ".8b">; 7280 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7281 asm, ".16b">; 7282 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7283 asm, ".16b">; 7284 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7285 asm, ".16b">; 7286 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7287 asm, ".16b">; 7288 7289 def : SIMDTableLookupAlias<asm # ".8b", 7290 !cast<Instruction>(NAME#"v8i8One"), 7291 V64, VecListOne128>; 7292 def : SIMDTableLookupAlias<asm # ".8b", 7293 !cast<Instruction>(NAME#"v8i8Two"), 7294 V64, VecListTwo128>; 7295 def : SIMDTableLookupAlias<asm # ".8b", 7296 !cast<Instruction>(NAME#"v8i8Three"), 7297 V64, VecListThree128>; 7298 def : SIMDTableLookupAlias<asm # ".8b", 7299 !cast<Instruction>(NAME#"v8i8Four"), 7300 V64, VecListFour128>; 7301 def : SIMDTableLookupAlias<asm # ".16b", 7302 !cast<Instruction>(NAME#"v16i8One"), 7303 V128, VecListOne128>; 7304 def : SIMDTableLookupAlias<asm # ".16b", 7305 !cast<Instruction>(NAME#"v16i8Two"), 7306 V128, VecListTwo128>; 7307 def : SIMDTableLookupAlias<asm # ".16b", 7308 !cast<Instruction>(NAME#"v16i8Three"), 7309 V128, VecListThree128>; 7310 def : SIMDTableLookupAlias<asm # ".16b", 7311 !cast<Instruction>(NAME#"v16i8Four"), 7312 V128, VecListFour128>; 7313} 7314 7315multiclass SIMDTableLookupTied<bit op, string asm> { 7316 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7317 asm, ".8b">; 7318 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7319 asm, ".8b">; 7320 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7321 asm, ".8b">; 7322 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7323 asm, ".8b">; 7324 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7325 asm, ".16b">; 7326 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7327 asm, ".16b">; 7328 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7329 asm, ".16b">; 7330 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7331 asm, ".16b">; 7332 7333 def : SIMDTableLookupAlias<asm # ".8b", 7334 !cast<Instruction>(NAME#"v8i8One"), 7335 V64, VecListOne128>; 7336 def : SIMDTableLookupAlias<asm # ".8b", 7337 !cast<Instruction>(NAME#"v8i8Two"), 7338 V64, VecListTwo128>; 7339 def : SIMDTableLookupAlias<asm # ".8b", 7340 !cast<Instruction>(NAME#"v8i8Three"), 7341 V64, VecListThree128>; 7342 def : SIMDTableLookupAlias<asm # ".8b", 7343 !cast<Instruction>(NAME#"v8i8Four"), 7344 V64, VecListFour128>; 7345 def : SIMDTableLookupAlias<asm # ".16b", 7346 !cast<Instruction>(NAME#"v16i8One"), 7347 V128, VecListOne128>; 7348 def : SIMDTableLookupAlias<asm # ".16b", 7349 !cast<Instruction>(NAME#"v16i8Two"), 7350 V128, VecListTwo128>; 7351 def : SIMDTableLookupAlias<asm # ".16b", 7352 !cast<Instruction>(NAME#"v16i8Three"), 7353 V128, VecListThree128>; 7354 def : SIMDTableLookupAlias<asm # ".16b", 7355 !cast<Instruction>(NAME#"v16i8Four"), 7356 V128, VecListFour128>; 7357} 7358 7359 7360//---------------------------------------------------------------------------- 7361// AdvSIMD scalar CPY 7362//---------------------------------------------------------------------------- 7363let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7364class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 7365 string kind, Operand idxtype> 7366 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 7367 "{\t$dst, $src" # kind # "$idx" # 7368 "|\t$dst, $src$idx}", "", []>, 7369 Sched<[WriteV]> { 7370 bits<5> dst; 7371 bits<5> src; 7372 let Inst{31-21} = 0b01011110000; 7373 let Inst{15-10} = 0b000001; 7374 let Inst{9-5} = src; 7375 let Inst{4-0} = dst; 7376} 7377 7378class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 7379 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7380 : InstAlias<asm # "{\t$dst, $src" # size # "$index" # 7381 # "|\t$dst, $src$index}", 7382 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7383 7384 7385multiclass SIMDScalarCPY<string asm> { 7386 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 7387 bits<4> idx; 7388 let Inst{20-17} = idx; 7389 let Inst{16} = 1; 7390 } 7391 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 7392 bits<3> idx; 7393 let Inst{20-18} = idx; 7394 let Inst{17-16} = 0b10; 7395 } 7396 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 7397 bits<2> idx; 7398 let Inst{20-19} = idx; 7399 let Inst{18-16} = 0b100; 7400 } 7401 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 7402 bits<1> idx; 7403 let Inst{20} = idx; 7404 let Inst{19-16} = 0b1000; 7405 } 7406 7407 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7408 VectorIndexD:$idx)))), 7409 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7410 7411 // 'DUP' mnemonic aliases. 7412 def : SIMDScalarCPYAlias<"dup", ".b", 7413 !cast<Instruction>(NAME#"i8"), 7414 FPR8, V128, VectorIndexB>; 7415 def : SIMDScalarCPYAlias<"dup", ".h", 7416 !cast<Instruction>(NAME#"i16"), 7417 FPR16, V128, VectorIndexH>; 7418 def : SIMDScalarCPYAlias<"dup", ".s", 7419 !cast<Instruction>(NAME#"i32"), 7420 FPR32, V128, VectorIndexS>; 7421 def : SIMDScalarCPYAlias<"dup", ".d", 7422 !cast<Instruction>(NAME#"i64"), 7423 FPR64, V128, VectorIndexD>; 7424} 7425 7426//---------------------------------------------------------------------------- 7427// AdvSIMD modified immediate instructions 7428//---------------------------------------------------------------------------- 7429 7430class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7431 string asm, string op_string, 7432 string cstr, list<dag> pattern> 7433 : I<oops, iops, asm, op_string, cstr, pattern>, 7434 Sched<[WriteV]> { 7435 bits<5> Rd; 7436 bits<8> imm8; 7437 let Inst{31} = 0; 7438 let Inst{30} = Q; 7439 let Inst{29} = op; 7440 let Inst{28-19} = 0b0111100000; 7441 let Inst{18-16} = imm8{7-5}; 7442 let Inst{11} = op2; 7443 let Inst{10} = 1; 7444 let Inst{9-5} = imm8{4-0}; 7445 let Inst{4-0} = Rd; 7446} 7447 7448class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7449 Operand immtype, dag opt_shift_iop, 7450 string opt_shift, string asm, string kind, 7451 list<dag> pattern> 7452 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7453 !con((ins immtype:$imm8), opt_shift_iop), asm, 7454 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7455 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7456 "", pattern> { 7457 let DecoderMethod = "DecodeModImmInstruction"; 7458} 7459 7460class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7461 Operand immtype, dag opt_shift_iop, 7462 string opt_shift, string asm, string kind, 7463 list<dag> pattern> 7464 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7465 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7466 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7467 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7468 "$Rd = $dst", pattern> { 7469 let DecoderMethod = "DecodeModImmTiedInstruction"; 7470} 7471 7472class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7473 RegisterOperand vectype, string asm, 7474 string kind, list<dag> pattern> 7475 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7476 (ins logical_vec_shift:$shift), 7477 "$shift", asm, kind, pattern> { 7478 bits<2> shift; 7479 let Inst{15} = b15_b12{1}; 7480 let Inst{14-13} = shift; 7481 let Inst{12} = b15_b12{0}; 7482} 7483 7484class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7485 RegisterOperand vectype, string asm, 7486 string kind, list<dag> pattern> 7487 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7488 (ins logical_vec_shift:$shift), 7489 "$shift", asm, kind, pattern> { 7490 bits<2> shift; 7491 let Inst{15} = b15_b12{1}; 7492 let Inst{14-13} = shift; 7493 let Inst{12} = b15_b12{0}; 7494} 7495 7496 7497class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7498 RegisterOperand vectype, string asm, 7499 string kind, list<dag> pattern> 7500 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7501 (ins logical_vec_hw_shift:$shift), 7502 "$shift", asm, kind, pattern> { 7503 bits<2> shift; 7504 let Inst{15} = b15_b12{1}; 7505 let Inst{14} = 0; 7506 let Inst{13} = shift{0}; 7507 let Inst{12} = b15_b12{0}; 7508} 7509 7510class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7511 RegisterOperand vectype, string asm, 7512 string kind, list<dag> pattern> 7513 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7514 (ins logical_vec_hw_shift:$shift), 7515 "$shift", asm, kind, pattern> { 7516 bits<2> shift; 7517 let Inst{15} = b15_b12{1}; 7518 let Inst{14} = 0; 7519 let Inst{13} = shift{0}; 7520 let Inst{12} = b15_b12{0}; 7521} 7522 7523multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7524 string asm> { 7525 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7526 asm, ".4h", []>; 7527 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7528 asm, ".8h", []>; 7529 7530 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7531 asm, ".2s", []>; 7532 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7533 asm, ".4s", []>; 7534} 7535 7536multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7537 bits<2> w_cmode, string asm, 7538 SDNode OpNode> { 7539 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7540 asm, ".4h", 7541 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7542 imm0_255:$imm8, 7543 (i32 imm:$shift)))]>; 7544 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7545 asm, ".8h", 7546 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7547 imm0_255:$imm8, 7548 (i32 imm:$shift)))]>; 7549 7550 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7551 asm, ".2s", 7552 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7553 imm0_255:$imm8, 7554 (i32 imm:$shift)))]>; 7555 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7556 asm, ".4s", 7557 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7558 imm0_255:$imm8, 7559 (i32 imm:$shift)))]>; 7560} 7561 7562class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7563 RegisterOperand vectype, string asm, 7564 string kind, list<dag> pattern> 7565 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7566 (ins move_vec_shift:$shift), 7567 "$shift", asm, kind, pattern> { 7568 bits<1> shift; 7569 let Inst{15-13} = cmode{3-1}; 7570 let Inst{12} = shift; 7571} 7572 7573class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7574 RegisterOperand vectype, 7575 Operand imm_type, string asm, 7576 string kind, list<dag> pattern> 7577 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7578 asm, kind, pattern> { 7579 let Inst{15-12} = cmode; 7580} 7581 7582class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7583 list<dag> pattern> 7584 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7585 "\t$Rd, $imm8", "", pattern> { 7586 let Inst{15-12} = cmode; 7587 let DecoderMethod = "DecodeModImmInstruction"; 7588} 7589 7590//---------------------------------------------------------------------------- 7591// AdvSIMD indexed element 7592//---------------------------------------------------------------------------- 7593 7594let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7595class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7596 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7597 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7598 string apple_kind, string dst_kind, string lhs_kind, 7599 string rhs_kind, list<dag> pattern> 7600 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7601 asm, 7602 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7603 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7604 Sched<[WriteV]> { 7605 bits<5> Rd; 7606 bits<5> Rn; 7607 bits<5> Rm; 7608 7609 let Inst{31} = 0; 7610 let Inst{30} = Q; 7611 let Inst{29} = U; 7612 let Inst{28} = Scalar; 7613 let Inst{27-24} = 0b1111; 7614 let Inst{23-22} = size; 7615 // Bit 21 must be set by the derived class. 7616 let Inst{20-16} = Rm; 7617 let Inst{15-12} = opc; 7618 // Bit 11 must be set by the derived class. 7619 let Inst{10} = 0; 7620 let Inst{9-5} = Rn; 7621 let Inst{4-0} = Rd; 7622} 7623 7624let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7625class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7626 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7627 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7628 string apple_kind, string dst_kind, string lhs_kind, 7629 string rhs_kind, list<dag> pattern> 7630 : I<(outs dst_reg:$dst), 7631 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7632 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7633 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7634 Sched<[WriteV]> { 7635 bits<5> Rd; 7636 bits<5> Rn; 7637 bits<5> Rm; 7638 7639 let Inst{31} = 0; 7640 let Inst{30} = Q; 7641 let Inst{29} = U; 7642 let Inst{28} = Scalar; 7643 let Inst{27-24} = 0b1111; 7644 let Inst{23-22} = size; 7645 // Bit 21 must be set by the derived class. 7646 let Inst{20-16} = Rm; 7647 let Inst{15-12} = opc; 7648 // Bit 11 must be set by the derived class. 7649 let Inst{10} = 0; 7650 let Inst{9-5} = Rn; 7651 let Inst{4-0} = Rd; 7652} 7653 7654// ARMv8.2-A Dot Product Instructions (Indexed) 7655class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, string asm, string dst_kind, 7656 string lhs_kind, string rhs_kind, 7657 RegisterOperand RegType, 7658 ValueType AccumType, ValueType InputType, 7659 SDPatternOperator OpNode> : 7660 BaseSIMDIndexedTied<Q, U, 0b0, 0b10, 0b1110, RegType, RegType, V128, 7661 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 7662 [(set (AccumType RegType:$dst), 7663 (AccumType (OpNode (AccumType RegType:$Rd), 7664 (InputType RegType:$Rn), 7665 (InputType (bitconvert (AccumType 7666 (AArch64duplane32 (v4i32 V128:$Rm), 7667 VectorIndexS:$idx)))))))]> { 7668 bits<2> idx; 7669 let Inst{21} = idx{0}; // L 7670 let Inst{11} = idx{1}; // H 7671} 7672 7673multiclass SIMDThreeSameVectorDotIndex<bit U, string asm, 7674 SDPatternOperator OpNode> { 7675 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, asm, ".2s", ".8b", ".4b", 7676 V64, v2i32, v8i8, OpNode>; 7677 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, asm, ".4s", ".16b", ".4b", 7678 V128, v4i32, v16i8, OpNode>; 7679} 7680 7681// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 7682class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 7683 string dst_kind, string lhs_kind, 7684 string rhs_kind, RegisterOperand RegType, 7685 ValueType AccumType, ValueType InputType, 7686 SDPatternOperator OpNode> : 7687 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 7688 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 7689 [(set (AccumType RegType:$dst), 7690 (AccumType (OpNode (AccumType RegType:$Rd), 7691 (InputType RegType:$Rn), 7692 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 7693 VectorIndexH:$idx)))))]> { 7694 // idx = H:L:M 7695 bits<3> idx; 7696 let Inst{11} = idx{2}; // H 7697 let Inst{21} = idx{1}; // L 7698 let Inst{20} = idx{0}; // M 7699} 7700 7701multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 7702 SDPatternOperator OpNode> { 7703 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 7704 V64, v2f32, v4f16, OpNode>; 7705 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 7706 V128, v4f32, v8f16, OpNode>; 7707} 7708 7709multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 7710 SDPatternOperator OpNode> { 7711 let Predicates = [HasNEON, HasFullFP16] in { 7712 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 7713 V64, V64, 7714 V128_lo, VectorIndexH, 7715 asm, ".4h", ".4h", ".4h", ".h", 7716 [(set (v4f16 V64:$Rd), 7717 (OpNode (v4f16 V64:$Rn), 7718 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7719 bits<3> idx; 7720 let Inst{11} = idx{2}; 7721 let Inst{21} = idx{1}; 7722 let Inst{20} = idx{0}; 7723 } 7724 7725 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 7726 V128, V128, 7727 V128_lo, VectorIndexH, 7728 asm, ".8h", ".8h", ".8h", ".h", 7729 [(set (v8f16 V128:$Rd), 7730 (OpNode (v8f16 V128:$Rn), 7731 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7732 bits<3> idx; 7733 let Inst{11} = idx{2}; 7734 let Inst{21} = idx{1}; 7735 let Inst{20} = idx{0}; 7736 } 7737 } // Predicates = [HasNEON, HasFullFP16] 7738 7739 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7740 V64, V64, 7741 V128, VectorIndexS, 7742 asm, ".2s", ".2s", ".2s", ".s", 7743 [(set (v2f32 V64:$Rd), 7744 (OpNode (v2f32 V64:$Rn), 7745 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 7746 bits<2> idx; 7747 let Inst{11} = idx{1}; 7748 let Inst{21} = idx{0}; 7749 } 7750 7751 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7752 V128, V128, 7753 V128, VectorIndexS, 7754 asm, ".4s", ".4s", ".4s", ".s", 7755 [(set (v4f32 V128:$Rd), 7756 (OpNode (v4f32 V128:$Rn), 7757 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 7758 bits<2> idx; 7759 let Inst{11} = idx{1}; 7760 let Inst{21} = idx{0}; 7761 } 7762 7763 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 7764 V128, V128, 7765 V128, VectorIndexD, 7766 asm, ".2d", ".2d", ".2d", ".d", 7767 [(set (v2f64 V128:$Rd), 7768 (OpNode (v2f64 V128:$Rn), 7769 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 7770 bits<1> idx; 7771 let Inst{11} = idx{0}; 7772 let Inst{21} = 0; 7773 } 7774 7775 let Predicates = [HasNEON, HasFullFP16] in { 7776 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 7777 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7778 asm, ".h", "", "", ".h", 7779 [(set (f16 FPR16Op:$Rd), 7780 (OpNode (f16 FPR16Op:$Rn), 7781 (f16 (vector_extract (v8f16 V128_lo:$Rm), 7782 VectorIndexH:$idx))))]> { 7783 bits<3> idx; 7784 let Inst{11} = idx{2}; 7785 let Inst{21} = idx{1}; 7786 let Inst{20} = idx{0}; 7787 } 7788 } // Predicates = [HasNEON, HasFullFP16] 7789 7790 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 7791 FPR32Op, FPR32Op, V128, VectorIndexS, 7792 asm, ".s", "", "", ".s", 7793 [(set (f32 FPR32Op:$Rd), 7794 (OpNode (f32 FPR32Op:$Rn), 7795 (f32 (vector_extract (v4f32 V128:$Rm), 7796 VectorIndexS:$idx))))]> { 7797 bits<2> idx; 7798 let Inst{11} = idx{1}; 7799 let Inst{21} = idx{0}; 7800 } 7801 7802 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 7803 FPR64Op, FPR64Op, V128, VectorIndexD, 7804 asm, ".d", "", "", ".d", 7805 [(set (f64 FPR64Op:$Rd), 7806 (OpNode (f64 FPR64Op:$Rn), 7807 (f64 (vector_extract (v2f64 V128:$Rm), 7808 VectorIndexD:$idx))))]> { 7809 bits<1> idx; 7810 let Inst{11} = idx{0}; 7811 let Inst{21} = 0; 7812 } 7813} 7814 7815multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 7816 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 7817 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 7818 (AArch64duplane32 (v4f32 V128:$Rm), 7819 VectorIndexS:$idx))), 7820 (!cast<Instruction>(INST # v2i32_indexed) 7821 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 7822 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 7823 (AArch64dup (f32 FPR32Op:$Rm)))), 7824 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 7825 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 7826 7827 7828 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 7829 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 7830 (AArch64duplane32 (v4f32 V128:$Rm), 7831 VectorIndexS:$idx))), 7832 (!cast<Instruction>(INST # "v4i32_indexed") 7833 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 7834 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 7835 (AArch64dup (f32 FPR32Op:$Rm)))), 7836 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 7837 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 7838 7839 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 7840 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 7841 (AArch64duplane64 (v2f64 V128:$Rm), 7842 VectorIndexD:$idx))), 7843 (!cast<Instruction>(INST # "v2i64_indexed") 7844 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 7845 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 7846 (AArch64dup (f64 FPR64Op:$Rm)))), 7847 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 7848 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 7849 7850 // 2 variants for 32-bit scalar version: extract from .2s or from .4s 7851 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 7852 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 7853 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 7854 V128:$Rm, VectorIndexS:$idx)>; 7855 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 7856 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))), 7857 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 7858 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>; 7859 7860 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 7861 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 7862 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 7863 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 7864 V128:$Rm, VectorIndexD:$idx)>; 7865} 7866 7867multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 7868 let Predicates = [HasNEON, HasFullFP16] in { 7869 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 7870 V128_lo, VectorIndexH, 7871 asm, ".4h", ".4h", ".4h", ".h", []> { 7872 bits<3> idx; 7873 let Inst{11} = idx{2}; 7874 let Inst{21} = idx{1}; 7875 let Inst{20} = idx{0}; 7876 } 7877 7878 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 7879 V128, V128, 7880 V128_lo, VectorIndexH, 7881 asm, ".8h", ".8h", ".8h", ".h", []> { 7882 bits<3> idx; 7883 let Inst{11} = idx{2}; 7884 let Inst{21} = idx{1}; 7885 let Inst{20} = idx{0}; 7886 } 7887 } // Predicates = [HasNEON, HasFullFP16] 7888 7889 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 7890 V128, VectorIndexS, 7891 asm, ".2s", ".2s", ".2s", ".s", []> { 7892 bits<2> idx; 7893 let Inst{11} = idx{1}; 7894 let Inst{21} = idx{0}; 7895 } 7896 7897 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7898 V128, V128, 7899 V128, VectorIndexS, 7900 asm, ".4s", ".4s", ".4s", ".s", []> { 7901 bits<2> idx; 7902 let Inst{11} = idx{1}; 7903 let Inst{21} = idx{0}; 7904 } 7905 7906 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 7907 V128, V128, 7908 V128, VectorIndexD, 7909 asm, ".2d", ".2d", ".2d", ".d", []> { 7910 bits<1> idx; 7911 let Inst{11} = idx{0}; 7912 let Inst{21} = 0; 7913 } 7914 7915 let Predicates = [HasNEON, HasFullFP16] in { 7916 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 7917 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7918 asm, ".h", "", "", ".h", []> { 7919 bits<3> idx; 7920 let Inst{11} = idx{2}; 7921 let Inst{21} = idx{1}; 7922 let Inst{20} = idx{0}; 7923 } 7924 } // Predicates = [HasNEON, HasFullFP16] 7925 7926 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 7927 FPR32Op, FPR32Op, V128, VectorIndexS, 7928 asm, ".s", "", "", ".s", []> { 7929 bits<2> idx; 7930 let Inst{11} = idx{1}; 7931 let Inst{21} = idx{0}; 7932 } 7933 7934 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 7935 FPR64Op, FPR64Op, V128, VectorIndexD, 7936 asm, ".d", "", "", ".d", []> { 7937 bits<1> idx; 7938 let Inst{11} = idx{0}; 7939 let Inst{21} = 0; 7940 } 7941} 7942 7943multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 7944 SDPatternOperator OpNode> { 7945 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 7946 V128_lo, VectorIndexH, 7947 asm, ".4h", ".4h", ".4h", ".h", 7948 [(set (v4i16 V64:$Rd), 7949 (OpNode (v4i16 V64:$Rn), 7950 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7951 bits<3> idx; 7952 let Inst{11} = idx{2}; 7953 let Inst{21} = idx{1}; 7954 let Inst{20} = idx{0}; 7955 } 7956 7957 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7958 V128, V128, 7959 V128_lo, VectorIndexH, 7960 asm, ".8h", ".8h", ".8h", ".h", 7961 [(set (v8i16 V128:$Rd), 7962 (OpNode (v8i16 V128:$Rn), 7963 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7964 bits<3> idx; 7965 let Inst{11} = idx{2}; 7966 let Inst{21} = idx{1}; 7967 let Inst{20} = idx{0}; 7968 } 7969 7970 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7971 V64, V64, 7972 V128, VectorIndexS, 7973 asm, ".2s", ".2s", ".2s", ".s", 7974 [(set (v2i32 V64:$Rd), 7975 (OpNode (v2i32 V64:$Rn), 7976 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7977 bits<2> idx; 7978 let Inst{11} = idx{1}; 7979 let Inst{21} = idx{0}; 7980 } 7981 7982 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7983 V128, V128, 7984 V128, VectorIndexS, 7985 asm, ".4s", ".4s", ".4s", ".s", 7986 [(set (v4i32 V128:$Rd), 7987 (OpNode (v4i32 V128:$Rn), 7988 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7989 bits<2> idx; 7990 let Inst{11} = idx{1}; 7991 let Inst{21} = idx{0}; 7992 } 7993 7994 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 7995 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7996 asm, ".h", "", "", ".h", []> { 7997 bits<3> idx; 7998 let Inst{11} = idx{2}; 7999 let Inst{21} = idx{1}; 8000 let Inst{20} = idx{0}; 8001 } 8002 8003 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8004 FPR32Op, FPR32Op, V128, VectorIndexS, 8005 asm, ".s", "", "", ".s", 8006 [(set (i32 FPR32Op:$Rd), 8007 (OpNode FPR32Op:$Rn, 8008 (i32 (vector_extract (v4i32 V128:$Rm), 8009 VectorIndexS:$idx))))]> { 8010 bits<2> idx; 8011 let Inst{11} = idx{1}; 8012 let Inst{21} = idx{0}; 8013 } 8014} 8015 8016multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8017 SDPatternOperator OpNode> { 8018 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8019 V64, V64, 8020 V128_lo, VectorIndexH, 8021 asm, ".4h", ".4h", ".4h", ".h", 8022 [(set (v4i16 V64:$Rd), 8023 (OpNode (v4i16 V64:$Rn), 8024 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8025 bits<3> idx; 8026 let Inst{11} = idx{2}; 8027 let Inst{21} = idx{1}; 8028 let Inst{20} = idx{0}; 8029 } 8030 8031 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8032 V128, V128, 8033 V128_lo, VectorIndexH, 8034 asm, ".8h", ".8h", ".8h", ".h", 8035 [(set (v8i16 V128:$Rd), 8036 (OpNode (v8i16 V128:$Rn), 8037 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8038 bits<3> idx; 8039 let Inst{11} = idx{2}; 8040 let Inst{21} = idx{1}; 8041 let Inst{20} = idx{0}; 8042 } 8043 8044 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8045 V64, V64, 8046 V128, VectorIndexS, 8047 asm, ".2s", ".2s", ".2s", ".s", 8048 [(set (v2i32 V64:$Rd), 8049 (OpNode (v2i32 V64:$Rn), 8050 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8051 bits<2> idx; 8052 let Inst{11} = idx{1}; 8053 let Inst{21} = idx{0}; 8054 } 8055 8056 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8057 V128, V128, 8058 V128, VectorIndexS, 8059 asm, ".4s", ".4s", ".4s", ".s", 8060 [(set (v4i32 V128:$Rd), 8061 (OpNode (v4i32 V128:$Rn), 8062 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8063 bits<2> idx; 8064 let Inst{11} = idx{1}; 8065 let Inst{21} = idx{0}; 8066 } 8067} 8068 8069multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8070 SDPatternOperator OpNode> { 8071 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8072 V128_lo, VectorIndexH, 8073 asm, ".4h", ".4h", ".4h", ".h", 8074 [(set (v4i16 V64:$dst), 8075 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8076 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8077 bits<3> idx; 8078 let Inst{11} = idx{2}; 8079 let Inst{21} = idx{1}; 8080 let Inst{20} = idx{0}; 8081 } 8082 8083 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8084 V128, V128, 8085 V128_lo, VectorIndexH, 8086 asm, ".8h", ".8h", ".8h", ".h", 8087 [(set (v8i16 V128:$dst), 8088 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8089 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8090 bits<3> idx; 8091 let Inst{11} = idx{2}; 8092 let Inst{21} = idx{1}; 8093 let Inst{20} = idx{0}; 8094 } 8095 8096 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8097 V64, V64, 8098 V128, VectorIndexS, 8099 asm, ".2s", ".2s", ".2s", ".s", 8100 [(set (v2i32 V64:$dst), 8101 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8102 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8103 bits<2> idx; 8104 let Inst{11} = idx{1}; 8105 let Inst{21} = idx{0}; 8106 } 8107 8108 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8109 V128, V128, 8110 V128, VectorIndexS, 8111 asm, ".4s", ".4s", ".4s", ".s", 8112 [(set (v4i32 V128:$dst), 8113 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8114 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8115 bits<2> idx; 8116 let Inst{11} = idx{1}; 8117 let Inst{21} = idx{0}; 8118 } 8119} 8120 8121multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8122 SDPatternOperator OpNode> { 8123 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8124 V128, V64, 8125 V128_lo, VectorIndexH, 8126 asm, ".4s", ".4s", ".4h", ".h", 8127 [(set (v4i32 V128:$Rd), 8128 (OpNode (v4i16 V64:$Rn), 8129 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8130 bits<3> idx; 8131 let Inst{11} = idx{2}; 8132 let Inst{21} = idx{1}; 8133 let Inst{20} = idx{0}; 8134 } 8135 8136 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8137 V128, V128, 8138 V128_lo, VectorIndexH, 8139 asm#"2", ".4s", ".4s", ".8h", ".h", 8140 [(set (v4i32 V128:$Rd), 8141 (OpNode (extract_high_v8i16 V128:$Rn), 8142 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8143 VectorIndexH:$idx))))]> { 8144 8145 bits<3> idx; 8146 let Inst{11} = idx{2}; 8147 let Inst{21} = idx{1}; 8148 let Inst{20} = idx{0}; 8149 } 8150 8151 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8152 V128, V64, 8153 V128, VectorIndexS, 8154 asm, ".2d", ".2d", ".2s", ".s", 8155 [(set (v2i64 V128:$Rd), 8156 (OpNode (v2i32 V64:$Rn), 8157 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8158 bits<2> idx; 8159 let Inst{11} = idx{1}; 8160 let Inst{21} = idx{0}; 8161 } 8162 8163 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8164 V128, V128, 8165 V128, VectorIndexS, 8166 asm#"2", ".2d", ".2d", ".4s", ".s", 8167 [(set (v2i64 V128:$Rd), 8168 (OpNode (extract_high_v4i32 V128:$Rn), 8169 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8170 VectorIndexS:$idx))))]> { 8171 bits<2> idx; 8172 let Inst{11} = idx{1}; 8173 let Inst{21} = idx{0}; 8174 } 8175 8176 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8177 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8178 asm, ".h", "", "", ".h", []> { 8179 bits<3> idx; 8180 let Inst{11} = idx{2}; 8181 let Inst{21} = idx{1}; 8182 let Inst{20} = idx{0}; 8183 } 8184 8185 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8186 FPR64Op, FPR32Op, V128, VectorIndexS, 8187 asm, ".s", "", "", ".s", []> { 8188 bits<2> idx; 8189 let Inst{11} = idx{1}; 8190 let Inst{21} = idx{0}; 8191 } 8192} 8193 8194multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8195 SDPatternOperator Accum> { 8196 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8197 V128, V64, 8198 V128_lo, VectorIndexH, 8199 asm, ".4s", ".4s", ".4h", ".h", 8200 [(set (v4i32 V128:$dst), 8201 (Accum (v4i32 V128:$Rd), 8202 (v4i32 (int_aarch64_neon_sqdmull 8203 (v4i16 V64:$Rn), 8204 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8205 VectorIndexH:$idx))))))]> { 8206 bits<3> idx; 8207 let Inst{11} = idx{2}; 8208 let Inst{21} = idx{1}; 8209 let Inst{20} = idx{0}; 8210 } 8211 8212 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8213 // intermediate EXTRACT_SUBREG would be untyped. 8214 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8215 (i32 (vector_extract (v4i32 8216 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8217 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8218 VectorIndexH:$idx)))), 8219 (i64 0))))), 8220 (EXTRACT_SUBREG 8221 (!cast<Instruction>(NAME # v4i16_indexed) 8222 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8223 V128_lo:$Rm, VectorIndexH:$idx), 8224 ssub)>; 8225 8226 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8227 V128, V128, 8228 V128_lo, VectorIndexH, 8229 asm#"2", ".4s", ".4s", ".8h", ".h", 8230 [(set (v4i32 V128:$dst), 8231 (Accum (v4i32 V128:$Rd), 8232 (v4i32 (int_aarch64_neon_sqdmull 8233 (extract_high_v8i16 V128:$Rn), 8234 (extract_high_v8i16 8235 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8236 VectorIndexH:$idx))))))]> { 8237 bits<3> idx; 8238 let Inst{11} = idx{2}; 8239 let Inst{21} = idx{1}; 8240 let Inst{20} = idx{0}; 8241 } 8242 8243 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8244 V128, V64, 8245 V128, VectorIndexS, 8246 asm, ".2d", ".2d", ".2s", ".s", 8247 [(set (v2i64 V128:$dst), 8248 (Accum (v2i64 V128:$Rd), 8249 (v2i64 (int_aarch64_neon_sqdmull 8250 (v2i32 V64:$Rn), 8251 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8252 VectorIndexS:$idx))))))]> { 8253 bits<2> idx; 8254 let Inst{11} = idx{1}; 8255 let Inst{21} = idx{0}; 8256 } 8257 8258 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8259 V128, V128, 8260 V128, VectorIndexS, 8261 asm#"2", ".2d", ".2d", ".4s", ".s", 8262 [(set (v2i64 V128:$dst), 8263 (Accum (v2i64 V128:$Rd), 8264 (v2i64 (int_aarch64_neon_sqdmull 8265 (extract_high_v4i32 V128:$Rn), 8266 (extract_high_v4i32 8267 (AArch64duplane32 (v4i32 V128:$Rm), 8268 VectorIndexS:$idx))))))]> { 8269 bits<2> idx; 8270 let Inst{11} = idx{1}; 8271 let Inst{21} = idx{0}; 8272 } 8273 8274 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8275 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8276 asm, ".h", "", "", ".h", []> { 8277 bits<3> idx; 8278 let Inst{11} = idx{2}; 8279 let Inst{21} = idx{1}; 8280 let Inst{20} = idx{0}; 8281 } 8282 8283 8284 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8285 FPR64Op, FPR32Op, V128, VectorIndexS, 8286 asm, ".s", "", "", ".s", 8287 [(set (i64 FPR64Op:$dst), 8288 (Accum (i64 FPR64Op:$Rd), 8289 (i64 (int_aarch64_neon_sqdmulls_scalar 8290 (i32 FPR32Op:$Rn), 8291 (i32 (vector_extract (v4i32 V128:$Rm), 8292 VectorIndexS:$idx))))))]> { 8293 8294 bits<2> idx; 8295 let Inst{11} = idx{1}; 8296 let Inst{21} = idx{0}; 8297 } 8298} 8299 8300multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8301 SDPatternOperator OpNode> { 8302 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8303 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8304 V128, V64, 8305 V128_lo, VectorIndexH, 8306 asm, ".4s", ".4s", ".4h", ".h", 8307 [(set (v4i32 V128:$Rd), 8308 (OpNode (v4i16 V64:$Rn), 8309 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8310 bits<3> idx; 8311 let Inst{11} = idx{2}; 8312 let Inst{21} = idx{1}; 8313 let Inst{20} = idx{0}; 8314 } 8315 8316 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8317 V128, V128, 8318 V128_lo, VectorIndexH, 8319 asm#"2", ".4s", ".4s", ".8h", ".h", 8320 [(set (v4i32 V128:$Rd), 8321 (OpNode (extract_high_v8i16 V128:$Rn), 8322 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8323 VectorIndexH:$idx))))]> { 8324 8325 bits<3> idx; 8326 let Inst{11} = idx{2}; 8327 let Inst{21} = idx{1}; 8328 let Inst{20} = idx{0}; 8329 } 8330 8331 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8332 V128, V64, 8333 V128, VectorIndexS, 8334 asm, ".2d", ".2d", ".2s", ".s", 8335 [(set (v2i64 V128:$Rd), 8336 (OpNode (v2i32 V64:$Rn), 8337 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8338 bits<2> idx; 8339 let Inst{11} = idx{1}; 8340 let Inst{21} = idx{0}; 8341 } 8342 8343 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8344 V128, V128, 8345 V128, VectorIndexS, 8346 asm#"2", ".2d", ".2d", ".4s", ".s", 8347 [(set (v2i64 V128:$Rd), 8348 (OpNode (extract_high_v4i32 V128:$Rn), 8349 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8350 VectorIndexS:$idx))))]> { 8351 bits<2> idx; 8352 let Inst{11} = idx{1}; 8353 let Inst{21} = idx{0}; 8354 } 8355 } 8356} 8357 8358multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8359 SDPatternOperator OpNode> { 8360 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8361 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8362 V128, V64, 8363 V128_lo, VectorIndexH, 8364 asm, ".4s", ".4s", ".4h", ".h", 8365 [(set (v4i32 V128:$dst), 8366 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8367 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8368 bits<3> idx; 8369 let Inst{11} = idx{2}; 8370 let Inst{21} = idx{1}; 8371 let Inst{20} = idx{0}; 8372 } 8373 8374 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8375 V128, V128, 8376 V128_lo, VectorIndexH, 8377 asm#"2", ".4s", ".4s", ".8h", ".h", 8378 [(set (v4i32 V128:$dst), 8379 (OpNode (v4i32 V128:$Rd), 8380 (extract_high_v8i16 V128:$Rn), 8381 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8382 VectorIndexH:$idx))))]> { 8383 bits<3> idx; 8384 let Inst{11} = idx{2}; 8385 let Inst{21} = idx{1}; 8386 let Inst{20} = idx{0}; 8387 } 8388 8389 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8390 V128, V64, 8391 V128, VectorIndexS, 8392 asm, ".2d", ".2d", ".2s", ".s", 8393 [(set (v2i64 V128:$dst), 8394 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8395 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8396 bits<2> idx; 8397 let Inst{11} = idx{1}; 8398 let Inst{21} = idx{0}; 8399 } 8400 8401 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8402 V128, V128, 8403 V128, VectorIndexS, 8404 asm#"2", ".2d", ".2d", ".4s", ".s", 8405 [(set (v2i64 V128:$dst), 8406 (OpNode (v2i64 V128:$Rd), 8407 (extract_high_v4i32 V128:$Rn), 8408 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8409 VectorIndexS:$idx))))]> { 8410 bits<2> idx; 8411 let Inst{11} = idx{1}; 8412 let Inst{21} = idx{0}; 8413 } 8414 } 8415} 8416 8417//---------------------------------------------------------------------------- 8418// AdvSIMD scalar shift by immediate 8419//---------------------------------------------------------------------------- 8420 8421let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8422class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8423 RegisterClass regtype1, RegisterClass regtype2, 8424 Operand immtype, string asm, list<dag> pattern> 8425 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8426 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8427 Sched<[WriteV]> { 8428 bits<5> Rd; 8429 bits<5> Rn; 8430 bits<7> imm; 8431 let Inst{31-30} = 0b01; 8432 let Inst{29} = U; 8433 let Inst{28-23} = 0b111110; 8434 let Inst{22-16} = fixed_imm; 8435 let Inst{15-11} = opc; 8436 let Inst{10} = 1; 8437 let Inst{9-5} = Rn; 8438 let Inst{4-0} = Rd; 8439} 8440 8441let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8442class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 8443 RegisterClass regtype1, RegisterClass regtype2, 8444 Operand immtype, string asm, list<dag> pattern> 8445 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 8446 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 8447 Sched<[WriteV]> { 8448 bits<5> Rd; 8449 bits<5> Rn; 8450 bits<7> imm; 8451 let Inst{31-30} = 0b01; 8452 let Inst{29} = U; 8453 let Inst{28-23} = 0b111110; 8454 let Inst{22-16} = fixed_imm; 8455 let Inst{15-11} = opc; 8456 let Inst{10} = 1; 8457 let Inst{9-5} = Rn; 8458 let Inst{4-0} = Rd; 8459} 8460 8461 8462multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 8463 let Predicates = [HasNEON, HasFullFP16] in { 8464 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8465 FPR16, FPR16, vecshiftR16, asm, []> { 8466 let Inst{19-16} = imm{3-0}; 8467 } 8468 } // Predicates = [HasNEON, HasFullFP16] 8469 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8470 FPR32, FPR32, vecshiftR32, asm, []> { 8471 let Inst{20-16} = imm{4-0}; 8472 } 8473 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8474 FPR64, FPR64, vecshiftR64, asm, []> { 8475 let Inst{21-16} = imm{5-0}; 8476 } 8477} 8478 8479multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 8480 SDPatternOperator OpNode> { 8481 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8482 FPR64, FPR64, vecshiftR64, asm, 8483 [(set (i64 FPR64:$Rd), 8484 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 8485 let Inst{21-16} = imm{5-0}; 8486 } 8487 8488 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 8489 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 8490} 8491 8492multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 8493 SDPatternOperator OpNode = null_frag> { 8494 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8495 FPR64, FPR64, vecshiftR64, asm, 8496 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 8497 (i32 vecshiftR64:$imm)))]> { 8498 let Inst{21-16} = imm{5-0}; 8499 } 8500 8501 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 8502 (i32 vecshiftR64:$imm))), 8503 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 8504 vecshiftR64:$imm)>; 8505} 8506 8507multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 8508 SDPatternOperator OpNode> { 8509 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8510 FPR64, FPR64, vecshiftL64, asm, 8511 [(set (v1i64 FPR64:$Rd), 8512 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8513 let Inst{21-16} = imm{5-0}; 8514 } 8515} 8516 8517let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8518multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 8519 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8520 FPR64, FPR64, vecshiftL64, asm, []> { 8521 let Inst{21-16} = imm{5-0}; 8522 } 8523} 8524 8525let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8526multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 8527 SDPatternOperator OpNode = null_frag> { 8528 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8529 FPR8, FPR16, vecshiftR8, asm, []> { 8530 let Inst{18-16} = imm{2-0}; 8531 } 8532 8533 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8534 FPR16, FPR32, vecshiftR16, asm, []> { 8535 let Inst{19-16} = imm{3-0}; 8536 } 8537 8538 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8539 FPR32, FPR64, vecshiftR32, asm, 8540 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 8541 let Inst{20-16} = imm{4-0}; 8542 } 8543} 8544 8545multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 8546 SDPatternOperator OpNode> { 8547 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8548 FPR8, FPR8, vecshiftL8, asm, []> { 8549 let Inst{18-16} = imm{2-0}; 8550 } 8551 8552 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8553 FPR16, FPR16, vecshiftL16, asm, []> { 8554 let Inst{19-16} = imm{3-0}; 8555 } 8556 8557 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8558 FPR32, FPR32, vecshiftL32, asm, 8559 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 8560 let Inst{20-16} = imm{4-0}; 8561 } 8562 8563 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8564 FPR64, FPR64, vecshiftL64, asm, 8565 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8566 let Inst{21-16} = imm{5-0}; 8567 } 8568 8569 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 8570 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 8571} 8572 8573multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 8574 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8575 FPR8, FPR8, vecshiftR8, asm, []> { 8576 let Inst{18-16} = imm{2-0}; 8577 } 8578 8579 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8580 FPR16, FPR16, vecshiftR16, asm, []> { 8581 let Inst{19-16} = imm{3-0}; 8582 } 8583 8584 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8585 FPR32, FPR32, vecshiftR32, asm, []> { 8586 let Inst{20-16} = imm{4-0}; 8587 } 8588 8589 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8590 FPR64, FPR64, vecshiftR64, asm, []> { 8591 let Inst{21-16} = imm{5-0}; 8592 } 8593} 8594 8595//---------------------------------------------------------------------------- 8596// AdvSIMD vector x indexed element 8597//---------------------------------------------------------------------------- 8598 8599let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8600class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 8601 RegisterOperand dst_reg, RegisterOperand src_reg, 8602 Operand immtype, 8603 string asm, string dst_kind, string src_kind, 8604 list<dag> pattern> 8605 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 8606 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 8607 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 8608 Sched<[WriteV]> { 8609 bits<5> Rd; 8610 bits<5> Rn; 8611 let Inst{31} = 0; 8612 let Inst{30} = Q; 8613 let Inst{29} = U; 8614 let Inst{28-23} = 0b011110; 8615 let Inst{22-16} = fixed_imm; 8616 let Inst{15-11} = opc; 8617 let Inst{10} = 1; 8618 let Inst{9-5} = Rn; 8619 let Inst{4-0} = Rd; 8620} 8621 8622let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8623class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 8624 RegisterOperand vectype1, RegisterOperand vectype2, 8625 Operand immtype, 8626 string asm, string dst_kind, string src_kind, 8627 list<dag> pattern> 8628 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 8629 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 8630 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 8631 Sched<[WriteV]> { 8632 bits<5> Rd; 8633 bits<5> Rn; 8634 let Inst{31} = 0; 8635 let Inst{30} = Q; 8636 let Inst{29} = U; 8637 let Inst{28-23} = 0b011110; 8638 let Inst{22-16} = fixed_imm; 8639 let Inst{15-11} = opc; 8640 let Inst{10} = 1; 8641 let Inst{9-5} = Rn; 8642 let Inst{4-0} = Rd; 8643} 8644 8645multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 8646 Intrinsic OpNode> { 8647 let Predicates = [HasNEON, HasFullFP16] in { 8648 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8649 V64, V64, vecshiftR16, 8650 asm, ".4h", ".4h", 8651 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 8652 bits<4> imm; 8653 let Inst{19-16} = imm; 8654 } 8655 8656 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8657 V128, V128, vecshiftR16, 8658 asm, ".8h", ".8h", 8659 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 8660 bits<4> imm; 8661 let Inst{19-16} = imm; 8662 } 8663 } // Predicates = [HasNEON, HasFullFP16] 8664 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8665 V64, V64, vecshiftR32, 8666 asm, ".2s", ".2s", 8667 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 8668 bits<5> imm; 8669 let Inst{20-16} = imm; 8670 } 8671 8672 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8673 V128, V128, vecshiftR32, 8674 asm, ".4s", ".4s", 8675 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 8676 bits<5> imm; 8677 let Inst{20-16} = imm; 8678 } 8679 8680 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8681 V128, V128, vecshiftR64, 8682 asm, ".2d", ".2d", 8683 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 8684 bits<6> imm; 8685 let Inst{21-16} = imm; 8686 } 8687} 8688 8689multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 8690 Intrinsic OpNode> { 8691 let Predicates = [HasNEON, HasFullFP16] in { 8692 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8693 V64, V64, vecshiftR16, 8694 asm, ".4h", ".4h", 8695 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 8696 bits<4> imm; 8697 let Inst{19-16} = imm; 8698 } 8699 8700 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8701 V128, V128, vecshiftR16, 8702 asm, ".8h", ".8h", 8703 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 8704 bits<4> imm; 8705 let Inst{19-16} = imm; 8706 } 8707 } // Predicates = [HasNEON, HasFullFP16] 8708 8709 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8710 V64, V64, vecshiftR32, 8711 asm, ".2s", ".2s", 8712 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 8713 bits<5> imm; 8714 let Inst{20-16} = imm; 8715 } 8716 8717 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8718 V128, V128, vecshiftR32, 8719 asm, ".4s", ".4s", 8720 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 8721 bits<5> imm; 8722 let Inst{20-16} = imm; 8723 } 8724 8725 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8726 V128, V128, vecshiftR64, 8727 asm, ".2d", ".2d", 8728 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 8729 bits<6> imm; 8730 let Inst{21-16} = imm; 8731 } 8732} 8733 8734multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 8735 SDPatternOperator OpNode> { 8736 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8737 V64, V128, vecshiftR16Narrow, 8738 asm, ".8b", ".8h", 8739 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 8740 bits<3> imm; 8741 let Inst{18-16} = imm; 8742 } 8743 8744 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8745 V128, V128, vecshiftR16Narrow, 8746 asm#"2", ".16b", ".8h", []> { 8747 bits<3> imm; 8748 let Inst{18-16} = imm; 8749 let hasSideEffects = 0; 8750 } 8751 8752 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8753 V64, V128, vecshiftR32Narrow, 8754 asm, ".4h", ".4s", 8755 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 8756 bits<4> imm; 8757 let Inst{19-16} = imm; 8758 } 8759 8760 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8761 V128, V128, vecshiftR32Narrow, 8762 asm#"2", ".8h", ".4s", []> { 8763 bits<4> imm; 8764 let Inst{19-16} = imm; 8765 let hasSideEffects = 0; 8766 } 8767 8768 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8769 V64, V128, vecshiftR64Narrow, 8770 asm, ".2s", ".2d", 8771 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 8772 bits<5> imm; 8773 let Inst{20-16} = imm; 8774 } 8775 8776 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8777 V128, V128, vecshiftR64Narrow, 8778 asm#"2", ".4s", ".2d", []> { 8779 bits<5> imm; 8780 let Inst{20-16} = imm; 8781 let hasSideEffects = 0; 8782 } 8783 8784 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 8785 // themselves, so put them here instead. 8786 8787 // Patterns involving what's effectively an insert high and a normal 8788 // intrinsic, represented by CONCAT_VECTORS. 8789 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 8790 vecshiftR16Narrow:$imm)), 8791 (!cast<Instruction>(NAME # "v16i8_shift") 8792 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 8793 V128:$Rn, vecshiftR16Narrow:$imm)>; 8794 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 8795 vecshiftR32Narrow:$imm)), 8796 (!cast<Instruction>(NAME # "v8i16_shift") 8797 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 8798 V128:$Rn, vecshiftR32Narrow:$imm)>; 8799 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 8800 vecshiftR64Narrow:$imm)), 8801 (!cast<Instruction>(NAME # "v4i32_shift") 8802 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 8803 V128:$Rn, vecshiftR64Narrow:$imm)>; 8804} 8805 8806multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 8807 SDPatternOperator OpNode> { 8808 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8809 V64, V64, vecshiftL8, 8810 asm, ".8b", ".8b", 8811 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 8812 (i32 vecshiftL8:$imm)))]> { 8813 bits<3> imm; 8814 let Inst{18-16} = imm; 8815 } 8816 8817 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 8818 V128, V128, vecshiftL8, 8819 asm, ".16b", ".16b", 8820 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 8821 (i32 vecshiftL8:$imm)))]> { 8822 bits<3> imm; 8823 let Inst{18-16} = imm; 8824 } 8825 8826 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8827 V64, V64, vecshiftL16, 8828 asm, ".4h", ".4h", 8829 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 8830 (i32 vecshiftL16:$imm)))]> { 8831 bits<4> imm; 8832 let Inst{19-16} = imm; 8833 } 8834 8835 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8836 V128, V128, vecshiftL16, 8837 asm, ".8h", ".8h", 8838 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 8839 (i32 vecshiftL16:$imm)))]> { 8840 bits<4> imm; 8841 let Inst{19-16} = imm; 8842 } 8843 8844 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8845 V64, V64, vecshiftL32, 8846 asm, ".2s", ".2s", 8847 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 8848 (i32 vecshiftL32:$imm)))]> { 8849 bits<5> imm; 8850 let Inst{20-16} = imm; 8851 } 8852 8853 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8854 V128, V128, vecshiftL32, 8855 asm, ".4s", ".4s", 8856 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 8857 (i32 vecshiftL32:$imm)))]> { 8858 bits<5> imm; 8859 let Inst{20-16} = imm; 8860 } 8861 8862 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8863 V128, V128, vecshiftL64, 8864 asm, ".2d", ".2d", 8865 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 8866 (i32 vecshiftL64:$imm)))]> { 8867 bits<6> imm; 8868 let Inst{21-16} = imm; 8869 } 8870} 8871 8872multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 8873 SDPatternOperator OpNode> { 8874 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8875 V64, V64, vecshiftR8, 8876 asm, ".8b", ".8b", 8877 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 8878 (i32 vecshiftR8:$imm)))]> { 8879 bits<3> imm; 8880 let Inst{18-16} = imm; 8881 } 8882 8883 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 8884 V128, V128, vecshiftR8, 8885 asm, ".16b", ".16b", 8886 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 8887 (i32 vecshiftR8:$imm)))]> { 8888 bits<3> imm; 8889 let Inst{18-16} = imm; 8890 } 8891 8892 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8893 V64, V64, vecshiftR16, 8894 asm, ".4h", ".4h", 8895 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 8896 (i32 vecshiftR16:$imm)))]> { 8897 bits<4> imm; 8898 let Inst{19-16} = imm; 8899 } 8900 8901 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8902 V128, V128, vecshiftR16, 8903 asm, ".8h", ".8h", 8904 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 8905 (i32 vecshiftR16:$imm)))]> { 8906 bits<4> imm; 8907 let Inst{19-16} = imm; 8908 } 8909 8910 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8911 V64, V64, vecshiftR32, 8912 asm, ".2s", ".2s", 8913 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 8914 (i32 vecshiftR32:$imm)))]> { 8915 bits<5> imm; 8916 let Inst{20-16} = imm; 8917 } 8918 8919 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8920 V128, V128, vecshiftR32, 8921 asm, ".4s", ".4s", 8922 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 8923 (i32 vecshiftR32:$imm)))]> { 8924 bits<5> imm; 8925 let Inst{20-16} = imm; 8926 } 8927 8928 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8929 V128, V128, vecshiftR64, 8930 asm, ".2d", ".2d", 8931 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 8932 (i32 vecshiftR64:$imm)))]> { 8933 bits<6> imm; 8934 let Inst{21-16} = imm; 8935 } 8936} 8937 8938let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8939multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 8940 SDPatternOperator OpNode = null_frag> { 8941 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 8942 V64, V64, vecshiftR8, asm, ".8b", ".8b", 8943 [(set (v8i8 V64:$dst), 8944 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 8945 (i32 vecshiftR8:$imm)))]> { 8946 bits<3> imm; 8947 let Inst{18-16} = imm; 8948 } 8949 8950 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8951 V128, V128, vecshiftR8, asm, ".16b", ".16b", 8952 [(set (v16i8 V128:$dst), 8953 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 8954 (i32 vecshiftR8:$imm)))]> { 8955 bits<3> imm; 8956 let Inst{18-16} = imm; 8957 } 8958 8959 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 8960 V64, V64, vecshiftR16, asm, ".4h", ".4h", 8961 [(set (v4i16 V64:$dst), 8962 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 8963 (i32 vecshiftR16:$imm)))]> { 8964 bits<4> imm; 8965 let Inst{19-16} = imm; 8966 } 8967 8968 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8969 V128, V128, vecshiftR16, asm, ".8h", ".8h", 8970 [(set (v8i16 V128:$dst), 8971 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8972 (i32 vecshiftR16:$imm)))]> { 8973 bits<4> imm; 8974 let Inst{19-16} = imm; 8975 } 8976 8977 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 8978 V64, V64, vecshiftR32, asm, ".2s", ".2s", 8979 [(set (v2i32 V64:$dst), 8980 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8981 (i32 vecshiftR32:$imm)))]> { 8982 bits<5> imm; 8983 let Inst{20-16} = imm; 8984 } 8985 8986 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8987 V128, V128, vecshiftR32, asm, ".4s", ".4s", 8988 [(set (v4i32 V128:$dst), 8989 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8990 (i32 vecshiftR32:$imm)))]> { 8991 bits<5> imm; 8992 let Inst{20-16} = imm; 8993 } 8994 8995 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 8996 V128, V128, vecshiftR64, 8997 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 8998 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 8999 (i32 vecshiftR64:$imm)))]> { 9000 bits<6> imm; 9001 let Inst{21-16} = imm; 9002 } 9003} 9004 9005multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9006 SDPatternOperator OpNode = null_frag> { 9007 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9008 V64, V64, vecshiftL8, 9009 asm, ".8b", ".8b", 9010 [(set (v8i8 V64:$dst), 9011 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9012 (i32 vecshiftL8:$imm)))]> { 9013 bits<3> imm; 9014 let Inst{18-16} = imm; 9015 } 9016 9017 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9018 V128, V128, vecshiftL8, 9019 asm, ".16b", ".16b", 9020 [(set (v16i8 V128:$dst), 9021 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9022 (i32 vecshiftL8:$imm)))]> { 9023 bits<3> imm; 9024 let Inst{18-16} = imm; 9025 } 9026 9027 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9028 V64, V64, vecshiftL16, 9029 asm, ".4h", ".4h", 9030 [(set (v4i16 V64:$dst), 9031 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9032 (i32 vecshiftL16:$imm)))]> { 9033 bits<4> imm; 9034 let Inst{19-16} = imm; 9035 } 9036 9037 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9038 V128, V128, vecshiftL16, 9039 asm, ".8h", ".8h", 9040 [(set (v8i16 V128:$dst), 9041 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9042 (i32 vecshiftL16:$imm)))]> { 9043 bits<4> imm; 9044 let Inst{19-16} = imm; 9045 } 9046 9047 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9048 V64, V64, vecshiftL32, 9049 asm, ".2s", ".2s", 9050 [(set (v2i32 V64:$dst), 9051 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9052 (i32 vecshiftL32:$imm)))]> { 9053 bits<5> imm; 9054 let Inst{20-16} = imm; 9055 } 9056 9057 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9058 V128, V128, vecshiftL32, 9059 asm, ".4s", ".4s", 9060 [(set (v4i32 V128:$dst), 9061 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9062 (i32 vecshiftL32:$imm)))]> { 9063 bits<5> imm; 9064 let Inst{20-16} = imm; 9065 } 9066 9067 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9068 V128, V128, vecshiftL64, 9069 asm, ".2d", ".2d", 9070 [(set (v2i64 V128:$dst), 9071 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9072 (i32 vecshiftL64:$imm)))]> { 9073 bits<6> imm; 9074 let Inst{21-16} = imm; 9075 } 9076} 9077 9078multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9079 SDPatternOperator OpNode> { 9080 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9081 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9082 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9083 bits<3> imm; 9084 let Inst{18-16} = imm; 9085 } 9086 9087 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9088 V128, V128, vecshiftL8, 9089 asm#"2", ".8h", ".16b", 9090 [(set (v8i16 V128:$Rd), 9091 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 9092 bits<3> imm; 9093 let Inst{18-16} = imm; 9094 } 9095 9096 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9097 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9098 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9099 bits<4> imm; 9100 let Inst{19-16} = imm; 9101 } 9102 9103 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9104 V128, V128, vecshiftL16, 9105 asm#"2", ".4s", ".8h", 9106 [(set (v4i32 V128:$Rd), 9107 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 9108 9109 bits<4> imm; 9110 let Inst{19-16} = imm; 9111 } 9112 9113 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9114 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9115 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9116 bits<5> imm; 9117 let Inst{20-16} = imm; 9118 } 9119 9120 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9121 V128, V128, vecshiftL32, 9122 asm#"2", ".2d", ".4s", 9123 [(set (v2i64 V128:$Rd), 9124 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9125 bits<5> imm; 9126 let Inst{20-16} = imm; 9127 } 9128} 9129 9130 9131//--- 9132// Vector load/store 9133//--- 9134// SIMD ldX/stX no-index memory references don't allow the optional 9135// ", #0" constant and handle post-indexing explicitly, so we use 9136// a more specialized parse method for them. Otherwise, it's the same as 9137// the general GPR64sp handling. 9138 9139class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9140 string asm, dag oops, dag iops, list<dag> pattern> 9141 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9142 bits<5> Vt; 9143 bits<5> Rn; 9144 let Inst{31} = 0; 9145 let Inst{30} = Q; 9146 let Inst{29-23} = 0b0011000; 9147 let Inst{22} = L; 9148 let Inst{21-16} = 0b000000; 9149 let Inst{15-12} = opcode; 9150 let Inst{11-10} = size; 9151 let Inst{9-5} = Rn; 9152 let Inst{4-0} = Vt; 9153} 9154 9155class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9156 string asm, dag oops, dag iops> 9157 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9158 bits<5> Vt; 9159 bits<5> Rn; 9160 bits<5> Xm; 9161 let Inst{31} = 0; 9162 let Inst{30} = Q; 9163 let Inst{29-23} = 0b0011001; 9164 let Inst{22} = L; 9165 let Inst{21} = 0; 9166 let Inst{20-16} = Xm; 9167 let Inst{15-12} = opcode; 9168 let Inst{11-10} = size; 9169 let Inst{9-5} = Rn; 9170 let Inst{4-0} = Vt; 9171} 9172 9173// The immediate form of AdvSIMD post-indexed addressing is encoded with 9174// register post-index addressing from the zero register. 9175multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9176 int Offset, int Size> { 9177 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9178 // "ld1\t$Vt, [$Rn], #16" 9179 // may get mapped to 9180 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9181 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9182 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9183 GPR64sp:$Rn, 9184 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9185 XZR), 1>; 9186 9187 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9188 // "ld1.8b\t$Vt, [$Rn], #16" 9189 // may get mapped to 9190 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9191 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9192 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9193 GPR64sp:$Rn, 9194 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9195 XZR), 0>; 9196 9197 // E.g. "ld1.8b { v0, v1 }, [x1]" 9198 // "ld1\t$Vt, [$Rn]" 9199 // may get mapped to 9200 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9201 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9202 (!cast<Instruction>(BaseName # Count # "v" # layout) 9203 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9204 GPR64sp:$Rn), 0>; 9205 9206 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9207 // "ld1\t$Vt, [$Rn], $Xm" 9208 // may get mapped to 9209 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9210 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9211 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9212 GPR64sp:$Rn, 9213 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9214 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9215} 9216 9217multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9218 int Offset128, int Offset64, bits<4> opcode> { 9219 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9220 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9221 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9222 (ins GPR64sp:$Rn), []>; 9223 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9224 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9225 (ins GPR64sp:$Rn), []>; 9226 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9227 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9228 (ins GPR64sp:$Rn), []>; 9229 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9230 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9231 (ins GPR64sp:$Rn), []>; 9232 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9233 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9234 (ins GPR64sp:$Rn), []>; 9235 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9236 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9237 (ins GPR64sp:$Rn), []>; 9238 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9239 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9240 (ins GPR64sp:$Rn), []>; 9241 9242 9243 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9244 (outs GPR64sp:$wback, 9245 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9246 (ins GPR64sp:$Rn, 9247 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9248 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9249 (outs GPR64sp:$wback, 9250 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9251 (ins GPR64sp:$Rn, 9252 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9253 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9254 (outs GPR64sp:$wback, 9255 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9256 (ins GPR64sp:$Rn, 9257 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9258 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9259 (outs GPR64sp:$wback, 9260 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9261 (ins GPR64sp:$Rn, 9262 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9263 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9264 (outs GPR64sp:$wback, 9265 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9266 (ins GPR64sp:$Rn, 9267 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9268 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9269 (outs GPR64sp:$wback, 9270 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9271 (ins GPR64sp:$Rn, 9272 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9273 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9274 (outs GPR64sp:$wback, 9275 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9276 (ins GPR64sp:$Rn, 9277 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9278 } 9279 9280 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9281 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9282 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9283 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9284 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9285 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9286 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9287} 9288 9289// Only ld1/st1 has a v1d version. 9290multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9291 int Offset128, int Offset64, bits<4> opcode> { 9292 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9293 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9294 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9295 GPR64sp:$Rn), []>; 9296 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9297 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9298 GPR64sp:$Rn), []>; 9299 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9300 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9301 GPR64sp:$Rn), []>; 9302 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9303 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9304 GPR64sp:$Rn), []>; 9305 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9306 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9307 GPR64sp:$Rn), []>; 9308 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9309 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9310 GPR64sp:$Rn), []>; 9311 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9312 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9313 GPR64sp:$Rn), []>; 9314 9315 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9316 (outs GPR64sp:$wback), 9317 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9318 GPR64sp:$Rn, 9319 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9320 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9321 (outs GPR64sp:$wback), 9322 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9323 GPR64sp:$Rn, 9324 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9325 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9326 (outs GPR64sp:$wback), 9327 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9328 GPR64sp:$Rn, 9329 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9330 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9331 (outs GPR64sp:$wback), 9332 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9333 GPR64sp:$Rn, 9334 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9335 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9336 (outs GPR64sp:$wback), 9337 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9338 GPR64sp:$Rn, 9339 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9340 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9341 (outs GPR64sp:$wback), 9342 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9343 GPR64sp:$Rn, 9344 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9345 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9346 (outs GPR64sp:$wback), 9347 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9348 GPR64sp:$Rn, 9349 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9350 } 9351 9352 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9353 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9354 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9355 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9356 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9357 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9358 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9359} 9360 9361multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9362 int Offset128, int Offset64, bits<4> opcode> 9363 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9364 9365 // LD1 instructions have extra "1d" variants. 9366 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9367 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9368 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9369 (ins GPR64sp:$Rn), []>; 9370 9371 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9372 (outs GPR64sp:$wback, 9373 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9374 (ins GPR64sp:$Rn, 9375 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9376 } 9377 9378 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9379} 9380 9381multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9382 int Offset128, int Offset64, bits<4> opcode> 9383 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9384 9385 // ST1 instructions have extra "1d" variants. 9386 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9387 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9388 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9389 GPR64sp:$Rn), []>; 9390 9391 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9392 (outs GPR64sp:$wback), 9393 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9394 GPR64sp:$Rn, 9395 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9396 } 9397 9398 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9399} 9400 9401multiclass SIMDLd1Multiple<string asm> { 9402 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9403 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9404 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9405 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9406} 9407 9408multiclass SIMDSt1Multiple<string asm> { 9409 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9410 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9411 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9412 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9413} 9414 9415multiclass SIMDLd2Multiple<string asm> { 9416 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9417} 9418 9419multiclass SIMDSt2Multiple<string asm> { 9420 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9421} 9422 9423multiclass SIMDLd3Multiple<string asm> { 9424 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9425} 9426 9427multiclass SIMDSt3Multiple<string asm> { 9428 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9429} 9430 9431multiclass SIMDLd4Multiple<string asm> { 9432 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9433} 9434 9435multiclass SIMDSt4Multiple<string asm> { 9436 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9437} 9438 9439//--- 9440// AdvSIMD Load/store single-element 9441//--- 9442 9443class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 9444 string asm, string operands, string cst, 9445 dag oops, dag iops, list<dag> pattern> 9446 : I<oops, iops, asm, operands, cst, pattern> { 9447 bits<5> Vt; 9448 bits<5> Rn; 9449 let Inst{31} = 0; 9450 let Inst{29-24} = 0b001101; 9451 let Inst{22} = L; 9452 let Inst{21} = R; 9453 let Inst{15-13} = opcode; 9454 let Inst{9-5} = Rn; 9455 let Inst{4-0} = Vt; 9456} 9457 9458class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 9459 string asm, string operands, string cst, 9460 dag oops, dag iops, list<dag> pattern> 9461 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 9462 bits<5> Vt; 9463 bits<5> Rn; 9464 let Inst{31} = 0; 9465 let Inst{29-24} = 0b001101; 9466 let Inst{22} = L; 9467 let Inst{21} = R; 9468 let Inst{15-13} = opcode; 9469 let Inst{9-5} = Rn; 9470 let Inst{4-0} = Vt; 9471} 9472 9473 9474let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9475class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 9476 DAGOperand listtype> 9477 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 9478 (outs listtype:$Vt), (ins GPR64sp:$Rn), 9479 []> { 9480 let Inst{30} = Q; 9481 let Inst{23} = 0; 9482 let Inst{20-16} = 0b00000; 9483 let Inst{12} = S; 9484 let Inst{11-10} = size; 9485} 9486let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9487class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 9488 string asm, DAGOperand listtype, DAGOperand GPR64pi> 9489 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 9490 "$Rn = $wback", 9491 (outs GPR64sp:$wback, listtype:$Vt), 9492 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 9493 bits<5> Xm; 9494 let Inst{30} = Q; 9495 let Inst{23} = 1; 9496 let Inst{20-16} = Xm; 9497 let Inst{12} = S; 9498 let Inst{11-10} = size; 9499} 9500 9501multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 9502 int Offset, int Size> { 9503 // E.g. "ld1r { v0.8b }, [x1], #1" 9504 // "ld1r.8b\t$Vt, [$Rn], #1" 9505 // may get mapped to 9506 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9507 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9508 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9509 GPR64sp:$Rn, 9510 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9511 XZR), 1>; 9512 9513 // E.g. "ld1r.8b { v0 }, [x1], #1" 9514 // "ld1r.8b\t$Vt, [$Rn], #1" 9515 // may get mapped to 9516 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9517 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9518 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9519 GPR64sp:$Rn, 9520 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9521 XZR), 0>; 9522 9523 // E.g. "ld1r.8b { v0 }, [x1]" 9524 // "ld1r.8b\t$Vt, [$Rn]" 9525 // may get mapped to 9526 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9527 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9528 (!cast<Instruction>(BaseName # "v" # layout) 9529 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9530 GPR64sp:$Rn), 0>; 9531 9532 // E.g. "ld1r.8b { v0 }, [x1], x2" 9533 // "ld1r.8b\t$Vt, [$Rn], $Xm" 9534 // may get mapped to 9535 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9536 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9537 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9538 GPR64sp:$Rn, 9539 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9540 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9541} 9542 9543multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 9544 int Offset1, int Offset2, int Offset4, int Offset8> { 9545 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 9546 !cast<DAGOperand>("VecList" # Count # "8b")>; 9547 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 9548 !cast<DAGOperand>("VecList" # Count #"16b")>; 9549 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 9550 !cast<DAGOperand>("VecList" # Count #"4h")>; 9551 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 9552 !cast<DAGOperand>("VecList" # Count #"8h")>; 9553 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 9554 !cast<DAGOperand>("VecList" # Count #"2s")>; 9555 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 9556 !cast<DAGOperand>("VecList" # Count #"4s")>; 9557 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 9558 !cast<DAGOperand>("VecList" # Count #"1d")>; 9559 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 9560 !cast<DAGOperand>("VecList" # Count #"2d")>; 9561 9562 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 9563 !cast<DAGOperand>("VecList" # Count # "8b"), 9564 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9565 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 9566 !cast<DAGOperand>("VecList" # Count # "16b"), 9567 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9568 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 9569 !cast<DAGOperand>("VecList" # Count # "4h"), 9570 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9571 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 9572 !cast<DAGOperand>("VecList" # Count # "8h"), 9573 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9574 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 9575 !cast<DAGOperand>("VecList" # Count # "2s"), 9576 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9577 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 9578 !cast<DAGOperand>("VecList" # Count # "4s"), 9579 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9580 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 9581 !cast<DAGOperand>("VecList" # Count # "1d"), 9582 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9583 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 9584 !cast<DAGOperand>("VecList" # Count # "2d"), 9585 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9586 9587 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 9588 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 9589 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 9590 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 9591 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 9592 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 9593 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 9594 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 9595} 9596 9597class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 9598 dag oops, dag iops, list<dag> pattern> 9599 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9600 pattern> { 9601 // idx encoded in Q:S:size fields. 9602 bits<4> idx; 9603 let Inst{30} = idx{3}; 9604 let Inst{23} = 0; 9605 let Inst{20-16} = 0b00000; 9606 let Inst{12} = idx{2}; 9607 let Inst{11-10} = idx{1-0}; 9608} 9609class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 9610 dag oops, dag iops, list<dag> pattern> 9611 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9612 oops, iops, pattern> { 9613 // idx encoded in Q:S:size fields. 9614 bits<4> idx; 9615 let Inst{30} = idx{3}; 9616 let Inst{23} = 0; 9617 let Inst{20-16} = 0b00000; 9618 let Inst{12} = idx{2}; 9619 let Inst{11-10} = idx{1-0}; 9620} 9621class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 9622 dag oops, dag iops> 9623 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9624 "$Rn = $wback", oops, iops, []> { 9625 // idx encoded in Q:S:size fields. 9626 bits<4> idx; 9627 bits<5> Xm; 9628 let Inst{30} = idx{3}; 9629 let Inst{23} = 1; 9630 let Inst{20-16} = Xm; 9631 let Inst{12} = idx{2}; 9632 let Inst{11-10} = idx{1-0}; 9633} 9634class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 9635 dag oops, dag iops> 9636 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9637 "$Rn = $wback", oops, iops, []> { 9638 // idx encoded in Q:S:size fields. 9639 bits<4> idx; 9640 bits<5> Xm; 9641 let Inst{30} = idx{3}; 9642 let Inst{23} = 1; 9643 let Inst{20-16} = Xm; 9644 let Inst{12} = idx{2}; 9645 let Inst{11-10} = idx{1-0}; 9646} 9647 9648class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 9649 dag oops, dag iops, list<dag> pattern> 9650 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9651 pattern> { 9652 // idx encoded in Q:S:size<1> fields. 9653 bits<3> idx; 9654 let Inst{30} = idx{2}; 9655 let Inst{23} = 0; 9656 let Inst{20-16} = 0b00000; 9657 let Inst{12} = idx{1}; 9658 let Inst{11} = idx{0}; 9659 let Inst{10} = size; 9660} 9661class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 9662 dag oops, dag iops, list<dag> pattern> 9663 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9664 oops, iops, pattern> { 9665 // idx encoded in Q:S:size<1> fields. 9666 bits<3> idx; 9667 let Inst{30} = idx{2}; 9668 let Inst{23} = 0; 9669 let Inst{20-16} = 0b00000; 9670 let Inst{12} = idx{1}; 9671 let Inst{11} = idx{0}; 9672 let Inst{10} = size; 9673} 9674 9675class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 9676 dag oops, dag iops> 9677 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9678 "$Rn = $wback", oops, iops, []> { 9679 // idx encoded in Q:S:size<1> fields. 9680 bits<3> idx; 9681 bits<5> Xm; 9682 let Inst{30} = idx{2}; 9683 let Inst{23} = 1; 9684 let Inst{20-16} = Xm; 9685 let Inst{12} = idx{1}; 9686 let Inst{11} = idx{0}; 9687 let Inst{10} = size; 9688} 9689class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 9690 dag oops, dag iops> 9691 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9692 "$Rn = $wback", oops, iops, []> { 9693 // idx encoded in Q:S:size<1> fields. 9694 bits<3> idx; 9695 bits<5> Xm; 9696 let Inst{30} = idx{2}; 9697 let Inst{23} = 1; 9698 let Inst{20-16} = Xm; 9699 let Inst{12} = idx{1}; 9700 let Inst{11} = idx{0}; 9701 let Inst{10} = size; 9702} 9703class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9704 dag oops, dag iops, list<dag> pattern> 9705 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9706 pattern> { 9707 // idx encoded in Q:S fields. 9708 bits<2> idx; 9709 let Inst{30} = idx{1}; 9710 let Inst{23} = 0; 9711 let Inst{20-16} = 0b00000; 9712 let Inst{12} = idx{0}; 9713 let Inst{11-10} = size; 9714} 9715class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9716 dag oops, dag iops, list<dag> pattern> 9717 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9718 oops, iops, pattern> { 9719 // idx encoded in Q:S fields. 9720 bits<2> idx; 9721 let Inst{30} = idx{1}; 9722 let Inst{23} = 0; 9723 let Inst{20-16} = 0b00000; 9724 let Inst{12} = idx{0}; 9725 let Inst{11-10} = size; 9726} 9727class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 9728 string asm, dag oops, dag iops> 9729 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9730 "$Rn = $wback", oops, iops, []> { 9731 // idx encoded in Q:S fields. 9732 bits<2> idx; 9733 bits<5> Xm; 9734 let Inst{30} = idx{1}; 9735 let Inst{23} = 1; 9736 let Inst{20-16} = Xm; 9737 let Inst{12} = idx{0}; 9738 let Inst{11-10} = size; 9739} 9740class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 9741 string asm, dag oops, dag iops> 9742 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9743 "$Rn = $wback", oops, iops, []> { 9744 // idx encoded in Q:S fields. 9745 bits<2> idx; 9746 bits<5> Xm; 9747 let Inst{30} = idx{1}; 9748 let Inst{23} = 1; 9749 let Inst{20-16} = Xm; 9750 let Inst{12} = idx{0}; 9751 let Inst{11-10} = size; 9752} 9753class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9754 dag oops, dag iops, list<dag> pattern> 9755 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9756 pattern> { 9757 // idx encoded in Q field. 9758 bits<1> idx; 9759 let Inst{30} = idx; 9760 let Inst{23} = 0; 9761 let Inst{20-16} = 0b00000; 9762 let Inst{12} = 0; 9763 let Inst{11-10} = size; 9764} 9765class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9766 dag oops, dag iops, list<dag> pattern> 9767 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9768 oops, iops, pattern> { 9769 // idx encoded in Q field. 9770 bits<1> idx; 9771 let Inst{30} = idx; 9772 let Inst{23} = 0; 9773 let Inst{20-16} = 0b00000; 9774 let Inst{12} = 0; 9775 let Inst{11-10} = size; 9776} 9777class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 9778 string asm, dag oops, dag iops> 9779 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9780 "$Rn = $wback", oops, iops, []> { 9781 // idx encoded in Q field. 9782 bits<1> idx; 9783 bits<5> Xm; 9784 let Inst{30} = idx; 9785 let Inst{23} = 1; 9786 let Inst{20-16} = Xm; 9787 let Inst{12} = 0; 9788 let Inst{11-10} = size; 9789} 9790class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 9791 string asm, dag oops, dag iops> 9792 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9793 "$Rn = $wback", oops, iops, []> { 9794 // idx encoded in Q field. 9795 bits<1> idx; 9796 bits<5> Xm; 9797 let Inst{30} = idx; 9798 let Inst{23} = 1; 9799 let Inst{20-16} = Xm; 9800 let Inst{12} = 0; 9801 let Inst{11-10} = size; 9802} 9803 9804let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9805multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 9806 RegisterOperand listtype, 9807 RegisterOperand GPR64pi> { 9808 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 9809 (outs listtype:$dst), 9810 (ins listtype:$Vt, VectorIndexB:$idx, 9811 GPR64sp:$Rn), []>; 9812 9813 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 9814 (outs GPR64sp:$wback, listtype:$dst), 9815 (ins listtype:$Vt, VectorIndexB:$idx, 9816 GPR64sp:$Rn, GPR64pi:$Xm)>; 9817} 9818let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9819multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 9820 RegisterOperand listtype, 9821 RegisterOperand GPR64pi> { 9822 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 9823 (outs listtype:$dst), 9824 (ins listtype:$Vt, VectorIndexH:$idx, 9825 GPR64sp:$Rn), []>; 9826 9827 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 9828 (outs GPR64sp:$wback, listtype:$dst), 9829 (ins listtype:$Vt, VectorIndexH:$idx, 9830 GPR64sp:$Rn, GPR64pi:$Xm)>; 9831} 9832let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9833multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 9834 RegisterOperand listtype, 9835 RegisterOperand GPR64pi> { 9836 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 9837 (outs listtype:$dst), 9838 (ins listtype:$Vt, VectorIndexS:$idx, 9839 GPR64sp:$Rn), []>; 9840 9841 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 9842 (outs GPR64sp:$wback, listtype:$dst), 9843 (ins listtype:$Vt, VectorIndexS:$idx, 9844 GPR64sp:$Rn, GPR64pi:$Xm)>; 9845} 9846let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9847multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 9848 RegisterOperand listtype, RegisterOperand GPR64pi> { 9849 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 9850 (outs listtype:$dst), 9851 (ins listtype:$Vt, VectorIndexD:$idx, 9852 GPR64sp:$Rn), []>; 9853 9854 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 9855 (outs GPR64sp:$wback, listtype:$dst), 9856 (ins listtype:$Vt, VectorIndexD:$idx, 9857 GPR64sp:$Rn, GPR64pi:$Xm)>; 9858} 9859let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9860multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 9861 RegisterOperand listtype, RegisterOperand GPR64pi> { 9862 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 9863 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 9864 GPR64sp:$Rn), []>; 9865 9866 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 9867 (outs GPR64sp:$wback), 9868 (ins listtype:$Vt, VectorIndexB:$idx, 9869 GPR64sp:$Rn, GPR64pi:$Xm)>; 9870} 9871let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9872multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 9873 RegisterOperand listtype, RegisterOperand GPR64pi> { 9874 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 9875 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 9876 GPR64sp:$Rn), []>; 9877 9878 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 9879 (outs GPR64sp:$wback), 9880 (ins listtype:$Vt, VectorIndexH:$idx, 9881 GPR64sp:$Rn, GPR64pi:$Xm)>; 9882} 9883let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9884multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 9885 RegisterOperand listtype, RegisterOperand GPR64pi> { 9886 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 9887 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 9888 GPR64sp:$Rn), []>; 9889 9890 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 9891 (outs GPR64sp:$wback), 9892 (ins listtype:$Vt, VectorIndexS:$idx, 9893 GPR64sp:$Rn, GPR64pi:$Xm)>; 9894} 9895let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9896multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 9897 RegisterOperand listtype, RegisterOperand GPR64pi> { 9898 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 9899 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 9900 GPR64sp:$Rn), []>; 9901 9902 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 9903 (outs GPR64sp:$wback), 9904 (ins listtype:$Vt, VectorIndexD:$idx, 9905 GPR64sp:$Rn, GPR64pi:$Xm)>; 9906} 9907 9908multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 9909 string Count, int Offset, Operand idxtype> { 9910 // E.g. "ld1 { v0.8b }[0], [x1], #1" 9911 // "ld1\t$Vt, [$Rn], #1" 9912 // may get mapped to 9913 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9914 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 9915 (!cast<Instruction>(NAME # Type # "_POST") 9916 GPR64sp:$Rn, 9917 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9918 idxtype:$idx, XZR), 1>; 9919 9920 // E.g. "ld1.8b { v0 }[0], [x1], #1" 9921 // "ld1.8b\t$Vt, [$Rn], #1" 9922 // may get mapped to 9923 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9924 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 9925 (!cast<Instruction>(NAME # Type # "_POST") 9926 GPR64sp:$Rn, 9927 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9928 idxtype:$idx, XZR), 0>; 9929 9930 // E.g. "ld1.8b { v0 }[0], [x1]" 9931 // "ld1.8b\t$Vt, [$Rn]" 9932 // may get mapped to 9933 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9934 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 9935 (!cast<Instruction>(NAME # Type) 9936 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9937 idxtype:$idx, GPR64sp:$Rn), 0>; 9938 9939 // E.g. "ld1.8b { v0 }[0], [x1], x2" 9940 // "ld1.8b\t$Vt, [$Rn], $Xm" 9941 // may get mapped to 9942 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9943 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 9944 (!cast<Instruction>(NAME # Type # "_POST") 9945 GPR64sp:$Rn, 9946 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9947 idxtype:$idx, 9948 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9949} 9950 9951multiclass SIMDLdSt1SingleAliases<string asm> { 9952 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 9953 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 9954 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 9955 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 9956} 9957 9958multiclass SIMDLdSt2SingleAliases<string asm> { 9959 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 9960 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 9961 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 9962 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 9963} 9964 9965multiclass SIMDLdSt3SingleAliases<string asm> { 9966 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 9967 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 9968 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 9969 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 9970} 9971 9972multiclass SIMDLdSt4SingleAliases<string asm> { 9973 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 9974 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 9975 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 9976 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 9977} 9978} // end of 'let Predicates = [HasNEON]' 9979 9980//---------------------------------------------------------------------------- 9981// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 9982//---------------------------------------------------------------------------- 9983 9984let Predicates = [HasNEON, HasRDM] in { 9985 9986class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 9987 RegisterOperand regtype, string asm, 9988 string kind, list<dag> pattern> 9989 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 9990 pattern> { 9991} 9992multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 9993 SDPatternOperator Accum> { 9994 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 9995 [(set (v4i16 V64:$dst), 9996 (Accum (v4i16 V64:$Rd), 9997 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 9998 (v4i16 V64:$Rm)))))]>; 9999 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10000 [(set (v8i16 V128:$dst), 10001 (Accum (v8i16 V128:$Rd), 10002 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 10003 (v8i16 V128:$Rm)))))]>; 10004 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10005 [(set (v2i32 V64:$dst), 10006 (Accum (v2i32 V64:$Rd), 10007 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 10008 (v2i32 V64:$Rm)))))]>; 10009 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10010 [(set (v4i32 V128:$dst), 10011 (Accum (v4i32 V128:$Rd), 10012 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 10013 (v4i32 V128:$Rm)))))]>; 10014} 10015 10016multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10017 SDPatternOperator Accum> { 10018 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10019 V64, V64, V128_lo, VectorIndexH, 10020 asm, ".4h", ".4h", ".4h", ".h", 10021 [(set (v4i16 V64:$dst), 10022 (Accum (v4i16 V64:$Rd), 10023 (v4i16 (int_aarch64_neon_sqrdmulh 10024 (v4i16 V64:$Rn), 10025 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10026 VectorIndexH:$idx))))))]> { 10027 bits<3> idx; 10028 let Inst{11} = idx{2}; 10029 let Inst{21} = idx{1}; 10030 let Inst{20} = idx{0}; 10031 } 10032 10033 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10034 V128, V128, V128_lo, VectorIndexH, 10035 asm, ".8h", ".8h", ".8h", ".h", 10036 [(set (v8i16 V128:$dst), 10037 (Accum (v8i16 V128:$Rd), 10038 (v8i16 (int_aarch64_neon_sqrdmulh 10039 (v8i16 V128:$Rn), 10040 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10041 VectorIndexH:$idx))))))]> { 10042 bits<3> idx; 10043 let Inst{11} = idx{2}; 10044 let Inst{21} = idx{1}; 10045 let Inst{20} = idx{0}; 10046 } 10047 10048 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10049 V64, V64, V128, VectorIndexS, 10050 asm, ".2s", ".2s", ".2s", ".s", 10051 [(set (v2i32 V64:$dst), 10052 (Accum (v2i32 V64:$Rd), 10053 (v2i32 (int_aarch64_neon_sqrdmulh 10054 (v2i32 V64:$Rn), 10055 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10056 VectorIndexS:$idx))))))]> { 10057 bits<2> idx; 10058 let Inst{11} = idx{1}; 10059 let Inst{21} = idx{0}; 10060 } 10061 10062 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10063 // an intermediate EXTRACT_SUBREG would be untyped. 10064 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 10065 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 10066 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10067 (i32 (vector_extract 10068 (v4i32 (insert_subvector 10069 (undef), 10070 (v2i32 (int_aarch64_neon_sqrdmulh 10071 (v2i32 V64:$Rn), 10072 (v2i32 (AArch64duplane32 10073 (v4i32 V128:$Rm), 10074 VectorIndexS:$idx)))), 10075 (i32 0))), 10076 (i64 0))))), 10077 (EXTRACT_SUBREG 10078 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 10079 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 10080 FPR32Op:$Rd, 10081 ssub)), 10082 V64:$Rn, 10083 V128:$Rm, 10084 VectorIndexS:$idx)), 10085 ssub)>; 10086 10087 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10088 V128, V128, V128, VectorIndexS, 10089 asm, ".4s", ".4s", ".4s", ".s", 10090 [(set (v4i32 V128:$dst), 10091 (Accum (v4i32 V128:$Rd), 10092 (v4i32 (int_aarch64_neon_sqrdmulh 10093 (v4i32 V128:$Rn), 10094 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10095 VectorIndexS:$idx))))))]> { 10096 bits<2> idx; 10097 let Inst{11} = idx{1}; 10098 let Inst{21} = idx{0}; 10099 } 10100 10101 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10102 // an intermediate EXTRACT_SUBREG would be untyped. 10103 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10104 (i32 (vector_extract 10105 (v4i32 (int_aarch64_neon_sqrdmulh 10106 (v4i32 V128:$Rn), 10107 (v4i32 (AArch64duplane32 10108 (v4i32 V128:$Rm), 10109 VectorIndexS:$idx)))), 10110 (i64 0))))), 10111 (EXTRACT_SUBREG 10112 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 10113 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 10114 FPR32Op:$Rd, 10115 ssub)), 10116 V128:$Rn, 10117 V128:$Rm, 10118 VectorIndexS:$idx)), 10119 ssub)>; 10120 10121 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10122 FPR16Op, FPR16Op, V128_lo, 10123 VectorIndexH, asm, ".h", "", "", ".h", 10124 []> { 10125 bits<3> idx; 10126 let Inst{11} = idx{2}; 10127 let Inst{21} = idx{1}; 10128 let Inst{20} = idx{0}; 10129 } 10130 10131 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10132 FPR32Op, FPR32Op, V128, VectorIndexS, 10133 asm, ".s", "", "", ".s", 10134 [(set (i32 FPR32Op:$dst), 10135 (Accum (i32 FPR32Op:$Rd), 10136 (i32 (int_aarch64_neon_sqrdmulh 10137 (i32 FPR32Op:$Rn), 10138 (i32 (vector_extract (v4i32 V128:$Rm), 10139 VectorIndexS:$idx))))))]> { 10140 bits<2> idx; 10141 let Inst{11} = idx{1}; 10142 let Inst{21} = idx{0}; 10143 } 10144} 10145} // let Predicates = [HasNeon, HasRDM] 10146 10147//---------------------------------------------------------------------------- 10148// ARMv8.3 Complex ADD/MLA instructions 10149//---------------------------------------------------------------------------- 10150 10151class ComplexRotationOperand<int Angle, int Remainder, string Type> 10152 : AsmOperandClass { 10153 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10154 let DiagnosticType = "InvalidComplexRotation" # Type; 10155 let Name = "ComplexRotation" # Type; 10156} 10157def complexrotateop : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10158 SDNodeXForm<imm, [{ 10159 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10160}]>> { 10161 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10162 let PrintMethod = "printComplexRotationOp<90, 0>"; 10163} 10164def complexrotateopodd : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10165 SDNodeXForm<imm, [{ 10166 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10167}]>> { 10168 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10169 let PrintMethod = "printComplexRotationOp<180, 90>"; 10170} 10171let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10172class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10173 RegisterOperand regtype, Operand rottype, 10174 string asm, string kind, list<dag> pattern> 10175 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10176 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10177 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10178 Sched<[WriteV]> { 10179 bits<5> Rd; 10180 bits<5> Rn; 10181 bits<5> Rm; 10182 bits<1> rot; 10183 let Inst{31} = 0; 10184 let Inst{30} = Q; 10185 let Inst{29} = U; 10186 let Inst{28-24} = 0b01110; 10187 let Inst{23-22} = size; 10188 let Inst{21} = 0; 10189 let Inst{20-16} = Rm; 10190 let Inst{15-13} = opcode; 10191 // Non-tied version (FCADD) only has one rotation bit 10192 let Inst{12} = rot; 10193 let Inst{11} = 0; 10194 let Inst{10} = 1; 10195 let Inst{9-5} = Rn; 10196 let Inst{4-0} = Rd; 10197} 10198 10199//8.3 CompNum - Floating-point complex number support 10200multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10201 string asm, SDPatternOperator OpNode>{ 10202 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10203 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10204 asm, ".4h", 10205 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10206 (v4f16 V64:$Rn), 10207 (v4f16 V64:$Rm), 10208 (rottype i32:$rot)))]>; 10209 10210 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10211 asm, ".8h", 10212 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10213 (v8f16 V128:$Rn), 10214 (v8f16 V128:$Rm), 10215 (rottype i32:$rot)))]>; 10216 } 10217 10218 let Predicates = [HasComplxNum, HasNEON] in { 10219 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10220 asm, ".2s", 10221 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10222 (v2f32 V64:$Rn), 10223 (v2f32 V64:$Rm), 10224 (rottype i32:$rot)))]>; 10225 10226 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10227 asm, ".4s", 10228 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10229 (v4f32 V128:$Rn), 10230 (v4f32 V128:$Rm), 10231 (rottype i32:$rot)))]>; 10232 10233 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10234 asm, ".2d", 10235 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10236 (v2f64 V128:$Rn), 10237 (v2f64 V128:$Rm), 10238 (rottype i32:$rot)))]>; 10239 } 10240} 10241 10242let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10243class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10244 bits<3> opcode, 10245 RegisterOperand regtype, 10246 Operand rottype, string asm, 10247 string kind, list<dag> pattern> 10248 : I<(outs regtype:$dst), 10249 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10250 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10251 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10252 Sched<[WriteV]> { 10253 bits<5> Rd; 10254 bits<5> Rn; 10255 bits<5> Rm; 10256 bits<2> rot; 10257 let Inst{31} = 0; 10258 let Inst{30} = Q; 10259 let Inst{29} = U; 10260 let Inst{28-24} = 0b01110; 10261 let Inst{23-22} = size; 10262 let Inst{21} = 0; 10263 let Inst{20-16} = Rm; 10264 let Inst{15-13} = opcode; 10265 let Inst{12-11} = rot; 10266 let Inst{10} = 1; 10267 let Inst{9-5} = Rn; 10268 let Inst{4-0} = Rd; 10269} 10270 10271multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10272 Operand rottype, string asm, 10273 SDPatternOperator OpNode> { 10274 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10275 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10276 rottype, asm, ".4h", 10277 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10278 (v4f16 V64:$Rn), 10279 (v4f16 V64:$Rm), 10280 (rottype i32:$rot)))]>; 10281 10282 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10283 rottype, asm, ".8h", 10284 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10285 (v8f16 V128:$Rn), 10286 (v8f16 V128:$Rm), 10287 (rottype i32:$rot)))]>; 10288 } 10289 10290 let Predicates = [HasComplxNum, HasNEON] in { 10291 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10292 rottype, asm, ".2s", 10293 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10294 (v2f32 V64:$Rn), 10295 (v2f32 V64:$Rm), 10296 (rottype i32:$rot)))]>; 10297 10298 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10299 rottype, asm, ".4s", 10300 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10301 (v4f32 V128:$Rn), 10302 (v4f32 V128:$Rm), 10303 (rottype i32:$rot)))]>; 10304 10305 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10306 rottype, asm, ".2d", 10307 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10308 (v2f64 V128:$Rn), 10309 (v2f64 V128:$Rm), 10310 (rottype i32:$rot)))]>; 10311 } 10312} 10313 10314let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10315class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10316 bit opc1, bit opc2, RegisterOperand dst_reg, 10317 RegisterOperand lhs_reg, 10318 RegisterOperand rhs_reg, Operand vec_idx, 10319 Operand rottype, string asm, string apple_kind, 10320 string dst_kind, string lhs_kind, 10321 string rhs_kind, list<dag> pattern> 10322 : I<(outs dst_reg:$dst), 10323 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10324 asm, 10325 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10326 "$idx, $rot" # "|" # apple_kind # 10327 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10328 Sched<[WriteV]> { 10329 bits<5> Rd; 10330 bits<5> Rn; 10331 bits<5> Rm; 10332 bits<2> rot; 10333 10334 let Inst{31} = 0; 10335 let Inst{30} = Q; 10336 let Inst{29} = U; 10337 let Inst{28} = Scalar; 10338 let Inst{27-24} = 0b1111; 10339 let Inst{23-22} = size; 10340 // Bit 21 must be set by the derived class. 10341 let Inst{20-16} = Rm; 10342 let Inst{15} = opc1; 10343 let Inst{14-13} = rot; 10344 let Inst{12} = opc2; 10345 // Bit 11 must be set by the derived class. 10346 let Inst{10} = 0; 10347 let Inst{9-5} = Rn; 10348 let Inst{4-0} = Rd; 10349} 10350 10351// The complex instructions index by pairs of elements, so the VectorIndexes 10352// don't match the lane types, and the index bits are different to the other 10353// classes. 10354multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype, 10355 string asm, SDPatternOperator OpNode> { 10356 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10357 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10358 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10359 ".4h", ".h", []> { 10360 bits<1> idx; 10361 let Inst{11} = 0; 10362 let Inst{21} = idx{0}; 10363 } 10364 10365 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10366 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10367 ".8h", ".8h", ".h", []> { 10368 bits<2> idx; 10369 let Inst{11} = idx{1}; 10370 let Inst{21} = idx{0}; 10371 } 10372 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10373 10374 let Predicates = [HasComplxNum, HasNEON] in { 10375 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10376 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10377 ".4s", ".4s", ".s", []> { 10378 bits<1> idx; 10379 let Inst{11} = idx{0}; 10380 let Inst{21} = 0; 10381 } 10382 } // Predicates = [HasComplxNum, HasNEON] 10383} 10384 10385//---------------------------------------------------------------------------- 10386// Crypto extensions 10387//---------------------------------------------------------------------------- 10388 10389let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10390class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10391 list<dag> pat> 10392 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10393 Sched<[WriteV]>{ 10394 bits<5> Rd; 10395 bits<5> Rn; 10396 let Inst{31-16} = 0b0100111000101000; 10397 let Inst{15-12} = opc; 10398 let Inst{11-10} = 0b10; 10399 let Inst{9-5} = Rn; 10400 let Inst{4-0} = Rd; 10401} 10402 10403class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10404 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10405 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10406 10407class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10408 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10409 "$Rd = $dst", 10410 [(set (v16i8 V128:$dst), 10411 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10412 10413let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10414class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10415 dag oops, dag iops, list<dag> pat> 10416 : I<oops, iops, asm, 10417 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10418 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10419 Sched<[WriteV]>{ 10420 bits<5> Rd; 10421 bits<5> Rn; 10422 bits<5> Rm; 10423 let Inst{31-21} = 0b01011110000; 10424 let Inst{20-16} = Rm; 10425 let Inst{15} = 0; 10426 let Inst{14-12} = opc; 10427 let Inst{11-10} = 0b00; 10428 let Inst{9-5} = Rn; 10429 let Inst{4-0} = Rd; 10430} 10431 10432class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10433 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10434 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10435 [(set (v4i32 FPR128:$dst), 10436 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10437 (v4i32 V128:$Rm)))]>; 10438 10439class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10440 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10441 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10442 [(set (v4i32 V128:$dst), 10443 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10444 (v4i32 V128:$Rm)))]>; 10445 10446class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10447 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10448 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10449 [(set (v4i32 FPR128:$dst), 10450 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10451 (v4i32 V128:$Rm)))]>; 10452 10453let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10454class SHA2OpInst<bits<4> opc, string asm, string kind, 10455 string cstr, dag oops, dag iops, 10456 list<dag> pat> 10457 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10458 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10459 Sched<[WriteV]>{ 10460 bits<5> Rd; 10461 bits<5> Rn; 10462 let Inst{31-16} = 0b0101111000101000; 10463 let Inst{15-12} = opc; 10464 let Inst{11-10} = 0b10; 10465 let Inst{9-5} = Rn; 10466 let Inst{4-0} = Rd; 10467} 10468 10469class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10470 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10471 (ins V128:$Rd, V128:$Rn), 10472 [(set (v4i32 V128:$dst), 10473 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10474 10475class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10476 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10477 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10478 10479// Armv8.2-A Crypto extensions 10480class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10481 list<dag> pattern> 10482 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> { 10483 bits<5> Vd; 10484 bits<5> Vn; 10485 let Inst{31-25} = 0b1100111; 10486 let Inst{9-5} = Vn; 10487 let Inst{4-0} = Vd; 10488} 10489 10490class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10491 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops, 10492 "$Vm = $Vd", []> { 10493 let Inst{31-25} = 0b1100111; 10494 let Inst{24-21} = 0b0110; 10495 let Inst{20-15} = 0b000001; 10496 let Inst{14} = op0; 10497 let Inst{13-12} = 0b00; 10498 let Inst{11-10} = op1; 10499} 10500class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 10501 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 10502class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 10503 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 10504 10505class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 10506 string asmops, string cst> 10507 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 10508 bits<5> Vm; 10509 let Inst{24-21} = 0b0011; 10510 let Inst{20-16} = Vm; 10511 let Inst{15} = 0b1; 10512 let Inst{14} = op0; 10513 let Inst{13-12} = 0b00; 10514 let Inst{11-10} = op1; 10515} 10516class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 10517 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10518 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 10519class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 10520 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10521 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10522class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 10523 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10524 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 10525class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 10526 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10527 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10528class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 10529 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 10530 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10531 10532class CryptoRRRR<bits<2>op0, string asm, string asmops> 10533 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 10534 asmops, "", []> { 10535 bits<5> Vm; 10536 bits<5> Va; 10537 let Inst{24-23} = 0b00; 10538 let Inst{22-21} = op0; 10539 let Inst{20-16} = Vm; 10540 let Inst{15} = 0b0; 10541 let Inst{14-10} = Va; 10542} 10543class CryptoRRRR_16B<bits<2>op0, string asm> 10544 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 10545 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 10546} 10547class CryptoRRRR_4S<bits<2>op0, string asm> 10548 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 10549 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 10550} 10551 10552class CryptoRRRi6<string asm> 10553 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 10554 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 10555 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 10556 bits<6> imm; 10557 bits<5> Vm; 10558 let Inst{24-21} = 0b0100; 10559 let Inst{20-16} = Vm; 10560 let Inst{15-10} = imm; 10561 let Inst{9-5} = Vn; 10562 let Inst{4-0} = Vd; 10563} 10564 10565class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 10566 : BaseCryptoV82<(outs V128:$Vdst), 10567 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 10568 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 10569 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 10570 bits<2> imm; 10571 bits<5> Vm; 10572 let Inst{24-21} = 0b0010; 10573 let Inst{20-16} = Vm; 10574 let Inst{15} = 0b1; 10575 let Inst{14} = op0; 10576 let Inst{13-12} = imm; 10577 let Inst{11-10} = op1; 10578} 10579 10580//---------------------------------------------------------------------------- 10581// v8.1 atomic instructions extension: 10582// * CAS 10583// * CASP 10584// * SWP 10585// * LDOPregister<OP>, and aliases STOPregister<OP> 10586 10587// Instruction encodings: 10588// 10589// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 10590// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 10591// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 10592// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 10593// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 10594// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 10595 10596// Instruction syntax: 10597// 10598// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10599// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 10600// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 10601// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 10602// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10603// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 10604// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10605// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 10606// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 10607// ST<OP>{<order>} <Xs>, [<Xn|SP>] 10608 10609let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 10610class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 10611 string cstr, list<dag> pattern> 10612 : I<oops, iops, asm, operands, cstr, pattern> { 10613 bits<2> Sz; 10614 bit NP; 10615 bit Acq; 10616 bit Rel; 10617 bits<5> Rs; 10618 bits<5> Rn; 10619 bits<5> Rt; 10620 let Inst{31-30} = Sz; 10621 let Inst{29-24} = 0b001000; 10622 let Inst{23} = NP; 10623 let Inst{22} = Acq; 10624 let Inst{21} = 0b1; 10625 let Inst{20-16} = Rs; 10626 let Inst{15} = Rel; 10627 let Inst{14-10} = 0b11111; 10628 let Inst{9-5} = Rn; 10629 let Inst{4-0} = Rt; 10630 let Predicates = [HasLSE]; 10631} 10632 10633class BaseCAS<string order, string size, RegisterClass RC> 10634 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 10635 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 10636 "$out = $Rs",[]>, 10637 Sched<[WriteAtomic]> { 10638 let NP = 1; 10639} 10640 10641multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 10642 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 10643 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 10644 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 10645 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 10646} 10647 10648class BaseCASP<string order, string size, RegisterOperand RC> 10649 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 10650 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 10651 "$out = $Rs",[]>, 10652 Sched<[WriteAtomic]> { 10653 let NP = 0; 10654} 10655 10656multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 10657 let Sz = 0b00, Acq = Acq, Rel = Rel in 10658 def W : BaseCASP<order, "", WSeqPairClassOperand>; 10659 let Sz = 0b01, Acq = Acq, Rel = Rel in 10660 def X : BaseCASP<order, "", XSeqPairClassOperand>; 10661} 10662 10663let Predicates = [HasLSE] in 10664class BaseSWP<string order, string size, RegisterClass RC> 10665 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 10666 "\t$Rs, $Rt, [$Rn]","",[]>, 10667 Sched<[WriteAtomic]> { 10668 bits<2> Sz; 10669 bit Acq; 10670 bit Rel; 10671 bits<5> Rs; 10672 bits<3> opc = 0b000; 10673 bits<5> Rn; 10674 bits<5> Rt; 10675 let Inst{31-30} = Sz; 10676 let Inst{29-24} = 0b111000; 10677 let Inst{23} = Acq; 10678 let Inst{22} = Rel; 10679 let Inst{21} = 0b1; 10680 let Inst{20-16} = Rs; 10681 let Inst{15} = 0b1; 10682 let Inst{14-12} = opc; 10683 let Inst{11-10} = 0b00; 10684 let Inst{9-5} = Rn; 10685 let Inst{4-0} = Rt; 10686 let Predicates = [HasLSE]; 10687} 10688 10689multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 10690 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 10691 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 10692 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 10693 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 10694} 10695 10696let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 10697class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 10698 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 10699 "\t$Rs, $Rt, [$Rn]","",[]>, 10700 Sched<[WriteAtomic]> { 10701 bits<2> Sz; 10702 bit Acq; 10703 bit Rel; 10704 bits<5> Rs; 10705 bits<3> opc; 10706 bits<5> Rn; 10707 bits<5> Rt; 10708 let Inst{31-30} = Sz; 10709 let Inst{29-24} = 0b111000; 10710 let Inst{23} = Acq; 10711 let Inst{22} = Rel; 10712 let Inst{21} = 0b1; 10713 let Inst{20-16} = Rs; 10714 let Inst{15} = 0b0; 10715 let Inst{14-12} = opc; 10716 let Inst{11-10} = 0b00; 10717 let Inst{9-5} = Rn; 10718 let Inst{4-0} = Rt; 10719 let Predicates = [HasLSE]; 10720} 10721 10722multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 10723 string order> { 10724 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 10725 def B : BaseLDOPregister<op, order, "b", GPR32>; 10726 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 10727 def H : BaseLDOPregister<op, order, "h", GPR32>; 10728 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 10729 def W : BaseLDOPregister<op, order, "", GPR32>; 10730 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 10731 def X : BaseLDOPregister<op, order, "", GPR64>; 10732} 10733 10734// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 10735// complex DAG for DstRHS. 10736let Predicates = [HasLSE] in 10737multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 10738 string size, dag SrcRHS, dag DstRHS> { 10739 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 10740 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 10741 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 10742 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 10743 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 10744 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 10745 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 10746 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 10747 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 10748 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 10749} 10750 10751multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 10752 string size, dag RHS> { 10753 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 10754} 10755 10756multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 10757 string size, dag LHS, dag RHS> { 10758 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 10759} 10760 10761multiclass LDOPregister_patterns<string inst, string op> { 10762 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 10763 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 10764 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 10765 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 10766} 10767 10768multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 10769 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 10770 (i64 GPR64:$Rm), 10771 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 10772 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 10773 (i32 GPR32:$Rm), 10774 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 10775 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 10776 (i32 GPR32:$Rm), 10777 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 10778 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 10779 (i32 GPR32:$Rm), 10780 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 10781} 10782 10783let Predicates = [HasLSE] in 10784multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 10785 string size, dag OLD, dag NEW> { 10786 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 10787 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 10788 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 10789 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10790 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 10791 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10792 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 10793 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10794 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 10795 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10796} 10797 10798multiclass CASregister_patterns_ord<string inst, string suffix, string op, 10799 string size, dag OLD, dag NEW> { 10800 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 10801} 10802 10803multiclass CASregister_patterns<string inst, string op> { 10804 defm : CASregister_patterns_ord<inst, "X", op, "64", 10805 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 10806 defm : CASregister_patterns_ord<inst, "W", op, "32", 10807 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 10808 defm : CASregister_patterns_ord<inst, "H", op, "16", 10809 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 10810 defm : CASregister_patterns_ord<inst, "B", op, "8", 10811 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 10812} 10813 10814let Predicates = [HasLSE] in 10815class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 10816 Instruction inst> : 10817 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 10818 10819multiclass STOPregister<string asm, string instr> { 10820 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 10821 !cast<Instruction>(instr # "LB")>; 10822 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 10823 !cast<Instruction>(instr # "LH")>; 10824 def : BaseSTOPregister<asm # "l", GPR32, WZR, 10825 !cast<Instruction>(instr # "LW")>; 10826 def : BaseSTOPregister<asm # "l", GPR64, XZR, 10827 !cast<Instruction>(instr # "LX")>; 10828 def : BaseSTOPregister<asm # "b", GPR32, WZR, 10829 !cast<Instruction>(instr # "B")>; 10830 def : BaseSTOPregister<asm # "h", GPR32, WZR, 10831 !cast<Instruction>(instr # "H")>; 10832 def : BaseSTOPregister<asm, GPR32, WZR, 10833 !cast<Instruction>(instr # "W")>; 10834 def : BaseSTOPregister<asm, GPR64, XZR, 10835 !cast<Instruction>(instr # "X")>; 10836} 10837 10838//---------------------------------------------------------------------------- 10839// Allow the size specifier tokens to be upper case, not just lower. 10840def : TokenAlias<".4B", ".4b">; // Add dot product 10841def : TokenAlias<".8B", ".8b">; 10842def : TokenAlias<".4H", ".4h">; 10843def : TokenAlias<".2S", ".2s">; 10844def : TokenAlias<".1D", ".1d">; 10845def : TokenAlias<".16B", ".16b">; 10846def : TokenAlias<".8H", ".8h">; 10847def : TokenAlias<".4S", ".4s">; 10848def : TokenAlias<".2D", ".2d">; 10849def : TokenAlias<".1Q", ".1q">; 10850def : TokenAlias<".2H", ".2h">; 10851def : TokenAlias<".B", ".b">; 10852def : TokenAlias<".H", ".h">; 10853def : TokenAlias<".S", ".s">; 10854def : TokenAlias<".D", ".d">; 10855def : TokenAlias<".Q", ".q">; 10856