1//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9//===----------------------------------------------------------------------===// 10// Describe AArch64 instructions format here 11// 12 13// Format specifies the encoding used by the instruction. This is part of the 14// ad-hoc solution used to emit machine instruction encodings by our machine 15// code emitter. 16class Format<bits<2> val> { 17 bits<2> Value = val; 18} 19 20def PseudoFrm : Format<0>; 21def NormalFrm : Format<1>; // Do we need any others? 22 23// Enum describing whether an instruction is 24// destructive in its first source operand. 25class DestructiveInstTypeEnum<bits<4> val> { 26 bits<4> Value = val; 27} 28def NotDestructive : DestructiveInstTypeEnum<0>; 29// Destructive in its first operand and can be MOVPRFX'd, but has no other 30// special properties. 31def DestructiveOther : DestructiveInstTypeEnum<1>; 32def DestructiveUnary : DestructiveInstTypeEnum<2>; 33def DestructiveBinaryImm : DestructiveInstTypeEnum<3>; 34def DestructiveBinaryShImmUnpred : DestructiveInstTypeEnum<4>; 35def DestructiveBinary : DestructiveInstTypeEnum<5>; 36def DestructiveBinaryComm : DestructiveInstTypeEnum<6>; 37def DestructiveBinaryCommWithRev : DestructiveInstTypeEnum<7>; 38def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>; 39 40class FalseLanesEnum<bits<2> val> { 41 bits<2> Value = val; 42} 43def FalseLanesNone : FalseLanesEnum<0>; 44def FalseLanesZero : FalseLanesEnum<1>; 45def FalseLanesUndef : FalseLanesEnum<2>; 46 47// AArch64 Instruction Format 48class AArch64Inst<Format f, string cstr> : Instruction { 49 field bits<32> Inst; // Instruction encoding. 50 // Mask of bits that cause an encoding to be UNPREDICTABLE. 51 // If a bit is set, then if the corresponding bit in the 52 // target encoding differs from its value in the "Inst" field, 53 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 54 field bits<32> Unpredictable = 0; 55 // SoftFail is the generic name for this field, but we alias it so 56 // as to make it more obvious what it means in ARM-land. 57 field bits<32> SoftFail = Unpredictable; 58 let Namespace = "AArch64"; 59 Format F = f; 60 bits<2> Form = F.Value; 61 62 // Defaults 63 bit isWhile = 0; 64 bit isPTestLike = 0; 65 FalseLanesEnum FalseLanes = FalseLanesNone; 66 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 67 ElementSizeEnum ElementSize = ElementSizeNone; 68 69 let TSFlags{10} = isPTestLike; 70 let TSFlags{9} = isWhile; 71 let TSFlags{8-7} = FalseLanes.Value; 72 let TSFlags{6-3} = DestructiveInstType.Value; 73 let TSFlags{2-0} = ElementSize.Value; 74 75 let Pattern = []; 76 let Constraints = cstr; 77} 78 79class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 80 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 81 82// Pseudo instructions (don't have encoding information) 83class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 84 : AArch64Inst<PseudoFrm, cstr> { 85 dag OutOperandList = oops; 86 dag InOperandList = iops; 87 let Pattern = pattern; 88 let isCodeGenOnly = 1; 89 let isPseudo = 1; 90} 91 92// Real instructions (have encoding information) 93class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 94 let Pattern = pattern; 95 let Size = 4; 96} 97 98// Normal instructions 99class I<dag oops, dag iops, string asm, string operands, string cstr, 100 list<dag> pattern> 101 : EncodedI<cstr, pattern> { 102 dag OutOperandList = oops; 103 dag InOperandList = iops; 104 let AsmString = !strconcat(asm, operands); 105} 106 107class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 108class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 109class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 110 111// Helper fragment for an extract of the high portion of a 128-bit vector. 112def extract_high_v16i8 : 113 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>; 114def extract_high_v8i16 : 115 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>; 116def extract_high_v4i32 : 117 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>; 118def extract_high_v2i64 : 119 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>; 120 121//===----------------------------------------------------------------------===// 122// Asm Operand Classes. 123// 124 125// Shifter operand for arithmetic shifted encodings. 126def ShifterOperand : AsmOperandClass { 127 let Name = "Shifter"; 128} 129 130// Shifter operand for mov immediate encodings. 131def MovImm32ShifterOperand : AsmOperandClass { 132 let SuperClasses = [ShifterOperand]; 133 let Name = "MovImm32Shifter"; 134 let RenderMethod = "addShifterOperands"; 135 let DiagnosticType = "InvalidMovImm32Shift"; 136} 137def MovImm64ShifterOperand : AsmOperandClass { 138 let SuperClasses = [ShifterOperand]; 139 let Name = "MovImm64Shifter"; 140 let RenderMethod = "addShifterOperands"; 141 let DiagnosticType = "InvalidMovImm64Shift"; 142} 143 144// Shifter operand for arithmetic register shifted encodings. 145class ArithmeticShifterOperand<int width> : AsmOperandClass { 146 let SuperClasses = [ShifterOperand]; 147 let Name = "ArithmeticShifter" # width; 148 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 149 let RenderMethod = "addShifterOperands"; 150 let DiagnosticType = "AddSubRegShift" # width; 151} 152 153def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 154def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 155 156// Shifter operand for logical register shifted encodings. 157class LogicalShifterOperand<int width> : AsmOperandClass { 158 let SuperClasses = [ShifterOperand]; 159 let Name = "LogicalShifter" # width; 160 let PredicateMethod = "isLogicalShifter<" # width # ">"; 161 let RenderMethod = "addShifterOperands"; 162 let DiagnosticType = "AddSubRegShift" # width; 163} 164 165def LogicalShifterOperand32 : LogicalShifterOperand<32>; 166def LogicalShifterOperand64 : LogicalShifterOperand<64>; 167 168// Shifter operand for logical vector 128/64-bit shifted encodings. 169def LogicalVecShifterOperand : AsmOperandClass { 170 let SuperClasses = [ShifterOperand]; 171 let Name = "LogicalVecShifter"; 172 let RenderMethod = "addShifterOperands"; 173} 174def LogicalVecHalfWordShifterOperand : AsmOperandClass { 175 let SuperClasses = [LogicalVecShifterOperand]; 176 let Name = "LogicalVecHalfWordShifter"; 177 let RenderMethod = "addShifterOperands"; 178} 179 180// The "MSL" shifter on the vector MOVI instruction. 181def MoveVecShifterOperand : AsmOperandClass { 182 let SuperClasses = [ShifterOperand]; 183 let Name = "MoveVecShifter"; 184 let RenderMethod = "addShifterOperands"; 185} 186 187// Extend operand for arithmetic encodings. 188def ExtendOperand : AsmOperandClass { 189 let Name = "Extend"; 190 let DiagnosticType = "AddSubRegExtendLarge"; 191} 192def ExtendOperand64 : AsmOperandClass { 193 let SuperClasses = [ExtendOperand]; 194 let Name = "Extend64"; 195 let DiagnosticType = "AddSubRegExtendSmall"; 196} 197// 'extend' that's a lsl of a 64-bit register. 198def ExtendOperandLSL64 : AsmOperandClass { 199 let SuperClasses = [ExtendOperand]; 200 let Name = "ExtendLSL64"; 201 let RenderMethod = "addExtend64Operands"; 202 let DiagnosticType = "AddSubRegExtendLarge"; 203} 204 205// 8-bit floating-point immediate encodings. 206def FPImmOperand : AsmOperandClass { 207 let Name = "FPImm"; 208 let ParserMethod = "tryParseFPImm<true>"; 209 let DiagnosticType = "InvalidFPImm"; 210} 211 212def CondCode : AsmOperandClass { 213 let Name = "CondCode"; 214 let DiagnosticType = "InvalidCondCode"; 215} 216 217// A 32-bit register pasrsed as 64-bit 218def GPR32as64Operand : AsmOperandClass { 219 let Name = "GPR32as64"; 220 let ParserMethod = 221 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 222} 223def GPR32as64 : RegisterOperand<GPR32> { 224 let ParserMatchClass = GPR32as64Operand; 225} 226 227// A 64-bit register pasrsed as 32-bit 228def GPR64as32Operand : AsmOperandClass { 229 let Name = "GPR64as32"; 230 let ParserMethod = 231 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 232} 233def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 234 let ParserMatchClass = GPR64as32Operand; 235} 236 237// 8-bit immediate for AdvSIMD where 64-bit values of the form: 238// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 239// are encoded as the eight bit value 'abcdefgh'. 240def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 241 242class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 243 let Name = "UImm" # Width # "s" # Scale; 244 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 245 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 246 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 247} 248 249class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 250 let Name = "SImm" # Width # "s" # Scale; 251 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 252 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 253 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 254} 255 256//===----------------------------------------------------------------------===// 257// Operand Definitions. 258// 259 260// ADR[P] instruction labels. 261def AdrpOperand : AsmOperandClass { 262 let Name = "AdrpLabel"; 263 let ParserMethod = "tryParseAdrpLabel"; 264 let DiagnosticType = "InvalidLabel"; 265} 266def adrplabel : Operand<i64> { 267 let EncoderMethod = "getAdrLabelOpValue"; 268 let PrintMethod = "printAdrpLabel"; 269 let ParserMatchClass = AdrpOperand; 270 let OperandType = "OPERAND_PCREL"; 271} 272 273def AdrOperand : AsmOperandClass { 274 let Name = "AdrLabel"; 275 let ParserMethod = "tryParseAdrLabel"; 276 let DiagnosticType = "InvalidLabel"; 277} 278def adrlabel : Operand<i64> { 279 let EncoderMethod = "getAdrLabelOpValue"; 280 let ParserMatchClass = AdrOperand; 281} 282 283class SImmOperand<int width> : AsmOperandClass { 284 let Name = "SImm" # width; 285 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 286 let RenderMethod = "addImmOperands"; 287 let PredicateMethod = "isSImm<" # width # ">"; 288} 289 290 291class AsmImmRange<int Low, int High> : AsmOperandClass { 292 let Name = "Imm" # Low # "_" # High; 293 let DiagnosticType = "InvalidImm" # Low # "_" # High; 294 let RenderMethod = "addImmOperands"; 295 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 296} 297 298// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 299def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 300def simm10Scaled : Operand<i64> { 301 let ParserMatchClass = SImm10s8Operand; 302 let DecoderMethod = "DecodeSImm<10>"; 303 let PrintMethod = "printImmScale<8>"; 304} 305 306def simm9s16 : Operand<i64> { 307 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 308 let DecoderMethod = "DecodeSImm<9>"; 309 let PrintMethod = "printImmScale<16>"; 310} 311 312// uimm6 predicate - True if the immediate is in the range [0, 63]. 313def UImm6Operand : AsmOperandClass { 314 let Name = "UImm6"; 315 let DiagnosticType = "InvalidImm0_63"; 316} 317 318def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 319 let ParserMatchClass = UImm6Operand; 320} 321 322def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 323 let ParserMatchClass = AsmImmRange<0, 65535>; 324} 325 326def SImm9Operand : SImmOperand<9>; 327def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 328 let ParserMatchClass = SImm9Operand; 329 let DecoderMethod = "DecodeSImm<9>"; 330} 331 332def SImm8Operand : SImmOperand<8>; 333def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> { 334 let ParserMatchClass = SImm8Operand; 335 let DecoderMethod = "DecodeSImm<8>"; 336} 337 338def SImm6Operand : SImmOperand<6>; 339def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 340 let ParserMatchClass = SImm6Operand; 341 let DecoderMethod = "DecodeSImm<6>"; 342} 343 344def SImm5Operand : SImmOperand<5>; 345def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 346 let ParserMatchClass = SImm5Operand; 347 let DecoderMethod = "DecodeSImm<5>"; 348} 349 350def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 351 let ParserMatchClass = SImm5Operand; 352 let DecoderMethod = "DecodeSImm<5>"; 353} 354 355def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 356 let ParserMatchClass = SImm5Operand; 357 let DecoderMethod = "DecodeSImm<5>"; 358 let PrintMethod = "printSImm<8>"; 359} 360 361def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 362 let ParserMatchClass = SImm5Operand; 363 let DecoderMethod = "DecodeSImm<5>"; 364 let PrintMethod = "printSImm<16>"; 365} 366 367// simm7sN predicate - True if the immediate is a multiple of N in the range 368// [-64 * N, 63 * N]. 369 370def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 371def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 372def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 373 374def simm7s4 : Operand<i32> { 375 let ParserMatchClass = SImm7s4Operand; 376 let PrintMethod = "printImmScale<4>"; 377} 378 379def simm7s8 : Operand<i32> { 380 let ParserMatchClass = SImm7s8Operand; 381 let PrintMethod = "printImmScale<8>"; 382} 383 384def simm7s16 : Operand<i32> { 385 let ParserMatchClass = SImm7s16Operand; 386 let PrintMethod = "printImmScale<16>"; 387} 388 389def am_sve_fi : ComplexPattern<i64, 2, "SelectAddrModeFrameIndexSVE", []>; 390 391def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>; 392def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>; 393def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>; 394def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>; 395def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>; 396 397def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>; 398def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>; 399 400def UImmS1XForm : SDNodeXForm<imm, [{ 401 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 402}]>; 403def UImmS2XForm : SDNodeXForm<imm, [{ 404 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 405}]>; 406def UImmS4XForm : SDNodeXForm<imm, [{ 407 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 408}]>; 409def UImmS8XForm : SDNodeXForm<imm, [{ 410 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 411}]>; 412 413// uimm5sN predicate - True if the immediate is a multiple of N in the range 414// [0 * N, 32 * N]. 415def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 416def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 417def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 418 419def uimm5s2 : Operand<i64>, ImmLeaf<i64, 420 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 421 UImmS2XForm> { 422 let ParserMatchClass = UImm5s2Operand; 423 let PrintMethod = "printImmScale<2>"; 424} 425def uimm5s4 : Operand<i64>, ImmLeaf<i64, 426 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 427 UImmS4XForm> { 428 let ParserMatchClass = UImm5s4Operand; 429 let PrintMethod = "printImmScale<4>"; 430} 431def uimm5s8 : Operand<i64>, ImmLeaf<i64, 432 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 433 UImmS8XForm> { 434 let ParserMatchClass = UImm5s8Operand; 435 let PrintMethod = "printImmScale<8>"; 436} 437 438// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 439// instead of ImmLeaf (Constant) 440def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 441 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 442 UImmS2XForm> { 443 let ParserMatchClass = UImm5s2Operand; 444 let PrintMethod = "printImmScale<2>"; 445} 446def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 447 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 448 UImmS4XForm> { 449 let ParserMatchClass = UImm5s4Operand; 450 let PrintMethod = "printImmScale<4>"; 451} 452def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 453 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 454 UImmS8XForm> { 455 let ParserMatchClass = UImm5s8Operand; 456 let PrintMethod = "printImmScale<8>"; 457} 458 459// uimm6sN predicate - True if the immediate is a multiple of N in the range 460// [0 * N, 64 * N]. 461def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 462def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 463def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 464def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 465def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 466 467def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 468 let ParserMatchClass = UImm6s1Operand; 469} 470def uimm6s2 : Operand<i64>, ImmLeaf<i64, 471[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 472 let PrintMethod = "printImmScale<2>"; 473 let ParserMatchClass = UImm6s2Operand; 474} 475def uimm6s4 : Operand<i64>, ImmLeaf<i64, 476[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 477 let PrintMethod = "printImmScale<4>"; 478 let ParserMatchClass = UImm6s4Operand; 479} 480def uimm6s8 : Operand<i64>, ImmLeaf<i64, 481[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 482 let PrintMethod = "printImmScale<8>"; 483 let ParserMatchClass = UImm6s8Operand; 484} 485def uimm6s16 : Operand<i64>, ImmLeaf<i64, 486[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 487 let PrintMethod = "printImmScale<16>"; 488 let ParserMatchClass = UImm6s16Operand; 489} 490 491def SImmS2XForm : SDNodeXForm<imm, [{ 492 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 493}]>; 494def SImmS3XForm : SDNodeXForm<imm, [{ 495 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 496}]>; 497def SImmS4XForm : SDNodeXForm<imm, [{ 498 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 499}]>; 500def SImmS16XForm : SDNodeXForm<imm, [{ 501 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 502}]>; 503def SImmS32XForm : SDNodeXForm<imm, [{ 504 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 505}]>; 506 507// simm6sN predicate - True if the immediate is a multiple of N in the range 508// [-32 * N, 31 * N]. 509def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 510def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 511 let ParserMatchClass = SImm6s1Operand; 512 let DecoderMethod = "DecodeSImm<6>"; 513} 514 515// simm4sN predicate - True if the immediate is a multiple of N in the range 516// [ -8* N, 7 * N]. 517def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 518def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 519def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 520def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 521def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 522def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 523 524def simm4s1 : Operand<i64>, ImmLeaf<i64, 525[{ return Imm >=-8 && Imm <= 7; }]> { 526 let ParserMatchClass = SImm4s1Operand; 527 let DecoderMethod = "DecodeSImm<4>"; 528} 529 530def simm4s2 : Operand<i64>, ImmLeaf<i64, 531[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 532 let PrintMethod = "printImmScale<2>"; 533 let ParserMatchClass = SImm4s2Operand; 534 let DecoderMethod = "DecodeSImm<4>"; 535} 536 537def simm4s3 : Operand<i64>, ImmLeaf<i64, 538[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 539 let PrintMethod = "printImmScale<3>"; 540 let ParserMatchClass = SImm4s3Operand; 541 let DecoderMethod = "DecodeSImm<4>"; 542} 543 544def simm4s4 : Operand<i64>, ImmLeaf<i64, 545[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 546 let PrintMethod = "printImmScale<4>"; 547 let ParserMatchClass = SImm4s4Operand; 548 let DecoderMethod = "DecodeSImm<4>"; 549} 550def simm4s16 : Operand<i64>, ImmLeaf<i64, 551[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 552 let PrintMethod = "printImmScale<16>"; 553 let ParserMatchClass = SImm4s16Operand; 554 let DecoderMethod = "DecodeSImm<4>"; 555} 556def simm4s32 : Operand<i64>, ImmLeaf<i64, 557[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 558 let PrintMethod = "printImmScale<32>"; 559 let ParserMatchClass = SImm4s32Operand; 560 let DecoderMethod = "DecodeSImm<4>"; 561} 562 563def Imm1_8Operand : AsmImmRange<1, 8>; 564def Imm1_16Operand : AsmImmRange<1, 16>; 565def Imm1_32Operand : AsmImmRange<1, 32>; 566def Imm1_64Operand : AsmImmRange<1, 64>; 567 568class BranchTarget<int N> : AsmOperandClass { 569 let Name = "BranchTarget" # N; 570 let DiagnosticType = "InvalidLabel"; 571 let PredicateMethod = "isBranchTarget<" # N # ">"; 572} 573 574class PCRelLabel<int N> : BranchTarget<N> { 575 let Name = "PCRelLabel" # N; 576} 577 578def BranchTarget14Operand : BranchTarget<14>; 579def BranchTarget26Operand : BranchTarget<26>; 580def PCRelLabel19Operand : PCRelLabel<19>; 581 582def MovWSymbolG3AsmOperand : AsmOperandClass { 583 let Name = "MovWSymbolG3"; 584 let RenderMethod = "addImmOperands"; 585} 586 587def movw_symbol_g3 : Operand<i32> { 588 let ParserMatchClass = MovWSymbolG3AsmOperand; 589} 590 591def MovWSymbolG2AsmOperand : AsmOperandClass { 592 let Name = "MovWSymbolG2"; 593 let RenderMethod = "addImmOperands"; 594} 595 596def movw_symbol_g2 : Operand<i32> { 597 let ParserMatchClass = MovWSymbolG2AsmOperand; 598} 599 600def MovWSymbolG1AsmOperand : AsmOperandClass { 601 let Name = "MovWSymbolG1"; 602 let RenderMethod = "addImmOperands"; 603} 604 605def movw_symbol_g1 : Operand<i32> { 606 let ParserMatchClass = MovWSymbolG1AsmOperand; 607} 608 609def MovWSymbolG0AsmOperand : AsmOperandClass { 610 let Name = "MovWSymbolG0"; 611 let RenderMethod = "addImmOperands"; 612} 613 614def movw_symbol_g0 : Operand<i32> { 615 let ParserMatchClass = MovWSymbolG0AsmOperand; 616} 617 618class fixedpoint_i32<ValueType FloatVT> 619 : Operand<FloatVT>, 620 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 621 let EncoderMethod = "getFixedPointScaleOpValue"; 622 let DecoderMethod = "DecodeFixedPointScaleImm32"; 623 let ParserMatchClass = Imm1_32Operand; 624} 625 626class fixedpoint_i64<ValueType FloatVT> 627 : Operand<FloatVT>, 628 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 629 let EncoderMethod = "getFixedPointScaleOpValue"; 630 let DecoderMethod = "DecodeFixedPointScaleImm64"; 631 let ParserMatchClass = Imm1_64Operand; 632} 633 634def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 635def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 636def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 637 638def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 639def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 640def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 641 642def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 643 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 644}]> { 645 let EncoderMethod = "getVecShiftR8OpValue"; 646 let DecoderMethod = "DecodeVecShiftR8Imm"; 647 let ParserMatchClass = Imm1_8Operand; 648} 649def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 650 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 651}]> { 652 let EncoderMethod = "getVecShiftR16OpValue"; 653 let DecoderMethod = "DecodeVecShiftR16Imm"; 654 let ParserMatchClass = Imm1_16Operand; 655} 656def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 657 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 658}]> { 659 let EncoderMethod = "getVecShiftR16OpValue"; 660 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 661 let ParserMatchClass = Imm1_8Operand; 662} 663def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 664 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 665}]> { 666 let EncoderMethod = "getVecShiftR32OpValue"; 667 let DecoderMethod = "DecodeVecShiftR32Imm"; 668 let ParserMatchClass = Imm1_32Operand; 669} 670def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 671 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 672}]> { 673 let EncoderMethod = "getVecShiftR32OpValue"; 674 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 675 let ParserMatchClass = Imm1_16Operand; 676} 677def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 678 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 679}]> { 680 let EncoderMethod = "getVecShiftR64OpValue"; 681 let DecoderMethod = "DecodeVecShiftR64Imm"; 682 let ParserMatchClass = Imm1_64Operand; 683} 684def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 685 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 686}]> { 687 let EncoderMethod = "getVecShiftR64OpValue"; 688 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 689 let ParserMatchClass = Imm1_32Operand; 690} 691 692// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 693// (ImmLeaf) 694def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 695 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 696}]> { 697 let EncoderMethod = "getVecShiftR8OpValue"; 698 let DecoderMethod = "DecodeVecShiftR8Imm"; 699 let ParserMatchClass = Imm1_8Operand; 700} 701def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 702 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 703}]> { 704 let EncoderMethod = "getVecShiftR16OpValue"; 705 let DecoderMethod = "DecodeVecShiftR16Imm"; 706 let ParserMatchClass = Imm1_16Operand; 707} 708def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 709 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 710}]> { 711 let EncoderMethod = "getVecShiftR32OpValue"; 712 let DecoderMethod = "DecodeVecShiftR32Imm"; 713 let ParserMatchClass = Imm1_32Operand; 714} 715def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 716 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 717}]> { 718 let EncoderMethod = "getVecShiftR64OpValue"; 719 let DecoderMethod = "DecodeVecShiftR64Imm"; 720 let ParserMatchClass = Imm1_64Operand; 721} 722 723def Imm0_1Operand : AsmImmRange<0, 1>; 724def Imm0_7Operand : AsmImmRange<0, 7>; 725def Imm0_15Operand : AsmImmRange<0, 15>; 726def Imm0_31Operand : AsmImmRange<0, 31>; 727def Imm0_63Operand : AsmImmRange<0, 63>; 728 729def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 730 return (((uint32_t)Imm) < 8); 731}]> { 732 let EncoderMethod = "getVecShiftL8OpValue"; 733 let DecoderMethod = "DecodeVecShiftL8Imm"; 734 let ParserMatchClass = Imm0_7Operand; 735} 736def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 737 return (((uint32_t)Imm) < 16); 738}]> { 739 let EncoderMethod = "getVecShiftL16OpValue"; 740 let DecoderMethod = "DecodeVecShiftL16Imm"; 741 let ParserMatchClass = Imm0_15Operand; 742} 743def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 744 return (((uint32_t)Imm) < 32); 745}]> { 746 let EncoderMethod = "getVecShiftL32OpValue"; 747 let DecoderMethod = "DecodeVecShiftL32Imm"; 748 let ParserMatchClass = Imm0_31Operand; 749} 750def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 751 return (((uint32_t)Imm) < 64); 752}]> { 753 let EncoderMethod = "getVecShiftL64OpValue"; 754 let DecoderMethod = "DecodeVecShiftL64Imm"; 755 let ParserMatchClass = Imm0_63Operand; 756} 757 758// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 759// (ImmLeaf) 760def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 761 return (((uint32_t)Imm) < 8); 762}]> { 763 let EncoderMethod = "getVecShiftL8OpValue"; 764 let DecoderMethod = "DecodeVecShiftL8Imm"; 765 let ParserMatchClass = Imm0_7Operand; 766} 767def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 768 return (((uint32_t)Imm) < 16); 769}]> { 770 let EncoderMethod = "getVecShiftL16OpValue"; 771 let DecoderMethod = "DecodeVecShiftL16Imm"; 772 let ParserMatchClass = Imm0_15Operand; 773} 774def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 775 return (((uint32_t)Imm) < 32); 776}]> { 777 let EncoderMethod = "getVecShiftL32OpValue"; 778 let DecoderMethod = "DecodeVecShiftL32Imm"; 779 let ParserMatchClass = Imm0_31Operand; 780} 781def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 782 return (((uint32_t)Imm) < 64); 783}]> { 784 let EncoderMethod = "getVecShiftL64OpValue"; 785 let DecoderMethod = "DecodeVecShiftL64Imm"; 786 let ParserMatchClass = Imm0_63Operand; 787} 788 789// Crazy immediate formats used by 32-bit and 64-bit logical immediate 790// instructions for splatting repeating bit patterns across the immediate. 791def logical_imm32_XFORM : SDNodeXForm<imm, [{ 792 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 793 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 794}]>; 795def logical_imm64_XFORM : SDNodeXForm<imm, [{ 796 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 797 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 798}]>; 799 800def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 801 GISDNodeXFormEquiv<logical_imm32_XFORM>; 802def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 803 GISDNodeXFormEquiv<logical_imm64_XFORM>; 804 805let DiagnosticType = "LogicalSecondSource" in { 806 def LogicalImm32Operand : AsmOperandClass { 807 let Name = "LogicalImm32"; 808 let PredicateMethod = "isLogicalImm<int32_t>"; 809 let RenderMethod = "addLogicalImmOperands<int32_t>"; 810 } 811 def LogicalImm64Operand : AsmOperandClass { 812 let Name = "LogicalImm64"; 813 let PredicateMethod = "isLogicalImm<int64_t>"; 814 let RenderMethod = "addLogicalImmOperands<int64_t>"; 815 } 816 def LogicalImm32NotOperand : AsmOperandClass { 817 let Name = "LogicalImm32Not"; 818 let PredicateMethod = "isLogicalImm<int32_t>"; 819 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 820 } 821 def LogicalImm64NotOperand : AsmOperandClass { 822 let Name = "LogicalImm64Not"; 823 let PredicateMethod = "isLogicalImm<int64_t>"; 824 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 825 } 826} 827def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 828 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 829}], logical_imm32_XFORM> { 830 let PrintMethod = "printLogicalImm<int32_t>"; 831 let ParserMatchClass = LogicalImm32Operand; 832} 833def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 834 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 835}], logical_imm64_XFORM> { 836 let PrintMethod = "printLogicalImm<int64_t>"; 837 let ParserMatchClass = LogicalImm64Operand; 838} 839def logical_imm32_not : Operand<i32> { 840 let ParserMatchClass = LogicalImm32NotOperand; 841} 842def logical_imm64_not : Operand<i64> { 843 let ParserMatchClass = LogicalImm64NotOperand; 844} 845 846// iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535]. 847let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 848def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{ 849 return ((uint32_t)Imm) < 65536; 850}]>; 851 852def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{ 853 return ((uint64_t)Imm) < 65536; 854}]>; 855} 856 857// imm0_255 predicate - True if the immediate is in the range [0,255]. 858def Imm0_255Operand : AsmImmRange<0,255>; 859 860def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 861 return ((uint32_t)Imm) < 256; 862}]> { 863 let ParserMatchClass = Imm0_255Operand; 864 let PrintMethod = "printImm"; 865} 866 867// imm0_127 predicate - True if the immediate is in the range [0,127] 868def Imm0_127Operand : AsmImmRange<0, 127>; 869def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 870 return ((uint32_t)Imm) < 128; 871}]> { 872 let ParserMatchClass = Imm0_127Operand; 873 let PrintMethod = "printImm"; 874} 875 876def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 877 return ((uint64_t)Imm) < 128; 878}]> { 879 let ParserMatchClass = Imm0_127Operand; 880 let PrintMethod = "printImm"; 881} 882 883// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 884// for all shift-amounts. 885 886// imm0_63 predicate - True if the immediate is in the range [0,63] 887def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 888 return ((uint64_t)Imm) < 64; 889}]> { 890 let ParserMatchClass = Imm0_63Operand; 891} 892 893def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 894 return ((uint64_t)Imm) < 64; 895}]> { 896 let ParserMatchClass = Imm0_63Operand; 897} 898 899// imm0_31 predicate - True if the immediate is in the range [0,31] 900def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 901 return ((uint64_t)Imm) < 32; 902}]> { 903 let ParserMatchClass = Imm0_31Operand; 904} 905 906// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 907// instead of Constant (ImmLeaf) 908def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 909 return ((uint64_t)Imm) < 32; 910}]> { 911 let ParserMatchClass = Imm0_31Operand; 912} 913 914// True if the 32-bit immediate is in the range [0,31] 915def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 916 return ((uint64_t)Imm) < 32; 917}]> { 918 let ParserMatchClass = Imm0_31Operand; 919} 920 921// imm0_1 predicate - True if the immediate is in the range [0,1] 922def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 923 return ((uint64_t)Imm) < 2; 924}]> { 925 let ParserMatchClass = Imm0_1Operand; 926} 927 928// timm0_1 - as above, but use TargetConstant (TImmLeaf) 929def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 930 return ((uint64_t)Imm) < 2; 931}]> { 932 let ParserMatchClass = Imm0_1Operand; 933} 934 935// imm0_15 predicate - True if the immediate is in the range [0,15] 936def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 937 return ((uint64_t)Imm) < 16; 938}]> { 939 let ParserMatchClass = Imm0_15Operand; 940} 941 942// imm0_7 predicate - True if the immediate is in the range [0,7] 943def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 944 return ((uint64_t)Imm) < 8; 945}]> { 946 let ParserMatchClass = Imm0_7Operand; 947} 948 949// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 950def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 951 return ((uint32_t)Imm) < 8; 952}]> { 953 let ParserMatchClass = Imm0_7Operand; 954} 955 956// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 957def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 958 return ((uint32_t)Imm) < 16; 959}]> { 960 let ParserMatchClass = Imm0_15Operand; 961} 962 963// An arithmetic shifter operand: 964// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 965// {5-0} - imm6 966class arith_shift<ValueType Ty, int width> : Operand<Ty> { 967 let PrintMethod = "printShifter"; 968 let ParserMatchClass = !cast<AsmOperandClass>( 969 "ArithmeticShifterOperand" # width); 970} 971 972def arith_shift32 : arith_shift<i32, 32>; 973def arith_shift64 : arith_shift<i64, 64>; 974 975class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 976 : Operand<Ty>, 977 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 978 let PrintMethod = "printShiftedRegister"; 979 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 980} 981 982def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 983def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 984 985def gi_arith_shifted_reg32 : 986 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 987 GIComplexPatternEquiv<arith_shifted_reg32>; 988 989def gi_arith_shifted_reg64 : 990 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 991 GIComplexPatternEquiv<arith_shifted_reg64>; 992 993// An arithmetic shifter operand: 994// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 995// {5-0} - imm6 996class logical_shift<int width> : Operand<i32> { 997 let PrintMethod = "printShifter"; 998 let ParserMatchClass = !cast<AsmOperandClass>( 999 "LogicalShifterOperand" # width); 1000} 1001 1002def logical_shift32 : logical_shift<32>; 1003def logical_shift64 : logical_shift<64>; 1004 1005class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1006 : Operand<Ty>, 1007 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1008 let PrintMethod = "printShiftedRegister"; 1009 let MIOperandInfo = (ops regclass, shiftop); 1010} 1011 1012def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1013def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1014 1015def gi_logical_shifted_reg32 : 1016 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1017 GIComplexPatternEquiv<logical_shifted_reg32>; 1018 1019def gi_logical_shifted_reg64 : 1020 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1021 GIComplexPatternEquiv<logical_shifted_reg64>; 1022 1023// A logical vector shifter operand: 1024// {7-6} - shift type: 00 = lsl 1025// {5-0} - imm6: #0, #8, #16, or #24 1026def logical_vec_shift : Operand<i32> { 1027 let PrintMethod = "printShifter"; 1028 let EncoderMethod = "getVecShifterOpValue"; 1029 let ParserMatchClass = LogicalVecShifterOperand; 1030} 1031 1032// A logical vector half-word shifter operand: 1033// {7-6} - shift type: 00 = lsl 1034// {5-0} - imm6: #0 or #8 1035def logical_vec_hw_shift : Operand<i32> { 1036 let PrintMethod = "printShifter"; 1037 let EncoderMethod = "getVecShifterOpValue"; 1038 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1039} 1040 1041// A vector move shifter operand: 1042// {0} - imm1: #8 or #16 1043def move_vec_shift : Operand<i32> { 1044 let PrintMethod = "printShifter"; 1045 let EncoderMethod = "getMoveVecShifterOpValue"; 1046 let ParserMatchClass = MoveVecShifterOperand; 1047} 1048 1049let DiagnosticType = "AddSubSecondSource" in { 1050 def AddSubImmOperand : AsmOperandClass { 1051 let Name = "AddSubImm"; 1052 let ParserMethod = "tryParseImmWithOptionalShift"; 1053 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1054 } 1055 def AddSubImmNegOperand : AsmOperandClass { 1056 let Name = "AddSubImmNeg"; 1057 let ParserMethod = "tryParseImmWithOptionalShift"; 1058 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1059 } 1060} 1061// An ADD/SUB immediate shifter operand: 1062// second operand: 1063// {7-6} - shift type: 00 = lsl 1064// {5-0} - imm6: #0 or #12 1065class addsub_shifted_imm<ValueType Ty> 1066 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1067 let PrintMethod = "printAddSubImm"; 1068 let EncoderMethod = "getAddSubImmOpValue"; 1069 let ParserMatchClass = AddSubImmOperand; 1070 let MIOperandInfo = (ops i32imm, i32imm); 1071} 1072 1073class addsub_shifted_imm_neg<ValueType Ty> 1074 : Operand<Ty> { 1075 let EncoderMethod = "getAddSubImmOpValue"; 1076 let ParserMatchClass = AddSubImmNegOperand; 1077 let MIOperandInfo = (ops i32imm, i32imm); 1078} 1079 1080def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1081def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1082def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1083def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1084 1085def gi_addsub_shifted_imm32 : 1086 GIComplexOperandMatcher<s32, "selectArithImmed">, 1087 GIComplexPatternEquiv<addsub_shifted_imm32>; 1088 1089def gi_addsub_shifted_imm64 : 1090 GIComplexOperandMatcher<s64, "selectArithImmed">, 1091 GIComplexPatternEquiv<addsub_shifted_imm64>; 1092 1093class neg_addsub_shifted_imm<ValueType Ty> 1094 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1095 let PrintMethod = "printAddSubImm"; 1096 let EncoderMethod = "getAddSubImmOpValue"; 1097 let ParserMatchClass = AddSubImmOperand; 1098 let MIOperandInfo = (ops i32imm, i32imm); 1099} 1100 1101def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1102def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1103 1104def gi_neg_addsub_shifted_imm32 : 1105 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1106 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1107 1108def gi_neg_addsub_shifted_imm64 : 1109 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1110 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1111 1112// An extend operand: 1113// {5-3} - extend type 1114// {2-0} - imm3 1115def arith_extend : Operand<i32> { 1116 let PrintMethod = "printArithExtend"; 1117 let ParserMatchClass = ExtendOperand; 1118} 1119def arith_extend64 : Operand<i32> { 1120 let PrintMethod = "printArithExtend"; 1121 let ParserMatchClass = ExtendOperand64; 1122} 1123 1124// 'extend' that's a lsl of a 64-bit register. 1125def arith_extendlsl64 : Operand<i32> { 1126 let PrintMethod = "printArithExtend"; 1127 let ParserMatchClass = ExtendOperandLSL64; 1128} 1129 1130class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1131 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1132 let PrintMethod = "printExtendedRegister"; 1133 let MIOperandInfo = (ops GPR32, arith_extend); 1134} 1135 1136class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1137 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1138 let PrintMethod = "printExtendedRegister"; 1139 let MIOperandInfo = (ops GPR32, arith_extend64); 1140} 1141 1142def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1143def gi_arith_extended_reg32_i32 : 1144 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1145 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1146 1147def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1148def gi_arith_extended_reg32_i64 : 1149 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1150 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1151 1152def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1153def gi_arith_extended_reg32to64_i64 : 1154 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1155 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1156 1157// Floating-point immediate. 1158 1159def fpimm16XForm : SDNodeXForm<fpimm, [{ 1160 APFloat InVal = N->getValueAPF(); 1161 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1162 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1163 }]>; 1164 1165def fpimm32XForm : SDNodeXForm<fpimm, [{ 1166 APFloat InVal = N->getValueAPF(); 1167 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1168 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1169 }]>; 1170 1171def fpimm64XForm : SDNodeXForm<fpimm, [{ 1172 APFloat InVal = N->getValueAPF(); 1173 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1174 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1175 }]>; 1176 1177def fpimm16 : Operand<f16>, 1178 FPImmLeaf<f16, [{ 1179 return AArch64_AM::getFP16Imm(Imm) != -1; 1180 }], fpimm16XForm> { 1181 let ParserMatchClass = FPImmOperand; 1182 let PrintMethod = "printFPImmOperand"; 1183} 1184 1185def fpimm32 : Operand<f32>, 1186 FPImmLeaf<f32, [{ 1187 return AArch64_AM::getFP32Imm(Imm) != -1; 1188 }], fpimm32XForm> { 1189 let ParserMatchClass = FPImmOperand; 1190 let PrintMethod = "printFPImmOperand"; 1191} 1192def fpimm64 : Operand<f64>, 1193 FPImmLeaf<f64, [{ 1194 return AArch64_AM::getFP64Imm(Imm) != -1; 1195 }], fpimm64XForm> { 1196 let ParserMatchClass = FPImmOperand; 1197 let PrintMethod = "printFPImmOperand"; 1198} 1199 1200def fpimm8 : Operand<i32> { 1201 let ParserMatchClass = FPImmOperand; 1202 let PrintMethod = "printFPImmOperand"; 1203} 1204 1205def fpimm0 : FPImmLeaf<fAny, [{ 1206 return Imm.isExactlyValue(+0.0); 1207}]>; 1208 1209def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1210 GISDNodeXFormEquiv<fpimm16XForm>; 1211def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1212 GISDNodeXFormEquiv<fpimm32XForm>; 1213def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1214 GISDNodeXFormEquiv<fpimm64XForm>; 1215 1216// Vector lane operands 1217class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1218 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1219 let DiagnosticType = "Invalid" # Name; 1220 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1221 let RenderMethod = "addVectorIndexOperands"; 1222} 1223 1224class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1225 : Operand<ty> { 1226 let ParserMatchClass = mc; 1227 let PrintMethod = "printVectorIndex"; 1228} 1229 1230multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1231 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1232 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1233} 1234 1235def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1236def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1237def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1238def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1239def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1240 1241defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1242 [{ return ((uint64_t)Imm) == 1; }]>; 1243defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1244 [{ return ((uint64_t)Imm) < 16; }]>; 1245defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1246 [{ return ((uint64_t)Imm) < 8; }]>; 1247defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1248 [{ return ((uint64_t)Imm) < 4; }]>; 1249defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1250 [{ return ((uint64_t)Imm) < 2; }]>; 1251 1252defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1253 [{ return ((uint64_t)Imm) == 1; }]>; 1254defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1255 [{ return ((uint64_t)Imm) < 16; }]>; 1256defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1257 [{ return ((uint64_t)Imm) < 8; }]>; 1258defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1259 [{ return ((uint64_t)Imm) < 4; }]>; 1260defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1261 [{ return ((uint64_t)Imm) < 2; }]>; 1262 1263def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1264def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1265def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1266def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1267def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1268 1269defm sve_elm_idx_extdup_b 1270 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1271 [{ return ((uint64_t)Imm) < 64; }]>; 1272defm sve_elm_idx_extdup_h 1273 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1274 [{ return ((uint64_t)Imm) < 32; }]>; 1275defm sve_elm_idx_extdup_s 1276 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1277 [{ return ((uint64_t)Imm) < 16; }]>; 1278defm sve_elm_idx_extdup_d 1279 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1280 [{ return ((uint64_t)Imm) < 8; }]>; 1281defm sve_elm_idx_extdup_q 1282 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1283 [{ return ((uint64_t)Imm) < 4; }]>; 1284 1285// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1286// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1287// are encoded as the eight bit value 'abcdefgh'. 1288def simdimmtype10 : Operand<i32>, 1289 FPImmLeaf<f64, [{ 1290 return AArch64_AM::isAdvSIMDModImmType10( 1291 Imm.bitcastToAPInt().getZExtValue()); 1292 }], SDNodeXForm<fpimm, [{ 1293 APFloat InVal = N->getValueAPF(); 1294 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1295 .bitcastToAPInt() 1296 .getZExtValue()); 1297 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1298 }]>> { 1299 let ParserMatchClass = SIMDImmType10Operand; 1300 let PrintMethod = "printSIMDType10Operand"; 1301} 1302 1303 1304//--- 1305// System management 1306//--- 1307 1308// Base encoding for system instruction operands. 1309let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1310class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1311 list<dag> pattern = []> 1312 : I<oops, iops, asm, operands, "", pattern> { 1313 let Inst{31-22} = 0b1101010100; 1314 let Inst{21} = L; 1315} 1316 1317// System instructions which do not have an Rt register. 1318class SimpleSystemI<bit L, dag iops, string asm, string operands, 1319 list<dag> pattern = []> 1320 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1321 let Inst{4-0} = 0b11111; 1322} 1323 1324// System instructions which have an Rt register. 1325class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1326 list<dag> pattern = []> 1327 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1328 Sched<[WriteSys]> { 1329 bits<5> Rt; 1330 let Inst{4-0} = Rt; 1331} 1332 1333// System instructions for transactional memory extension 1334class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1335 string asm, string operands, list<dag> pattern> 1336 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1337 Sched<[WriteSys]> { 1338 let Inst{20-12} = 0b000110011; 1339 let Inst{11-8} = CRm; 1340 let Inst{7-5} = op2; 1341 let DecoderMethod = ""; 1342 1343 let mayLoad = 1; 1344 let mayStore = 1; 1345} 1346 1347// System instructions for transactional memory - single input operand 1348class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1349 : TMBaseSystemI<0b1, CRm, 0b011, 1350 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1351 bits<5> Rt; 1352 let Inst{4-0} = Rt; 1353} 1354 1355// System instructions that pass a register argument 1356// This class assumes the register is for input rather than output. 1357class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1358 list<dag> pattern = []> 1359 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1360 let Inst{20-12} = 0b000110001; 1361 let Inst{11-8} = CRm; 1362 let Inst{7-5} = Op2; 1363} 1364 1365// System instructions for transactional memory - no operand 1366class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1367 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1368 let Inst{4-0} = 0b11111; 1369} 1370 1371// System instructions for exit from transactions 1372class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1373 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>, 1374 Sched<[WriteSys]> { 1375 bits<16> imm; 1376 let Inst{31-24} = 0b11010100; 1377 let Inst{23-21} = op1; 1378 let Inst{20-5} = imm; 1379 let Inst{4-0} = 0b00000; 1380} 1381 1382// Hint instructions that take both a CRm and a 3-bit immediate. 1383// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1384// model patterns with sufficiently fine granularity 1385let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1386 class HintI<string mnemonic> 1387 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1388 [(int_aarch64_hint imm0_127:$imm)]>, 1389 Sched<[WriteHint]> { 1390 bits <7> imm; 1391 let Inst{20-12} = 0b000110010; 1392 let Inst{11-5} = imm; 1393 } 1394 1395// System instructions taking a single literal operand which encodes into 1396// CRm. op2 differentiates the opcodes. 1397def BarrierAsmOperand : AsmOperandClass { 1398 let Name = "Barrier"; 1399 let ParserMethod = "tryParseBarrierOperand"; 1400} 1401def barrier_op : Operand<i32> { 1402 let PrintMethod = "printBarrierOption"; 1403 let ParserMatchClass = BarrierAsmOperand; 1404} 1405def BarriernXSAsmOperand : AsmOperandClass { 1406 let Name = "BarriernXS"; 1407 let ParserMethod = "tryParseBarriernXSOperand"; 1408} 1409def barrier_nxs_op : Operand<i32> { 1410 let PrintMethod = "printBarriernXSOption"; 1411 let ParserMatchClass = BarriernXSAsmOperand; 1412} 1413class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1414 list<dag> pattern = []> 1415 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1416 Sched<[WriteBarrier]> { 1417 bits<4> CRm; 1418 let Inst{20-12} = 0b000110011; 1419 let Inst{11-8} = CRm; 1420 let Inst{7-5} = opc; 1421} 1422 1423class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1424 : SimpleSystemI<0, (ins), asm, "", pattern>, 1425 Sched<[]> { 1426 bits<4> CRm; 1427 let CRm = 0b0011; 1428 let Inst{31-12} = 0b11010101000000110010; 1429 let Inst{11-8} = CRm; 1430 let Inst{7-5} = op2; 1431 let Inst{4-0} = 0b11111; 1432} 1433 1434// MRS/MSR system instructions. These have different operand classes because 1435// a different subset of registers can be accessed through each instruction. 1436def MRSSystemRegisterOperand : AsmOperandClass { 1437 let Name = "MRSSystemRegister"; 1438 let ParserMethod = "tryParseSysReg"; 1439 let DiagnosticType = "MRS"; 1440} 1441// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1442def mrs_sysreg_op : Operand<i32> { 1443 let ParserMatchClass = MRSSystemRegisterOperand; 1444 let DecoderMethod = "DecodeMRSSystemRegister"; 1445 let PrintMethod = "printMRSSystemRegister"; 1446} 1447 1448def MSRSystemRegisterOperand : AsmOperandClass { 1449 let Name = "MSRSystemRegister"; 1450 let ParserMethod = "tryParseSysReg"; 1451 let DiagnosticType = "MSR"; 1452} 1453def msr_sysreg_op : Operand<i32> { 1454 let ParserMatchClass = MSRSystemRegisterOperand; 1455 let DecoderMethod = "DecodeMSRSystemRegister"; 1456 let PrintMethod = "printMSRSystemRegister"; 1457} 1458 1459def PSBHintOperand : AsmOperandClass { 1460 let Name = "PSBHint"; 1461 let ParserMethod = "tryParsePSBHint"; 1462} 1463def psbhint_op : Operand<i32> { 1464 let ParserMatchClass = PSBHintOperand; 1465 let PrintMethod = "printPSBHintOp"; 1466 let MCOperandPredicate = [{ 1467 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1468 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1469 if (!MCOp.isImm()) 1470 return false; 1471 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1472 }]; 1473} 1474 1475def BTIHintOperand : AsmOperandClass { 1476 let Name = "BTIHint"; 1477 let ParserMethod = "tryParseBTIHint"; 1478} 1479def btihint_op : Operand<i32> { 1480 let ParserMatchClass = BTIHintOperand; 1481 let PrintMethod = "printBTIHintOp"; 1482 let MCOperandPredicate = [{ 1483 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1484 if (!MCOp.isImm()) 1485 return false; 1486 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1487 }]; 1488} 1489 1490class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1491 "mrs", "\t$Rt, $systemreg"> { 1492 bits<16> systemreg; 1493 let Inst{20-5} = systemreg; 1494 let DecoderNamespace = "Fallback"; 1495 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1496 // require doing this. The alternative was to explicitly model each one, but 1497 // it feels like it is unnecessary because it seems there are no negative 1498 // consequences setting these flags for all. 1499 let Defs = [NZCV]; 1500} 1501 1502// FIXME: Some of these def NZCV, others don't. Best way to model that? 1503// Explicitly modeling each of the system register as a register class 1504// would do it, but feels like overkill at this point. 1505class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1506 "msr", "\t$systemreg, $Rt"> { 1507 bits<16> systemreg; 1508 let Inst{20-5} = systemreg; 1509 let DecoderNamespace = "Fallback"; 1510} 1511 1512def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1513 let Name = "SystemPStateFieldWithImm0_15"; 1514 let ParserMethod = "tryParseSysReg"; 1515} 1516def pstatefield4_op : Operand<i32> { 1517 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1518 let PrintMethod = "printSystemPStateField"; 1519} 1520 1521// Instructions to modify PSTATE, no input reg 1522let Defs = [NZCV] in 1523class PstateWriteSimple<dag iops, string asm, string operands> 1524 : SimpleSystemI<0, iops, asm, operands> { 1525 1526 let Inst{20-19} = 0b00; 1527 let Inst{15-12} = 0b0100; 1528} 1529 1530class MSRpstateImm0_15 1531 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1532 "\t$pstatefield, $imm">, 1533 Sched<[WriteSys]> { 1534 1535 bits<6> pstatefield; 1536 bits<4> imm; 1537 let Inst{18-16} = pstatefield{5-3}; 1538 let Inst{11-8} = imm; 1539 let Inst{7-5} = pstatefield{2-0}; 1540 1541 let DecoderMethod = "DecodeSystemPStateInstruction"; 1542 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1543 // Fail the decoder should attempt to decode the instruction as MSRI. 1544 let hasCompleteDecoder = 0; 1545} 1546 1547def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1548 let Name = "SystemPStateFieldWithImm0_1"; 1549 let ParserMethod = "tryParseSysReg"; 1550} 1551def pstatefield1_op : Operand<i32> { 1552 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1553 let PrintMethod = "printSystemPStateField"; 1554} 1555 1556class MSRpstateImm0_1 1557 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1558 "\t$pstatefield, $imm">, 1559 Sched<[WriteSys]> { 1560 1561 bits<6> pstatefield; 1562 bit imm; 1563 let Inst{18-16} = pstatefield{5-3}; 1564 let Inst{11-9} = 0b000; 1565 let Inst{8} = imm; 1566 let Inst{7-5} = pstatefield{2-0}; 1567 1568 let DecoderMethod = "DecodeSystemPStateInstruction"; 1569 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1570 // Fail the decoder should attempt to decode the instruction as MSRI. 1571 let hasCompleteDecoder = 0; 1572} 1573 1574// SYS and SYSL generic system instructions. 1575def SysCRAsmOperand : AsmOperandClass { 1576 let Name = "SysCR"; 1577 let ParserMethod = "tryParseSysCROperand"; 1578} 1579 1580def sys_cr_op : Operand<i32> { 1581 let PrintMethod = "printSysCROperand"; 1582 let ParserMatchClass = SysCRAsmOperand; 1583} 1584 1585class SystemXtI<bit L, string asm> 1586 : RtSystemI<L, (outs), 1587 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1588 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1589 bits<3> op1; 1590 bits<4> Cn; 1591 bits<4> Cm; 1592 bits<3> op2; 1593 let Inst{20-19} = 0b01; 1594 let Inst{18-16} = op1; 1595 let Inst{15-12} = Cn; 1596 let Inst{11-8} = Cm; 1597 let Inst{7-5} = op2; 1598} 1599 1600class SystemLXtI<bit L, string asm> 1601 : RtSystemI<L, (outs), 1602 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1603 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1604 bits<3> op1; 1605 bits<4> Cn; 1606 bits<4> Cm; 1607 bits<3> op2; 1608 let Inst{20-19} = 0b01; 1609 let Inst{18-16} = op1; 1610 let Inst{15-12} = Cn; 1611 let Inst{11-8} = Cm; 1612 let Inst{7-5} = op2; 1613} 1614 1615 1616// Branch (register) instructions: 1617// 1618// case opc of 1619// 0001 blr 1620// 0000 br 1621// 0101 dret 1622// 0100 eret 1623// 0010 ret 1624// otherwise UNDEFINED 1625class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1626 string operands, list<dag> pattern> 1627 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1628 let Inst{31-25} = 0b1101011; 1629 let Inst{24-21} = opc; 1630 let Inst{20-16} = 0b11111; 1631 let Inst{15-10} = 0b000000; 1632 let Inst{4-0} = 0b00000; 1633} 1634 1635class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1636 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1637 bits<5> Rn; 1638 let Inst{9-5} = Rn; 1639} 1640 1641let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1642class SpecialReturn<bits<4> opc, string asm> 1643 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1644 let Inst{9-5} = 0b11111; 1645} 1646 1647let mayLoad = 1 in 1648class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1649 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1650 Sched<[]> { 1651 bits<5> Rn; 1652 bits<5> Rt; 1653 let Inst{31-30} = sz; 1654 let Inst{29-10} = 0b11100010111111110000; 1655 let Inst{9-5} = Rn; 1656 let Inst{4-0} = Rt; 1657} 1658 1659class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1660 list<dag> pattern> 1661 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1662 let isAuthenticated = 1; 1663 let Inst{31-25} = 0b1101011; 1664 let Inst{20-11} = 0b1111100001; 1665 let Inst{10} = M; 1666 let Inst{4-0} = 0b11111; 1667} 1668 1669class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1670 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1671 bits<5> Rn; 1672 bits<5> Rm; 1673 let Inst{24-22} = 0b100; 1674 let Inst{21} = op; 1675 let Inst{9-5} = Rn; 1676 let Inst{4-0} = Rm; 1677} 1678 1679class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1680 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1681 bits<5> Rn; 1682 let Inst{24} = 0; 1683 let Inst{23-21} = opc; 1684 let Inst{9-5} = Rn; 1685} 1686 1687let Uses = [LR,SP] in 1688class AuthReturn<bits<3> op, bits<1> M, string asm> 1689 : AuthBase<M, (outs), (ins), asm, "", []> { 1690 let Inst{24} = 0; 1691 let Inst{23-21} = op; 1692 let Inst{9-0} = 0b1111111111; 1693} 1694 1695let mayLoad = 1 in 1696class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1697 string operands, string cstr, Operand opr> 1698 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1699 bits<10> offset; 1700 bits<5> Rn; 1701 bits<5> Rt; 1702 let isAuthenticated = 1; 1703 let Inst{31-24} = 0b11111000; 1704 let Inst{23} = M; 1705 let Inst{22} = offset{9}; 1706 let Inst{21} = 1; 1707 let Inst{20-12} = offset{8-0}; 1708 let Inst{11} = W; 1709 let Inst{10} = 1; 1710 let Inst{9-5} = Rn; 1711 let Inst{4-0} = Rt; 1712 1713 let DecoderMethod = "DecodeAuthLoadInstruction"; 1714} 1715 1716multiclass AuthLoad<bit M, string asm, Operand opr> { 1717 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1718 (ins GPR64sp:$Rn, opr:$offset), 1719 asm, "\t$Rt, [$Rn, $offset]", "", opr>; 1720 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1721 (ins GPR64sp:$Rn, opr:$offset), 1722 asm, "\t$Rt, [$Rn, $offset]!", 1723 "$Rn = $wback,@earlyclobber $wback", opr>; 1724 1725 def : InstAlias<asm # "\t$Rt, [$Rn]", 1726 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1727 1728 def : InstAlias<asm # "\t$Rt, [$wback]!", 1729 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1730} 1731 1732//--- 1733// Conditional branch instruction. 1734//--- 1735 1736// Condition code. 1737// 4-bit immediate. Pretty-printed as <cc> 1738def ccode : Operand<i32> { 1739 let PrintMethod = "printCondCode"; 1740 let ParserMatchClass = CondCode; 1741} 1742def inv_ccode : Operand<i32> { 1743 // AL and NV are invalid in the aliases which use inv_ccode 1744 let PrintMethod = "printInverseCondCode"; 1745 let ParserMatchClass = CondCode; 1746 let MCOperandPredicate = [{ 1747 return MCOp.isImm() && 1748 MCOp.getImm() != AArch64CC::AL && 1749 MCOp.getImm() != AArch64CC::NV; 1750 }]; 1751} 1752 1753// Conditional branch target. 19-bit immediate. The low two bits of the target 1754// offset are implied zero and so are not part of the immediate. 1755def am_brcond : Operand<OtherVT> { 1756 let EncoderMethod = "getCondBranchTargetOpValue"; 1757 let DecoderMethod = "DecodePCRelLabel19"; 1758 let PrintMethod = "printAlignedLabel"; 1759 let ParserMatchClass = PCRelLabel19Operand; 1760 let OperandType = "OPERAND_PCREL"; 1761} 1762 1763class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1764 "b", ".$cond\t$target", "", 1765 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1766 Sched<[WriteBr]> { 1767 let isBranch = 1; 1768 let isTerminator = 1; 1769 let Uses = [NZCV]; 1770 1771 bits<4> cond; 1772 bits<19> target; 1773 let Inst{31-24} = 0b01010100; 1774 let Inst{23-5} = target; 1775 let Inst{4} = 0; 1776 let Inst{3-0} = cond; 1777} 1778 1779//--- 1780// Compare-and-branch instructions. 1781//--- 1782class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1783 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1784 asm, "\t$Rt, $target", "", 1785 [(node regtype:$Rt, bb:$target)]>, 1786 Sched<[WriteBr]> { 1787 let isBranch = 1; 1788 let isTerminator = 1; 1789 1790 bits<5> Rt; 1791 bits<19> target; 1792 let Inst{30-25} = 0b011010; 1793 let Inst{24} = op; 1794 let Inst{23-5} = target; 1795 let Inst{4-0} = Rt; 1796} 1797 1798multiclass CmpBranch<bit op, string asm, SDNode node> { 1799 def W : BaseCmpBranch<GPR32, op, asm, node> { 1800 let Inst{31} = 0; 1801 } 1802 def X : BaseCmpBranch<GPR64, op, asm, node> { 1803 let Inst{31} = 1; 1804 } 1805} 1806 1807//--- 1808// Test-bit-and-branch instructions. 1809//--- 1810// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1811// the target offset are implied zero and so are not part of the immediate. 1812def am_tbrcond : Operand<OtherVT> { 1813 let EncoderMethod = "getTestBranchTargetOpValue"; 1814 let PrintMethod = "printAlignedLabel"; 1815 let ParserMatchClass = BranchTarget14Operand; 1816 let OperandType = "OPERAND_PCREL"; 1817} 1818 1819// AsmOperand classes to emit (or not) special diagnostics 1820def TBZImm0_31Operand : AsmOperandClass { 1821 let Name = "TBZImm0_31"; 1822 let PredicateMethod = "isImmInRange<0,31>"; 1823 let RenderMethod = "addImmOperands"; 1824} 1825def TBZImm32_63Operand : AsmOperandClass { 1826 let Name = "Imm32_63"; 1827 let PredicateMethod = "isImmInRange<32,63>"; 1828 let DiagnosticType = "InvalidImm0_63"; 1829 let RenderMethod = "addImmOperands"; 1830} 1831 1832class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1833 return (((uint32_t)Imm) < 32); 1834}]> { 1835 let ParserMatchClass = matcher; 1836} 1837 1838def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1839def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1840 1841def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1842 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1843}]> { 1844 let ParserMatchClass = TBZImm32_63Operand; 1845} 1846 1847class BaseTestBranch<RegisterClass regtype, Operand immtype, 1848 bit op, string asm, SDNode node> 1849 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1850 asm, "\t$Rt, $bit_off, $target", "", 1851 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1852 Sched<[WriteBr]> { 1853 let isBranch = 1; 1854 let isTerminator = 1; 1855 1856 bits<5> Rt; 1857 bits<6> bit_off; 1858 bits<14> target; 1859 1860 let Inst{30-25} = 0b011011; 1861 let Inst{24} = op; 1862 let Inst{23-19} = bit_off{4-0}; 1863 let Inst{18-5} = target; 1864 let Inst{4-0} = Rt; 1865 1866 let DecoderMethod = "DecodeTestAndBranch"; 1867} 1868 1869multiclass TestBranch<bit op, string asm, SDNode node> { 1870 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1871 let Inst{31} = 0; 1872 } 1873 1874 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1875 let Inst{31} = 1; 1876 } 1877 1878 // Alias X-reg with 0-31 imm to W-Reg. 1879 def : InstAlias<asm # "\t$Rd, $imm, $target", 1880 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1881 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1882 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1883 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1884 tbz_imm0_31_diag:$imm, bb:$target)>; 1885} 1886 1887//--- 1888// Unconditional branch (immediate) instructions. 1889//--- 1890def am_b_target : Operand<OtherVT> { 1891 let EncoderMethod = "getBranchTargetOpValue"; 1892 let PrintMethod = "printAlignedLabel"; 1893 let ParserMatchClass = BranchTarget26Operand; 1894 let OperandType = "OPERAND_PCREL"; 1895} 1896def am_bl_target : Operand<i64> { 1897 let EncoderMethod = "getBranchTargetOpValue"; 1898 let PrintMethod = "printAlignedLabel"; 1899 let ParserMatchClass = BranchTarget26Operand; 1900 let OperandType = "OPERAND_PCREL"; 1901} 1902 1903class BImm<bit op, dag iops, string asm, list<dag> pattern> 1904 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1905 bits<26> addr; 1906 let Inst{31} = op; 1907 let Inst{30-26} = 0b00101; 1908 let Inst{25-0} = addr; 1909 1910 let DecoderMethod = "DecodeUnconditionalBranch"; 1911} 1912 1913class BranchImm<bit op, string asm, list<dag> pattern> 1914 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1915class CallImm<bit op, string asm, list<dag> pattern> 1916 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1917 1918//--- 1919// Basic one-operand data processing instructions. 1920//--- 1921 1922let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1923class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1924 SDPatternOperator node> 1925 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1926 [(set regtype:$Rd, (node regtype:$Rn))]>, 1927 Sched<[WriteI, ReadI]> { 1928 bits<5> Rd; 1929 bits<5> Rn; 1930 1931 let Inst{30-13} = 0b101101011000000000; 1932 let Inst{12-10} = opc; 1933 let Inst{9-5} = Rn; 1934 let Inst{4-0} = Rd; 1935} 1936 1937let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1938multiclass OneOperandData<bits<3> opc, string asm, 1939 SDPatternOperator node = null_frag> { 1940 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1941 let Inst{31} = 0; 1942 } 1943 1944 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1945 let Inst{31} = 1; 1946 } 1947} 1948 1949class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1950 : BaseOneOperandData<opc, GPR32, asm, node> { 1951 let Inst{31} = 0; 1952} 1953 1954class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1955 : BaseOneOperandData<opc, GPR64, asm, node> { 1956 let Inst{31} = 1; 1957} 1958 1959class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm> 1960 : I<(outs GPR64:$Rd), (ins GPR64:$src, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 1961 "$Rd = $src", 1962 []>, 1963 Sched<[WriteI, ReadI]> { 1964 bits<5> Rd; 1965 bits<5> Rn; 1966 let Inst{31-15} = 0b11011010110000010; 1967 let Inst{14-12} = opcode_prefix; 1968 let Inst{11-10} = opcode; 1969 let Inst{9-5} = Rn; 1970 let Inst{4-0} = Rd; 1971} 1972 1973class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm> 1974 : I<(outs GPR64:$Rd), (ins GPR64:$src), asm, "\t$Rd", "$Rd = $src", 1975 []>, Sched<[]> { 1976 bits<5> Rd; 1977 let Inst{31-15} = 0b11011010110000010; 1978 let Inst{14-12} = opcode_prefix; 1979 let Inst{11-10} = opcode; 1980 let Inst{9-5} = 0b11111; 1981 let Inst{4-0} = Rd; 1982} 1983 1984class SignAuthTwoOperand<bits<4> opc, string asm, 1985 SDPatternOperator OpNode> 1986 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 1987 asm, "\t$Rd, $Rn, $Rm", "", 1988 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 1989 Sched<[WriteI, ReadI, ReadI]> { 1990 bits<5> Rd; 1991 bits<5> Rn; 1992 bits<5> Rm; 1993 let Inst{31-21} = 0b10011010110; 1994 let Inst{20-16} = Rm; 1995 let Inst{15-14} = 0b00; 1996 let Inst{13-10} = opc; 1997 let Inst{9-5} = Rn; 1998 let Inst{4-0} = Rd; 1999} 2000 2001class ClearAuth<bits<1> data, string asm> 2002 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2003 bits<5> Rd; 2004 let Inst{31-11} = 0b110110101100000101000; 2005 let Inst{10} = data; 2006 let Inst{9-5} = 0b11111; 2007 let Inst{4-0} = Rd; 2008} 2009 2010// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2011class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2012 : I<(outs), iops, asm, ops, "", []>, 2013 Sched<[WriteI, ReadI, ReadI]> { 2014 let Uses = [NZCV]; 2015 let Defs = [NZCV]; 2016 bits<5> Rn; 2017 let Inst{31} = sf; 2018 let Inst{30-15} = 0b0111010000000000; 2019 let Inst{14} = sz; 2020 let Inst{13-10} = 0b0010; 2021 let Inst{9-5} = Rn; 2022 let Inst{4-0} = 0b01101; 2023} 2024 2025class FlagRotate<dag iops, string asm, string ops> 2026 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2027 bits<6> imm; 2028 bits<4> mask; 2029 let Inst{20-15} = imm; 2030 let Inst{13-10} = 0b0001; 2031 let Inst{4} = 0b0; 2032 let Inst{3-0} = mask; 2033} 2034 2035//--- 2036// Basic two-operand data processing instructions. 2037//--- 2038class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2039 list<dag> pattern> 2040 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2041 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2042 Sched<[WriteI, ReadI, ReadI]> { 2043 let Uses = [NZCV]; 2044 bits<5> Rd; 2045 bits<5> Rn; 2046 bits<5> Rm; 2047 let Inst{30} = isSub; 2048 let Inst{28-21} = 0b11010000; 2049 let Inst{20-16} = Rm; 2050 let Inst{15-10} = 0; 2051 let Inst{9-5} = Rn; 2052 let Inst{4-0} = Rd; 2053} 2054 2055class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2056 SDNode OpNode> 2057 : BaseBaseAddSubCarry<isSub, regtype, asm, 2058 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2059 2060class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2061 SDNode OpNode> 2062 : BaseBaseAddSubCarry<isSub, regtype, asm, 2063 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2064 (implicit NZCV)]> { 2065 let Defs = [NZCV]; 2066} 2067 2068multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2069 SDNode OpNode, SDNode OpNode_setflags> { 2070 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2071 let Inst{31} = 0; 2072 let Inst{29} = 0; 2073 } 2074 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2075 let Inst{31} = 1; 2076 let Inst{29} = 0; 2077 } 2078 2079 // Sets flags. 2080 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2081 OpNode_setflags> { 2082 let Inst{31} = 0; 2083 let Inst{29} = 1; 2084 } 2085 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2086 OpNode_setflags> { 2087 let Inst{31} = 1; 2088 let Inst{29} = 1; 2089 } 2090} 2091 2092class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2093 SDPatternOperator OpNode, 2094 RegisterClass in1regtype = regtype, 2095 RegisterClass in2regtype = regtype> 2096 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2097 asm, "\t$Rd, $Rn, $Rm", "", 2098 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2099 bits<5> Rd; 2100 bits<5> Rn; 2101 bits<5> Rm; 2102 let Inst{30-21} = 0b0011010110; 2103 let Inst{20-16} = Rm; 2104 let Inst{15-14} = 0b00; 2105 let Inst{13-10} = opc; 2106 let Inst{9-5} = Rn; 2107 let Inst{4-0} = Rd; 2108} 2109 2110class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2111 SDPatternOperator OpNode> 2112 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2113 let Inst{10} = isSigned; 2114} 2115 2116multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2117 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2118 Sched<[WriteID32, ReadID, ReadID]> { 2119 let Inst{31} = 0; 2120 } 2121 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2122 Sched<[WriteID64, ReadID, ReadID]> { 2123 let Inst{31} = 1; 2124 } 2125} 2126 2127class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2128 SDPatternOperator OpNode = null_frag> 2129 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2130 Sched<[WriteIS, ReadI]> { 2131 let Inst{11-10} = shift_type; 2132} 2133 2134multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2135 def Wr : BaseShift<shift_type, GPR32, asm> { 2136 let Inst{31} = 0; 2137 } 2138 2139 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2140 let Inst{31} = 1; 2141 } 2142 2143 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2144 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2145 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2146 2147 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2148 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2149 2150 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2151 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2152 2153 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2154 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2155 2156 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2157 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2158 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2159 2160 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2161 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2162 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2163} 2164 2165class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2166 : InstAlias<asm#"\t$dst, $src1, $src2", 2167 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2168 2169class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2170 RegisterClass addtype, string asm, 2171 list<dag> pattern> 2172 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2173 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2174 bits<5> Rd; 2175 bits<5> Rn; 2176 bits<5> Rm; 2177 bits<5> Ra; 2178 let Inst{30-24} = 0b0011011; 2179 let Inst{23-21} = opc; 2180 let Inst{20-16} = Rm; 2181 let Inst{15} = isSub; 2182 let Inst{14-10} = Ra; 2183 let Inst{9-5} = Rn; 2184 let Inst{4-0} = Rd; 2185} 2186 2187multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 2188 // MADD/MSUB generation is decided by MachineCombiner.cpp 2189 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 2190 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 2191 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2192 let Inst{31} = 0; 2193 } 2194 2195 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 2196 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 2197 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2198 let Inst{31} = 1; 2199 } 2200} 2201 2202class WideMulAccum<bit isSub, bits<3> opc, string asm, 2203 SDNode AccNode, SDNode ExtNode> 2204 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2205 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2206 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2207 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2208 let Inst{31} = 1; 2209} 2210 2211class MulHi<bits<3> opc, string asm, SDNode OpNode> 2212 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2213 asm, "\t$Rd, $Rn, $Rm", "", 2214 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2215 Sched<[WriteIM64, ReadIM, ReadIM]> { 2216 bits<5> Rd; 2217 bits<5> Rn; 2218 bits<5> Rm; 2219 let Inst{31-24} = 0b10011011; 2220 let Inst{23-21} = opc; 2221 let Inst{20-16} = Rm; 2222 let Inst{15} = 0; 2223 let Inst{9-5} = Rn; 2224 let Inst{4-0} = Rd; 2225 2226 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2227 // (i.e. all bits 1) but is ignored by the processor. 2228 let PostEncoderMethod = "fixMulHigh"; 2229} 2230 2231class MulAccumWAlias<string asm, Instruction inst> 2232 : InstAlias<asm#"\t$dst, $src1, $src2", 2233 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2234class MulAccumXAlias<string asm, Instruction inst> 2235 : InstAlias<asm#"\t$dst, $src1, $src2", 2236 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2237class WideMulAccumAlias<string asm, Instruction inst> 2238 : InstAlias<asm#"\t$dst, $src1, $src2", 2239 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2240 2241class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2242 SDPatternOperator OpNode, string asm> 2243 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2244 asm, "\t$Rd, $Rn, $Rm", "", 2245 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2246 Sched<[WriteISReg, ReadI, ReadISReg]> { 2247 bits<5> Rd; 2248 bits<5> Rn; 2249 bits<5> Rm; 2250 2251 let Inst{31} = sf; 2252 let Inst{30-21} = 0b0011010110; 2253 let Inst{20-16} = Rm; 2254 let Inst{15-13} = 0b010; 2255 let Inst{12} = C; 2256 let Inst{11-10} = sz; 2257 let Inst{9-5} = Rn; 2258 let Inst{4-0} = Rd; 2259 let Predicates = [HasCRC]; 2260} 2261 2262//--- 2263// Address generation. 2264//--- 2265 2266class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2267 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2268 pattern>, 2269 Sched<[WriteI]> { 2270 bits<5> Xd; 2271 bits<21> label; 2272 let Inst{31} = page; 2273 let Inst{30-29} = label{1-0}; 2274 let Inst{28-24} = 0b10000; 2275 let Inst{23-5} = label{20-2}; 2276 let Inst{4-0} = Xd; 2277 2278 let DecoderMethod = "DecodeAdrInstruction"; 2279} 2280 2281//--- 2282// Move immediate. 2283//--- 2284 2285def movimm32_imm : Operand<i32> { 2286 let ParserMatchClass = AsmImmRange<0, 65535>; 2287 let EncoderMethod = "getMoveWideImmOpValue"; 2288 let PrintMethod = "printImm"; 2289} 2290def movimm32_shift : Operand<i32> { 2291 let PrintMethod = "printShifter"; 2292 let ParserMatchClass = MovImm32ShifterOperand; 2293} 2294def movimm64_shift : Operand<i32> { 2295 let PrintMethod = "printShifter"; 2296 let ParserMatchClass = MovImm64ShifterOperand; 2297} 2298 2299let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2300class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2301 string asm> 2302 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2303 asm, "\t$Rd, $imm$shift", "", []>, 2304 Sched<[WriteImm]> { 2305 bits<5> Rd; 2306 bits<16> imm; 2307 bits<6> shift; 2308 let Inst{30-29} = opc; 2309 let Inst{28-23} = 0b100101; 2310 let Inst{22-21} = shift{5-4}; 2311 let Inst{20-5} = imm; 2312 let Inst{4-0} = Rd; 2313 2314 let DecoderMethod = "DecodeMoveImmInstruction"; 2315} 2316 2317multiclass MoveImmediate<bits<2> opc, string asm> { 2318 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2319 let Inst{31} = 0; 2320 } 2321 2322 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2323 let Inst{31} = 1; 2324 } 2325} 2326 2327let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2328class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2329 string asm> 2330 : I<(outs regtype:$Rd), 2331 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2332 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2333 Sched<[WriteI, ReadI]> { 2334 bits<5> Rd; 2335 bits<16> imm; 2336 bits<6> shift; 2337 let Inst{30-29} = opc; 2338 let Inst{28-23} = 0b100101; 2339 let Inst{22-21} = shift{5-4}; 2340 let Inst{20-5} = imm; 2341 let Inst{4-0} = Rd; 2342 2343 let DecoderMethod = "DecodeMoveImmInstruction"; 2344} 2345 2346multiclass InsertImmediate<bits<2> opc, string asm> { 2347 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2348 let Inst{31} = 0; 2349 } 2350 2351 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2352 let Inst{31} = 1; 2353 } 2354} 2355 2356//--- 2357// Add/Subtract 2358//--- 2359 2360class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2361 string asm_inst, string asm_ops, 2362 dag inputs, dag pattern> 2363 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2364 Sched<[WriteI, ReadI]> { 2365 bits<5> Rd; 2366 bits<5> Rn; 2367 let Inst{30} = isSub; 2368 let Inst{29} = setFlags; 2369 let Inst{28-24} = 0b10001; 2370 let Inst{9-5} = Rn; 2371 let Inst{4-0} = Rd; 2372} 2373 2374class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2375 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2376 string asm_inst, SDPatternOperator OpNode> 2377 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2378 (ins srcRegtype:$Rn, immtype:$imm), 2379 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2380 bits<14> imm; 2381 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2382 let Inst{21-10} = imm{11-0}; 2383 let DecoderMethod = "DecodeAddSubImmShift"; 2384} 2385 2386class BaseAddSubRegPseudo<RegisterClass regtype, 2387 SDPatternOperator OpNode> 2388 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2389 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2390 Sched<[WriteI, ReadI, ReadI]>; 2391 2392class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2393 arith_shifted_reg shifted_regtype, string asm, 2394 SDPatternOperator OpNode> 2395 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2396 asm, "\t$Rd, $Rn, $Rm", "", 2397 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2398 Sched<[WriteISReg, ReadI, ReadISReg]> { 2399 // The operands are in order to match the 'addr' MI operands, so we 2400 // don't need an encoder method and by-name matching. Just use the default 2401 // in-order handling. Since we're using by-order, make sure the names 2402 // do not match. 2403 bits<5> dst; 2404 bits<5> src1; 2405 bits<5> src2; 2406 bits<8> shift; 2407 let Inst{30} = isSub; 2408 let Inst{29} = setFlags; 2409 let Inst{28-24} = 0b01011; 2410 let Inst{23-22} = shift{7-6}; 2411 let Inst{21} = 0; 2412 let Inst{20-16} = src2; 2413 let Inst{15-10} = shift{5-0}; 2414 let Inst{9-5} = src1; 2415 let Inst{4-0} = dst; 2416 2417 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2418} 2419 2420class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2421 RegisterClass src1Regtype, Operand src2Regtype, 2422 string asm, SDPatternOperator OpNode> 2423 : I<(outs dstRegtype:$R1), 2424 (ins src1Regtype:$R2, src2Regtype:$R3), 2425 asm, "\t$R1, $R2, $R3", "", 2426 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2427 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2428 bits<5> Rd; 2429 bits<5> Rn; 2430 bits<5> Rm; 2431 bits<6> ext; 2432 let Inst{30} = isSub; 2433 let Inst{29} = setFlags; 2434 let Inst{28-24} = 0b01011; 2435 let Inst{23-21} = 0b001; 2436 let Inst{20-16} = Rm; 2437 let Inst{15-13} = ext{5-3}; 2438 let Inst{12-10} = ext{2-0}; 2439 let Inst{9-5} = Rn; 2440 let Inst{4-0} = Rd; 2441 2442 let DecoderMethod = "DecodeAddSubERegInstruction"; 2443} 2444 2445let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2446class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2447 RegisterClass src1Regtype, RegisterClass src2Regtype, 2448 Operand ext_op, string asm> 2449 : I<(outs dstRegtype:$Rd), 2450 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2451 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2452 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2453 bits<5> Rd; 2454 bits<5> Rn; 2455 bits<5> Rm; 2456 bits<6> ext; 2457 let Inst{30} = isSub; 2458 let Inst{29} = setFlags; 2459 let Inst{28-24} = 0b01011; 2460 let Inst{23-21} = 0b001; 2461 let Inst{20-16} = Rm; 2462 let Inst{15} = ext{5}; 2463 let Inst{12-10} = ext{2-0}; 2464 let Inst{9-5} = Rn; 2465 let Inst{4-0} = Rd; 2466 2467 let DecoderMethod = "DecodeAddSubERegInstruction"; 2468} 2469 2470// Aliases for register+register add/subtract. 2471class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2472 RegisterClass src1Regtype, RegisterClass src2Regtype, 2473 int shiftExt> 2474 : InstAlias<asm#"\t$dst, $src1, $src2", 2475 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2476 shiftExt)>; 2477 2478multiclass AddSub<bit isSub, string mnemonic, string alias, 2479 SDPatternOperator OpNode = null_frag> { 2480 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2481 // Add/Subtract immediate 2482 // Increase the weight of the immediate variant to try to match it before 2483 // the extended register variant. 2484 // We used to match the register variant before the immediate when the 2485 // register argument could be implicitly zero-extended. 2486 let AddedComplexity = 6 in 2487 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2488 mnemonic, OpNode> { 2489 let Inst{31} = 0; 2490 } 2491 let AddedComplexity = 6 in 2492 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2493 mnemonic, OpNode> { 2494 let Inst{31} = 1; 2495 } 2496 2497 // Add/Subtract register - Only used for CodeGen 2498 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2499 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2500 2501 // Add/Subtract shifted register 2502 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2503 OpNode> { 2504 let Inst{31} = 0; 2505 } 2506 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2507 OpNode> { 2508 let Inst{31} = 1; 2509 } 2510 } 2511 2512 // Add/Subtract extended register 2513 let AddedComplexity = 1, hasSideEffects = 0 in { 2514 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2515 arith_extended_reg32_i32, mnemonic, OpNode> { 2516 let Inst{31} = 0; 2517 } 2518 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2519 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2520 let Inst{31} = 1; 2521 } 2522 } 2523 2524 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2525 arith_extendlsl64, mnemonic> { 2526 // UXTX and SXTX only. 2527 let Inst{14-13} = 0b11; 2528 let Inst{31} = 1; 2529 } 2530 2531 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2532 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2533 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2534 addsub_shifted_imm32_neg:$imm), 0>; 2535 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2536 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2537 addsub_shifted_imm64_neg:$imm), 0>; 2538 2539 // Register/register aliases with no shift when SP is not used. 2540 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2541 GPR32, GPR32, GPR32, 0>; 2542 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2543 GPR64, GPR64, GPR64, 0>; 2544 2545 // Register/register aliases with no shift when either the destination or 2546 // first source register is SP. 2547 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2548 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2549 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2550 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2551 def : AddSubRegAlias<mnemonic, 2552 !cast<Instruction>(NAME#"Xrx64"), 2553 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2554 def : AddSubRegAlias<mnemonic, 2555 !cast<Instruction>(NAME#"Xrx64"), 2556 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2557} 2558 2559multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2560 string alias, string cmpAlias> { 2561 let isCompare = 1, Defs = [NZCV] in { 2562 // Add/Subtract immediate 2563 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2564 mnemonic, OpNode> { 2565 let Inst{31} = 0; 2566 } 2567 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2568 mnemonic, OpNode> { 2569 let Inst{31} = 1; 2570 } 2571 2572 // Add/Subtract register 2573 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2574 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2575 2576 // Add/Subtract shifted register 2577 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2578 OpNode> { 2579 let Inst{31} = 0; 2580 } 2581 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2582 OpNode> { 2583 let Inst{31} = 1; 2584 } 2585 2586 // Add/Subtract extended register 2587 let AddedComplexity = 1 in { 2588 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2589 arith_extended_reg32_i32, mnemonic, OpNode> { 2590 let Inst{31} = 0; 2591 } 2592 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2593 arith_extended_reg32_i64, mnemonic, OpNode> { 2594 let Inst{31} = 1; 2595 } 2596 } 2597 2598 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2599 arith_extendlsl64, mnemonic> { 2600 // UXTX and SXTX only. 2601 let Inst{14-13} = 0b11; 2602 let Inst{31} = 1; 2603 } 2604 } // Defs = [NZCV] 2605 2606 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2607 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2608 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2609 addsub_shifted_imm32_neg:$imm), 0>; 2610 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2611 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2612 addsub_shifted_imm64_neg:$imm), 0>; 2613 2614 // Compare aliases 2615 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2616 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2617 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2618 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2619 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2620 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2621 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2622 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2623 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2624 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2625 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2626 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2627 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2628 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2629 2630 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2631 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2632 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2633 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2634 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2635 2636 // Compare shorthands 2637 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2638 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2639 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2640 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2641 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2642 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2643 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2644 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2645 2646 // Register/register aliases with no shift when SP is not used. 2647 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2648 GPR32, GPR32, GPR32, 0>; 2649 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2650 GPR64, GPR64, GPR64, 0>; 2651 2652 // Register/register aliases with no shift when the first source register 2653 // is SP. 2654 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2655 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2656 def : AddSubRegAlias<mnemonic, 2657 !cast<Instruction>(NAME#"Xrx64"), 2658 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2659} 2660 2661class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2662 : BaseAddSubImm< 2663 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2664 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2665 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2666 bits<6> imm6; 2667 bits<4> imm4; 2668 let Inst{31} = 1; 2669 let Inst{23-22} = 0b10; 2670 let Inst{21-16} = imm6; 2671 let Inst{15-14} = 0b00; 2672 let Inst{13-10} = imm4; 2673 let Unpredictable{15-14} = 0b11; 2674} 2675 2676class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2677 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2678 let Inst{31} = 1; 2679 let Inst{29} = setsFlags; 2680} 2681 2682//--- 2683// Extract 2684//--- 2685def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2686 SDTCisPtrTy<3>]>; 2687def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2688 2689class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2690 list<dag> patterns> 2691 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2692 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2693 Sched<[WriteExtr, ReadExtrHi]> { 2694 bits<5> Rd; 2695 bits<5> Rn; 2696 bits<5> Rm; 2697 bits<6> imm; 2698 2699 let Inst{30-23} = 0b00100111; 2700 let Inst{21} = 0; 2701 let Inst{20-16} = Rm; 2702 let Inst{15-10} = imm; 2703 let Inst{9-5} = Rn; 2704 let Inst{4-0} = Rd; 2705} 2706 2707multiclass ExtractImm<string asm> { 2708 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2709 [(set GPR32:$Rd, 2710 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2711 let Inst{31} = 0; 2712 let Inst{22} = 0; 2713 // imm<5> must be zero. 2714 let imm{5} = 0; 2715 } 2716 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2717 [(set GPR64:$Rd, 2718 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2719 2720 let Inst{31} = 1; 2721 let Inst{22} = 1; 2722 } 2723} 2724 2725//--- 2726// Bitfield 2727//--- 2728 2729let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2730class BaseBitfieldImm<bits<2> opc, 2731 RegisterClass regtype, Operand imm_type, string asm> 2732 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2733 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2734 Sched<[WriteIS, ReadI]> { 2735 bits<5> Rd; 2736 bits<5> Rn; 2737 bits<6> immr; 2738 bits<6> imms; 2739 2740 let Inst{30-29} = opc; 2741 let Inst{28-23} = 0b100110; 2742 let Inst{21-16} = immr; 2743 let Inst{15-10} = imms; 2744 let Inst{9-5} = Rn; 2745 let Inst{4-0} = Rd; 2746} 2747 2748multiclass BitfieldImm<bits<2> opc, string asm> { 2749 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2750 let Inst{31} = 0; 2751 let Inst{22} = 0; 2752 // imms<5> and immr<5> must be zero, else ReservedValue(). 2753 let Inst{21} = 0; 2754 let Inst{15} = 0; 2755 } 2756 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2757 let Inst{31} = 1; 2758 let Inst{22} = 1; 2759 } 2760} 2761 2762let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2763class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2764 RegisterClass regtype, Operand imm_type, string asm> 2765 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2766 imm_type:$imms), 2767 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2768 Sched<[WriteIS, ReadI]> { 2769 bits<5> Rd; 2770 bits<5> Rn; 2771 bits<6> immr; 2772 bits<6> imms; 2773 2774 let Inst{30-29} = opc; 2775 let Inst{28-23} = 0b100110; 2776 let Inst{21-16} = immr; 2777 let Inst{15-10} = imms; 2778 let Inst{9-5} = Rn; 2779 let Inst{4-0} = Rd; 2780} 2781 2782multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2783 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2784 let Inst{31} = 0; 2785 let Inst{22} = 0; 2786 // imms<5> and immr<5> must be zero, else ReservedValue(). 2787 let Inst{21} = 0; 2788 let Inst{15} = 0; 2789 } 2790 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2791 let Inst{31} = 1; 2792 let Inst{22} = 1; 2793 } 2794} 2795 2796//--- 2797// Logical 2798//--- 2799 2800// Logical (immediate) 2801class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2802 RegisterClass sregtype, Operand imm_type, string asm, 2803 list<dag> pattern> 2804 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2805 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2806 Sched<[WriteI, ReadI]> { 2807 bits<5> Rd; 2808 bits<5> Rn; 2809 bits<13> imm; 2810 let Inst{30-29} = opc; 2811 let Inst{28-23} = 0b100100; 2812 let Inst{22} = imm{12}; 2813 let Inst{21-16} = imm{11-6}; 2814 let Inst{15-10} = imm{5-0}; 2815 let Inst{9-5} = Rn; 2816 let Inst{4-0} = Rd; 2817 2818 let DecoderMethod = "DecodeLogicalImmInstruction"; 2819} 2820 2821// Logical (shifted register) 2822class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2823 logical_shifted_reg shifted_regtype, string asm, 2824 list<dag> pattern> 2825 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2826 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2827 Sched<[WriteISReg, ReadI, ReadISReg]> { 2828 // The operands are in order to match the 'addr' MI operands, so we 2829 // don't need an encoder method and by-name matching. Just use the default 2830 // in-order handling. Since we're using by-order, make sure the names 2831 // do not match. 2832 bits<5> dst; 2833 bits<5> src1; 2834 bits<5> src2; 2835 bits<8> shift; 2836 let Inst{30-29} = opc; 2837 let Inst{28-24} = 0b01010; 2838 let Inst{23-22} = shift{7-6}; 2839 let Inst{21} = N; 2840 let Inst{20-16} = src2; 2841 let Inst{15-10} = shift{5-0}; 2842 let Inst{9-5} = src1; 2843 let Inst{4-0} = dst; 2844 2845 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2846} 2847 2848// Aliases for register+register logical instructions. 2849class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2850 : InstAlias<asm#"\t$dst, $src1, $src2", 2851 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2852 2853multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2854 string Alias> { 2855 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2856 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2857 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2858 logical_imm32:$imm))]> { 2859 let Inst{31} = 0; 2860 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2861 } 2862 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2863 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2864 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2865 logical_imm64:$imm))]> { 2866 let Inst{31} = 1; 2867 } 2868 2869 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2870 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2871 logical_imm32_not:$imm), 0>; 2872 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2873 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2874 logical_imm64_not:$imm), 0>; 2875} 2876 2877multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2878 string Alias> { 2879 let isCompare = 1, Defs = [NZCV] in { 2880 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2881 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2882 let Inst{31} = 0; 2883 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2884 } 2885 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2886 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2887 let Inst{31} = 1; 2888 } 2889 } // end Defs = [NZCV] 2890 2891 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2892 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2893 logical_imm32_not:$imm), 0>; 2894 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2895 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2896 logical_imm64_not:$imm), 0>; 2897} 2898 2899class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2900 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2901 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2902 Sched<[WriteI, ReadI, ReadI]>; 2903 2904// Split from LogicalImm as not all instructions have both. 2905multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2906 SDPatternOperator OpNode> { 2907 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2908 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2909 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2910 } 2911 2912 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2913 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2914 logical_shifted_reg32:$Rm))]> { 2915 let Inst{31} = 0; 2916 } 2917 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2918 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2919 logical_shifted_reg64:$Rm))]> { 2920 let Inst{31} = 1; 2921 } 2922 2923 def : LogicalRegAlias<mnemonic, 2924 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2925 def : LogicalRegAlias<mnemonic, 2926 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2927} 2928 2929// Split from LogicalReg to allow setting NZCV Defs 2930multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2931 SDPatternOperator OpNode = null_frag> { 2932 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2933 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2934 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2935 2936 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2937 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2938 let Inst{31} = 0; 2939 } 2940 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2941 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2942 let Inst{31} = 1; 2943 } 2944 } // Defs = [NZCV] 2945 2946 def : LogicalRegAlias<mnemonic, 2947 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2948 def : LogicalRegAlias<mnemonic, 2949 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2950} 2951 2952//--- 2953// Conditionally set flags 2954//--- 2955 2956let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2957class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2958 string mnemonic, SDNode OpNode> 2959 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2960 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2961 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2962 (i32 imm:$cond), NZCV))]>, 2963 Sched<[WriteI, ReadI]> { 2964 let Uses = [NZCV]; 2965 let Defs = [NZCV]; 2966 2967 bits<5> Rn; 2968 bits<5> imm; 2969 bits<4> nzcv; 2970 bits<4> cond; 2971 2972 let Inst{30} = op; 2973 let Inst{29-21} = 0b111010010; 2974 let Inst{20-16} = imm; 2975 let Inst{15-12} = cond; 2976 let Inst{11-10} = 0b10; 2977 let Inst{9-5} = Rn; 2978 let Inst{4} = 0b0; 2979 let Inst{3-0} = nzcv; 2980} 2981 2982let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2983class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2984 SDNode OpNode> 2985 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2986 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2987 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2988 (i32 imm:$cond), NZCV))]>, 2989 Sched<[WriteI, ReadI, ReadI]> { 2990 let Uses = [NZCV]; 2991 let Defs = [NZCV]; 2992 2993 bits<5> Rn; 2994 bits<5> Rm; 2995 bits<4> nzcv; 2996 bits<4> cond; 2997 2998 let Inst{30} = op; 2999 let Inst{29-21} = 0b111010010; 3000 let Inst{20-16} = Rm; 3001 let Inst{15-12} = cond; 3002 let Inst{11-10} = 0b00; 3003 let Inst{9-5} = Rn; 3004 let Inst{4} = 0b0; 3005 let Inst{3-0} = nzcv; 3006} 3007 3008multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3009 // immediate operand variants 3010 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3011 let Inst{31} = 0; 3012 } 3013 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3014 let Inst{31} = 1; 3015 } 3016 // register operand variants 3017 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3018 let Inst{31} = 0; 3019 } 3020 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3021 let Inst{31} = 1; 3022 } 3023} 3024 3025//--- 3026// Conditional select 3027//--- 3028 3029class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3030 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3031 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3032 [(set regtype:$Rd, 3033 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3034 Sched<[WriteI, ReadI, ReadI]> { 3035 let Uses = [NZCV]; 3036 3037 bits<5> Rd; 3038 bits<5> Rn; 3039 bits<5> Rm; 3040 bits<4> cond; 3041 3042 let Inst{30} = op; 3043 let Inst{29-21} = 0b011010100; 3044 let Inst{20-16} = Rm; 3045 let Inst{15-12} = cond; 3046 let Inst{11-10} = op2; 3047 let Inst{9-5} = Rn; 3048 let Inst{4-0} = Rd; 3049} 3050 3051multiclass CondSelect<bit op, bits<2> op2, string asm> { 3052 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3053 let Inst{31} = 0; 3054 } 3055 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3056 let Inst{31} = 1; 3057 } 3058} 3059 3060class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3061 PatFrag frag> 3062 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3063 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3064 [(set regtype:$Rd, 3065 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3066 (i32 imm:$cond), NZCV))]>, 3067 Sched<[WriteI, ReadI, ReadI]> { 3068 let Uses = [NZCV]; 3069 3070 bits<5> Rd; 3071 bits<5> Rn; 3072 bits<5> Rm; 3073 bits<4> cond; 3074 3075 let Inst{30} = op; 3076 let Inst{29-21} = 0b011010100; 3077 let Inst{20-16} = Rm; 3078 let Inst{15-12} = cond; 3079 let Inst{11-10} = op2; 3080 let Inst{9-5} = Rn; 3081 let Inst{4-0} = Rd; 3082} 3083 3084def inv_cond_XFORM : SDNodeXForm<imm, [{ 3085 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3086 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3087 MVT::i32); 3088}]>; 3089 3090multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3091 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3092 let Inst{31} = 0; 3093 } 3094 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3095 let Inst{31} = 1; 3096 } 3097 3098 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3099 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3100 (inv_cond_XFORM imm:$cond))>; 3101 3102 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3103 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3104 (inv_cond_XFORM imm:$cond))>; 3105} 3106 3107//--- 3108// Special Mask Value 3109//--- 3110def maski8_or_more : Operand<i32>, 3111 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3112} 3113def maski16_or_more : Operand<i32>, 3114 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3115} 3116 3117 3118//--- 3119// Load/store 3120//--- 3121 3122// (unsigned immediate) 3123// Indexed for 8-bit registers. offset is in range [0,4095]. 3124def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 3125def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 3126def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 3127def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 3128def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 3129 3130def gi_am_indexed8 : 3131 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3132 GIComplexPatternEquiv<am_indexed8>; 3133def gi_am_indexed16 : 3134 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3135 GIComplexPatternEquiv<am_indexed16>; 3136def gi_am_indexed32 : 3137 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3138 GIComplexPatternEquiv<am_indexed32>; 3139def gi_am_indexed64 : 3140 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3141 GIComplexPatternEquiv<am_indexed64>; 3142def gi_am_indexed128 : 3143 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3144 GIComplexPatternEquiv<am_indexed128>; 3145 3146class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3147 let Name = "UImm12Offset" # Scale; 3148 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3149 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3150 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3151} 3152 3153def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3154def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3155def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3156def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3157def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3158 3159class uimm12_scaled<int Scale> : Operand<i64> { 3160 let ParserMatchClass 3161 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3162 let EncoderMethod 3163 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3164 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3165} 3166 3167def uimm12s1 : uimm12_scaled<1>; 3168def uimm12s2 : uimm12_scaled<2>; 3169def uimm12s4 : uimm12_scaled<4>; 3170def uimm12s8 : uimm12_scaled<8>; 3171def uimm12s16 : uimm12_scaled<16>; 3172 3173class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3174 string asm, list<dag> pattern> 3175 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3176 bits<5> Rt; 3177 3178 bits<5> Rn; 3179 bits<12> offset; 3180 3181 let Inst{31-30} = sz; 3182 let Inst{29-27} = 0b111; 3183 let Inst{26} = V; 3184 let Inst{25-24} = 0b01; 3185 let Inst{23-22} = opc; 3186 let Inst{21-10} = offset; 3187 let Inst{9-5} = Rn; 3188 let Inst{4-0} = Rt; 3189 3190 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3191} 3192 3193multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3194 Operand indextype, string asm, list<dag> pattern> { 3195 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3196 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3197 (ins GPR64sp:$Rn, indextype:$offset), 3198 asm, pattern>, 3199 Sched<[WriteLD]>; 3200 3201 def : InstAlias<asm # "\t$Rt, [$Rn]", 3202 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3203} 3204 3205multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3206 Operand indextype, string asm, list<dag> pattern> { 3207 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3208 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3209 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3210 asm, pattern>, 3211 Sched<[WriteST]>; 3212 3213 def : InstAlias<asm # "\t$Rt, [$Rn]", 3214 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3215} 3216 3217// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3218// substitute zero-registers automatically. 3219// 3220// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3221// into StoreUI. 3222multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3223 Operand indextype, string asm, list<dag> pattern> { 3224 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3225 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3226 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3227 asm, pattern>, 3228 Sched<[WriteST]>; 3229 3230 def : InstAlias<asm # "\t$Rt, [$Rn]", 3231 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3232} 3233 3234def PrefetchOperand : AsmOperandClass { 3235 let Name = "Prefetch"; 3236 let ParserMethod = "tryParsePrefetch"; 3237} 3238def prfop : Operand<i32> { 3239 let PrintMethod = "printPrefetchOp"; 3240 let ParserMatchClass = PrefetchOperand; 3241} 3242 3243let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3244class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3245 : BaseLoadStoreUI<sz, V, opc, 3246 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3247 asm, pat>, 3248 Sched<[WriteLD]>; 3249 3250//--- 3251// Load literal 3252//--- 3253 3254// Load literal address: 19-bit immediate. The low two bits of the target 3255// offset are implied zero and so are not part of the immediate. 3256def am_ldrlit : Operand<iPTR> { 3257 let EncoderMethod = "getLoadLiteralOpValue"; 3258 let DecoderMethod = "DecodePCRelLabel19"; 3259 let PrintMethod = "printAlignedLabel"; 3260 let ParserMatchClass = PCRelLabel19Operand; 3261 let OperandType = "OPERAND_PCREL"; 3262} 3263 3264let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3265class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3266 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3267 asm, "\t$Rt, $label", "", pat>, 3268 Sched<[WriteLD]> { 3269 bits<5> Rt; 3270 bits<19> label; 3271 let Inst{31-30} = opc; 3272 let Inst{29-27} = 0b011; 3273 let Inst{26} = V; 3274 let Inst{25-24} = 0b00; 3275 let Inst{23-5} = label; 3276 let Inst{4-0} = Rt; 3277} 3278 3279let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3280class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3281 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3282 asm, "\t$Rt, $label", "", pat>, 3283 Sched<[WriteLD]> { 3284 bits<5> Rt; 3285 bits<19> label; 3286 let Inst{31-30} = opc; 3287 let Inst{29-27} = 0b011; 3288 let Inst{26} = V; 3289 let Inst{25-24} = 0b00; 3290 let Inst{23-5} = label; 3291 let Inst{4-0} = Rt; 3292} 3293 3294//--- 3295// Load/store register offset 3296//--- 3297 3298def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 3299def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 3300def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 3301def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 3302def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 3303 3304def gi_ro_Xindexed8 : 3305 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3306 GIComplexPatternEquiv<ro_Xindexed8>; 3307def gi_ro_Xindexed16 : 3308 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3309 GIComplexPatternEquiv<ro_Xindexed16>; 3310def gi_ro_Xindexed32 : 3311 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3312 GIComplexPatternEquiv<ro_Xindexed32>; 3313def gi_ro_Xindexed64 : 3314 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3315 GIComplexPatternEquiv<ro_Xindexed64>; 3316def gi_ro_Xindexed128 : 3317 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3318 GIComplexPatternEquiv<ro_Xindexed128>; 3319 3320def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 3321def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 3322def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 3323def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 3324def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 3325 3326def gi_ro_Windexed8 : 3327 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3328 GIComplexPatternEquiv<ro_Windexed8>; 3329def gi_ro_Windexed16 : 3330 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3331 GIComplexPatternEquiv<ro_Windexed16>; 3332def gi_ro_Windexed32 : 3333 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3334 GIComplexPatternEquiv<ro_Windexed32>; 3335def gi_ro_Windexed64 : 3336 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3337 GIComplexPatternEquiv<ro_Windexed64>; 3338def gi_ro_Windexed128 : 3339 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3340 GIComplexPatternEquiv<ro_Windexed128>; 3341 3342class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3343 let Name = "Mem" # Reg # "Extend" # Width; 3344 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3345 let RenderMethod = "addMemExtendOperands"; 3346 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3347} 3348 3349def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3350 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3351 // the trivial shift. 3352 let RenderMethod = "addMemExtend8Operands"; 3353} 3354def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3355def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3356def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3357def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3358 3359def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3360 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3361 // the trivial shift. 3362 let RenderMethod = "addMemExtend8Operands"; 3363} 3364def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3365def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3366def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3367def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3368 3369class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3370 : Operand<i32> { 3371 let ParserMatchClass = ParserClass; 3372 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3373 let DecoderMethod = "DecodeMemExtend"; 3374 let EncoderMethod = "getMemExtendOpValue"; 3375 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3376} 3377 3378def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3379def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3380def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3381def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3382def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3383 3384def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3385def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3386def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3387def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3388def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3389 3390class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3391 Operand wextend, Operand xextend> { 3392 // CodeGen-level pattern covering the entire addressing mode. 3393 ComplexPattern Wpat = windex; 3394 ComplexPattern Xpat = xindex; 3395 3396 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3397 Operand Wext = wextend; 3398 Operand Xext = xextend; 3399} 3400 3401def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3402def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3403def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3404def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3405def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3406 ro_Xextend128>; 3407 3408class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3409 string asm, dag ins, dag outs, list<dag> pat> 3410 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3411 bits<5> Rt; 3412 bits<5> Rn; 3413 bits<5> Rm; 3414 bits<2> extend; 3415 let Inst{31-30} = sz; 3416 let Inst{29-27} = 0b111; 3417 let Inst{26} = V; 3418 let Inst{25-24} = 0b00; 3419 let Inst{23-22} = opc; 3420 let Inst{21} = 1; 3421 let Inst{20-16} = Rm; 3422 let Inst{15} = extend{1}; // sign extend Rm? 3423 let Inst{14} = 1; 3424 let Inst{12} = extend{0}; // do shift? 3425 let Inst{11-10} = 0b10; 3426 let Inst{9-5} = Rn; 3427 let Inst{4-0} = Rt; 3428} 3429 3430class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3431 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3432 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3433 3434multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3435 string asm, ValueType Ty, SDPatternOperator loadop> { 3436 let AddedComplexity = 10 in 3437 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 3438 (outs regtype:$Rt), 3439 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3440 [(set (Ty regtype:$Rt), 3441 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3442 ro_Wextend8:$extend)))]>, 3443 Sched<[WriteLDIdx, ReadAdrBase]> { 3444 let Inst{13} = 0b0; 3445 } 3446 3447 let AddedComplexity = 10 in 3448 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 3449 (outs regtype:$Rt), 3450 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3451 [(set (Ty regtype:$Rt), 3452 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3453 ro_Xextend8:$extend)))]>, 3454 Sched<[WriteLDIdx, ReadAdrBase]> { 3455 let Inst{13} = 0b1; 3456 } 3457 3458 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3459} 3460 3461multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3462 string asm, ValueType Ty, SDPatternOperator storeop> { 3463 let AddedComplexity = 10 in 3464 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3465 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3466 [(storeop (Ty regtype:$Rt), 3467 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3468 ro_Wextend8:$extend))]>, 3469 Sched<[WriteSTIdx, ReadAdrBase]> { 3470 let Inst{13} = 0b0; 3471 } 3472 3473 let AddedComplexity = 10 in 3474 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3475 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3476 [(storeop (Ty regtype:$Rt), 3477 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3478 ro_Xextend8:$extend))]>, 3479 Sched<[WriteSTIdx, ReadAdrBase]> { 3480 let Inst{13} = 0b1; 3481 } 3482 3483 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3484} 3485 3486class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3487 string asm, dag ins, dag outs, list<dag> pat> 3488 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3489 bits<5> Rt; 3490 bits<5> Rn; 3491 bits<5> Rm; 3492 bits<2> extend; 3493 let Inst{31-30} = sz; 3494 let Inst{29-27} = 0b111; 3495 let Inst{26} = V; 3496 let Inst{25-24} = 0b00; 3497 let Inst{23-22} = opc; 3498 let Inst{21} = 1; 3499 let Inst{20-16} = Rm; 3500 let Inst{15} = extend{1}; // sign extend Rm? 3501 let Inst{14} = 1; 3502 let Inst{12} = extend{0}; // do shift? 3503 let Inst{11-10} = 0b10; 3504 let Inst{9-5} = Rn; 3505 let Inst{4-0} = Rt; 3506} 3507 3508multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3509 string asm, ValueType Ty, SDPatternOperator loadop> { 3510 let AddedComplexity = 10 in 3511 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3512 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3513 [(set (Ty regtype:$Rt), 3514 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3515 ro_Wextend16:$extend)))]>, 3516 Sched<[WriteLDIdx, ReadAdrBase]> { 3517 let Inst{13} = 0b0; 3518 } 3519 3520 let AddedComplexity = 10 in 3521 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3522 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3523 [(set (Ty regtype:$Rt), 3524 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3525 ro_Xextend16:$extend)))]>, 3526 Sched<[WriteLDIdx, ReadAdrBase]> { 3527 let Inst{13} = 0b1; 3528 } 3529 3530 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3531} 3532 3533multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3534 string asm, ValueType Ty, SDPatternOperator storeop> { 3535 let AddedComplexity = 10 in 3536 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3537 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3538 [(storeop (Ty regtype:$Rt), 3539 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3540 ro_Wextend16:$extend))]>, 3541 Sched<[WriteSTIdx, ReadAdrBase]> { 3542 let Inst{13} = 0b0; 3543 } 3544 3545 let AddedComplexity = 10 in 3546 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3547 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3548 [(storeop (Ty regtype:$Rt), 3549 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3550 ro_Xextend16:$extend))]>, 3551 Sched<[WriteSTIdx, ReadAdrBase]> { 3552 let Inst{13} = 0b1; 3553 } 3554 3555 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3556} 3557 3558class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3559 string asm, dag ins, dag outs, list<dag> pat> 3560 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3561 bits<5> Rt; 3562 bits<5> Rn; 3563 bits<5> Rm; 3564 bits<2> extend; 3565 let Inst{31-30} = sz; 3566 let Inst{29-27} = 0b111; 3567 let Inst{26} = V; 3568 let Inst{25-24} = 0b00; 3569 let Inst{23-22} = opc; 3570 let Inst{21} = 1; 3571 let Inst{20-16} = Rm; 3572 let Inst{15} = extend{1}; // sign extend Rm? 3573 let Inst{14} = 1; 3574 let Inst{12} = extend{0}; // do shift? 3575 let Inst{11-10} = 0b10; 3576 let Inst{9-5} = Rn; 3577 let Inst{4-0} = Rt; 3578} 3579 3580multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3581 string asm, ValueType Ty, SDPatternOperator loadop> { 3582 let AddedComplexity = 10 in 3583 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3584 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3585 [(set (Ty regtype:$Rt), 3586 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3587 ro_Wextend32:$extend)))]>, 3588 Sched<[WriteLDIdx, ReadAdrBase]> { 3589 let Inst{13} = 0b0; 3590 } 3591 3592 let AddedComplexity = 10 in 3593 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3594 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3595 [(set (Ty regtype:$Rt), 3596 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3597 ro_Xextend32:$extend)))]>, 3598 Sched<[WriteLDIdx, ReadAdrBase]> { 3599 let Inst{13} = 0b1; 3600 } 3601 3602 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3603} 3604 3605multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3606 string asm, ValueType Ty, SDPatternOperator storeop> { 3607 let AddedComplexity = 10 in 3608 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3609 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3610 [(storeop (Ty regtype:$Rt), 3611 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3612 ro_Wextend32:$extend))]>, 3613 Sched<[WriteSTIdx, ReadAdrBase]> { 3614 let Inst{13} = 0b0; 3615 } 3616 3617 let AddedComplexity = 10 in 3618 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3619 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3620 [(storeop (Ty regtype:$Rt), 3621 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3622 ro_Xextend32:$extend))]>, 3623 Sched<[WriteSTIdx, ReadAdrBase]> { 3624 let Inst{13} = 0b1; 3625 } 3626 3627 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3628} 3629 3630class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3631 string asm, dag ins, dag outs, list<dag> pat> 3632 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3633 bits<5> Rt; 3634 bits<5> Rn; 3635 bits<5> Rm; 3636 bits<2> extend; 3637 let Inst{31-30} = sz; 3638 let Inst{29-27} = 0b111; 3639 let Inst{26} = V; 3640 let Inst{25-24} = 0b00; 3641 let Inst{23-22} = opc; 3642 let Inst{21} = 1; 3643 let Inst{20-16} = Rm; 3644 let Inst{15} = extend{1}; // sign extend Rm? 3645 let Inst{14} = 1; 3646 let Inst{12} = extend{0}; // do shift? 3647 let Inst{11-10} = 0b10; 3648 let Inst{9-5} = Rn; 3649 let Inst{4-0} = Rt; 3650} 3651 3652multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3653 string asm, ValueType Ty, SDPatternOperator loadop> { 3654 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3655 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3656 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3657 [(set (Ty regtype:$Rt), 3658 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3659 ro_Wextend64:$extend)))]>, 3660 Sched<[WriteLDIdx, ReadAdrBase]> { 3661 let Inst{13} = 0b0; 3662 } 3663 3664 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3665 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3666 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3667 [(set (Ty regtype:$Rt), 3668 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3669 ro_Xextend64:$extend)))]>, 3670 Sched<[WriteLDIdx, ReadAdrBase]> { 3671 let Inst{13} = 0b1; 3672 } 3673 3674 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3675} 3676 3677multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3678 string asm, ValueType Ty, SDPatternOperator storeop> { 3679 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3680 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3681 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3682 [(storeop (Ty regtype:$Rt), 3683 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3684 ro_Wextend64:$extend))]>, 3685 Sched<[WriteSTIdx, ReadAdrBase]> { 3686 let Inst{13} = 0b0; 3687 } 3688 3689 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3690 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3691 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3692 [(storeop (Ty regtype:$Rt), 3693 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3694 ro_Xextend64:$extend))]>, 3695 Sched<[WriteSTIdx, ReadAdrBase]> { 3696 let Inst{13} = 0b1; 3697 } 3698 3699 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3700} 3701 3702class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3703 string asm, dag ins, dag outs, list<dag> pat> 3704 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3705 bits<5> Rt; 3706 bits<5> Rn; 3707 bits<5> Rm; 3708 bits<2> extend; 3709 let Inst{31-30} = sz; 3710 let Inst{29-27} = 0b111; 3711 let Inst{26} = V; 3712 let Inst{25-24} = 0b00; 3713 let Inst{23-22} = opc; 3714 let Inst{21} = 1; 3715 let Inst{20-16} = Rm; 3716 let Inst{15} = extend{1}; // sign extend Rm? 3717 let Inst{14} = 1; 3718 let Inst{12} = extend{0}; // do shift? 3719 let Inst{11-10} = 0b10; 3720 let Inst{9-5} = Rn; 3721 let Inst{4-0} = Rt; 3722} 3723 3724multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3725 string asm, ValueType Ty, SDPatternOperator loadop> { 3726 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3727 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3728 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3729 [(set (Ty regtype:$Rt), 3730 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3731 ro_Wextend128:$extend)))]>, 3732 Sched<[WriteLDIdx, ReadAdrBase]> { 3733 let Inst{13} = 0b0; 3734 } 3735 3736 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3737 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3738 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3739 [(set (Ty regtype:$Rt), 3740 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3741 ro_Xextend128:$extend)))]>, 3742 Sched<[WriteLDIdx, ReadAdrBase]> { 3743 let Inst{13} = 0b1; 3744 } 3745 3746 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3747} 3748 3749multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3750 string asm, ValueType Ty, SDPatternOperator storeop> { 3751 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3752 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3753 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3754 []>, 3755 Sched<[WriteSTIdx, ReadAdrBase]> { 3756 let Inst{13} = 0b0; 3757 } 3758 3759 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3760 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3761 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3762 []>, 3763 Sched<[WriteSTIdx, ReadAdrBase]> { 3764 let Inst{13} = 0b1; 3765 } 3766 3767 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3768} 3769 3770let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3771class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3772 string asm, list<dag> pat> 3773 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3774 Sched<[WriteLD]> { 3775 bits<5> Rt; 3776 bits<5> Rn; 3777 bits<5> Rm; 3778 bits<2> extend; 3779 let Inst{31-30} = sz; 3780 let Inst{29-27} = 0b111; 3781 let Inst{26} = V; 3782 let Inst{25-24} = 0b00; 3783 let Inst{23-22} = opc; 3784 let Inst{21} = 1; 3785 let Inst{20-16} = Rm; 3786 let Inst{15} = extend{1}; // sign extend Rm? 3787 let Inst{14} = 1; 3788 let Inst{12} = extend{0}; // do shift? 3789 let Inst{11-10} = 0b10; 3790 let Inst{9-5} = Rn; 3791 let Inst{4-0} = Rt; 3792} 3793 3794multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3795 def roW : BasePrefetchRO<sz, V, opc, (outs), 3796 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3797 asm, [(AArch64Prefetch imm:$Rt, 3798 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3799 ro_Wextend64:$extend))]> { 3800 let Inst{13} = 0b0; 3801 } 3802 3803 def roX : BasePrefetchRO<sz, V, opc, (outs), 3804 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3805 asm, [(AArch64Prefetch imm:$Rt, 3806 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3807 ro_Xextend64:$extend))]> { 3808 let Inst{13} = 0b1; 3809 } 3810 3811 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3812 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3813 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3814} 3815 3816//--- 3817// Load/store unscaled immediate 3818//--- 3819 3820def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 3821def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 3822def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 3823def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 3824def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3825 3826def gi_am_unscaled8 : 3827 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3828 GIComplexPatternEquiv<am_unscaled8>; 3829def gi_am_unscaled16 : 3830 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3831 GIComplexPatternEquiv<am_unscaled16>; 3832def gi_am_unscaled32 : 3833 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3834 GIComplexPatternEquiv<am_unscaled32>; 3835def gi_am_unscaled64 : 3836 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3837 GIComplexPatternEquiv<am_unscaled64>; 3838def gi_am_unscaled128 : 3839 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3840 GIComplexPatternEquiv<am_unscaled128>; 3841 3842 3843class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3844 string asm, list<dag> pattern> 3845 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3846 bits<5> Rt; 3847 bits<5> Rn; 3848 bits<9> offset; 3849 let Inst{31-30} = sz; 3850 let Inst{29-27} = 0b111; 3851 let Inst{26} = V; 3852 let Inst{25-24} = 0b00; 3853 let Inst{23-22} = opc; 3854 let Inst{21} = 0; 3855 let Inst{20-12} = offset; 3856 let Inst{11-10} = 0b00; 3857 let Inst{9-5} = Rn; 3858 let Inst{4-0} = Rt; 3859 3860 let DecoderMethod = "DecodeSignedLdStInstruction"; 3861} 3862 3863// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3864multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3865 DAGOperand regtype > { 3866 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3867 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3868 Sched<[WriteST]> { 3869 let Inst{29} = 0; 3870 let Inst{24} = 1; 3871 } 3872 def : InstAlias<asm # "\t$Rt, [$Rn]", 3873 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3874} 3875 3876multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3877 DAGOperand regtype > { 3878 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3879 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3880 asm, []>, 3881 Sched<[WriteST]> { 3882 let Inst{29} = 0; 3883 let Inst{24} = 1; 3884 } 3885 def : InstAlias<asm # "\t$Rt, [$Rn]", 3886 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3887} 3888 3889multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3890 string asm, list<dag> pattern> { 3891 let AddedComplexity = 1 in // try this before LoadUI 3892 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3893 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3894 Sched<[WriteLD]>; 3895 3896 def : InstAlias<asm # "\t$Rt, [$Rn]", 3897 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3898} 3899 3900multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3901 string asm, list<dag> pattern> { 3902 let AddedComplexity = 1 in // try this before StoreUI 3903 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3904 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3905 asm, pattern>, 3906 Sched<[WriteST]>; 3907 3908 def : InstAlias<asm # "\t$Rt, [$Rn]", 3909 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3910} 3911 3912multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3913 list<dag> pat> { 3914 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3915 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3916 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3917 asm, pat>, 3918 Sched<[WriteLD]>; 3919 3920 def : InstAlias<asm # "\t$Rt, [$Rn]", 3921 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3922} 3923 3924//--- 3925// Load/store unscaled immediate, unprivileged 3926//--- 3927 3928class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3929 dag oops, dag iops, string asm> 3930 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3931 bits<5> Rt; 3932 bits<5> Rn; 3933 bits<9> offset; 3934 let Inst{31-30} = sz; 3935 let Inst{29-27} = 0b111; 3936 let Inst{26} = V; 3937 let Inst{25-24} = 0b00; 3938 let Inst{23-22} = opc; 3939 let Inst{21} = 0; 3940 let Inst{20-12} = offset; 3941 let Inst{11-10} = 0b10; 3942 let Inst{9-5} = Rn; 3943 let Inst{4-0} = Rt; 3944 3945 let DecoderMethod = "DecodeSignedLdStInstruction"; 3946} 3947 3948multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3949 RegisterClass regtype, string asm> { 3950 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3951 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3952 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3953 Sched<[WriteLD]>; 3954 3955 def : InstAlias<asm # "\t$Rt, [$Rn]", 3956 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3957} 3958 3959multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3960 RegisterClass regtype, string asm> { 3961 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3962 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3963 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3964 asm>, 3965 Sched<[WriteST]>; 3966 3967 def : InstAlias<asm # "\t$Rt, [$Rn]", 3968 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3969} 3970 3971//--- 3972// Load/store pre-indexed 3973//--- 3974 3975class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3976 string asm, string cstr, list<dag> pat> 3977 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3978 bits<5> Rt; 3979 bits<5> Rn; 3980 bits<9> offset; 3981 let Inst{31-30} = sz; 3982 let Inst{29-27} = 0b111; 3983 let Inst{26} = V; 3984 let Inst{25-24} = 0; 3985 let Inst{23-22} = opc; 3986 let Inst{21} = 0; 3987 let Inst{20-12} = offset; 3988 let Inst{11-10} = 0b11; 3989 let Inst{9-5} = Rn; 3990 let Inst{4-0} = Rt; 3991 3992 let DecoderMethod = "DecodeSignedLdStInstruction"; 3993} 3994 3995let hasSideEffects = 0 in { 3996let mayStore = 0, mayLoad = 1 in 3997class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3998 string asm> 3999 : BaseLoadStorePreIdx<sz, V, opc, 4000 (outs GPR64sp:$wback, regtype:$Rt), 4001 (ins GPR64sp:$Rn, simm9:$offset), asm, 4002 "$Rn = $wback,@earlyclobber $wback", []>, 4003 Sched<[WriteAdr, WriteLD]>; 4004 4005let mayStore = 1, mayLoad = 0 in 4006class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4007 string asm, SDPatternOperator storeop, ValueType Ty> 4008 : BaseLoadStorePreIdx<sz, V, opc, 4009 (outs GPR64sp:$wback), 4010 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4011 asm, "$Rn = $wback,@earlyclobber $wback", 4012 [(set GPR64sp:$wback, 4013 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4014 Sched<[WriteAdr, WriteST]>; 4015} // hasSideEffects = 0 4016 4017//--- 4018// Load/store post-indexed 4019//--- 4020 4021class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4022 string asm, string cstr, list<dag> pat> 4023 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4024 bits<5> Rt; 4025 bits<5> Rn; 4026 bits<9> offset; 4027 let Inst{31-30} = sz; 4028 let Inst{29-27} = 0b111; 4029 let Inst{26} = V; 4030 let Inst{25-24} = 0b00; 4031 let Inst{23-22} = opc; 4032 let Inst{21} = 0b0; 4033 let Inst{20-12} = offset; 4034 let Inst{11-10} = 0b01; 4035 let Inst{9-5} = Rn; 4036 let Inst{4-0} = Rt; 4037 4038 let DecoderMethod = "DecodeSignedLdStInstruction"; 4039} 4040 4041let hasSideEffects = 0 in { 4042let mayStore = 0, mayLoad = 1 in 4043class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4044 string asm> 4045 : BaseLoadStorePostIdx<sz, V, opc, 4046 (outs GPR64sp:$wback, regtype:$Rt), 4047 (ins GPR64sp:$Rn, simm9:$offset), 4048 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4049 Sched<[WriteAdr, WriteLD]>; 4050 4051let mayStore = 1, mayLoad = 0 in 4052class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4053 string asm, SDPatternOperator storeop, ValueType Ty> 4054 : BaseLoadStorePostIdx<sz, V, opc, 4055 (outs GPR64sp:$wback), 4056 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4057 asm, "$Rn = $wback,@earlyclobber $wback", 4058 [(set GPR64sp:$wback, 4059 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4060 Sched<[WriteAdr, WriteST]>; 4061} // hasSideEffects = 0 4062 4063 4064//--- 4065// Load/store pair 4066//--- 4067 4068// (indexed, offset) 4069 4070class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4071 string asm> 4072 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4073 bits<5> Rt; 4074 bits<5> Rt2; 4075 bits<5> Rn; 4076 bits<7> offset; 4077 let Inst{31-30} = opc; 4078 let Inst{29-27} = 0b101; 4079 let Inst{26} = V; 4080 let Inst{25-23} = 0b010; 4081 let Inst{22} = L; 4082 let Inst{21-15} = offset; 4083 let Inst{14-10} = Rt2; 4084 let Inst{9-5} = Rn; 4085 let Inst{4-0} = Rt; 4086 4087 let DecoderMethod = "DecodePairLdStInstruction"; 4088} 4089 4090multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4091 Operand indextype, string asm> { 4092 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4093 def i : BaseLoadStorePairOffset<opc, V, 1, 4094 (outs regtype:$Rt, regtype:$Rt2), 4095 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4096 Sched<[WriteLD, WriteLDHi]>; 4097 4098 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4099 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4100 GPR64sp:$Rn, 0)>; 4101} 4102 4103 4104multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4105 Operand indextype, string asm> { 4106 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4107 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4108 (ins regtype:$Rt, regtype:$Rt2, 4109 GPR64sp:$Rn, indextype:$offset), 4110 asm>, 4111 Sched<[WriteSTP]>; 4112 4113 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4114 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4115 GPR64sp:$Rn, 0)>; 4116} 4117 4118// (pre-indexed) 4119class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4120 string asm> 4121 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4122 bits<5> Rt; 4123 bits<5> Rt2; 4124 bits<5> Rn; 4125 bits<7> offset; 4126 let Inst{31-30} = opc; 4127 let Inst{29-27} = 0b101; 4128 let Inst{26} = V; 4129 let Inst{25-23} = 0b011; 4130 let Inst{22} = L; 4131 let Inst{21-15} = offset; 4132 let Inst{14-10} = Rt2; 4133 let Inst{9-5} = Rn; 4134 let Inst{4-0} = Rt; 4135 4136 let DecoderMethod = "DecodePairLdStInstruction"; 4137} 4138 4139let hasSideEffects = 0 in { 4140let mayStore = 0, mayLoad = 1 in 4141class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4142 Operand indextype, string asm> 4143 : BaseLoadStorePairPreIdx<opc, V, 1, 4144 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4145 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4146 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4147 4148let mayStore = 1, mayLoad = 0 in 4149class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4150 Operand indextype, string asm> 4151 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4152 (ins regtype:$Rt, regtype:$Rt2, 4153 GPR64sp:$Rn, indextype:$offset), 4154 asm>, 4155 Sched<[WriteAdr, WriteSTP]>; 4156} // hasSideEffects = 0 4157 4158// (post-indexed) 4159 4160class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4161 string asm> 4162 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4163 bits<5> Rt; 4164 bits<5> Rt2; 4165 bits<5> Rn; 4166 bits<7> offset; 4167 let Inst{31-30} = opc; 4168 let Inst{29-27} = 0b101; 4169 let Inst{26} = V; 4170 let Inst{25-23} = 0b001; 4171 let Inst{22} = L; 4172 let Inst{21-15} = offset; 4173 let Inst{14-10} = Rt2; 4174 let Inst{9-5} = Rn; 4175 let Inst{4-0} = Rt; 4176 4177 let DecoderMethod = "DecodePairLdStInstruction"; 4178} 4179 4180let hasSideEffects = 0 in { 4181let mayStore = 0, mayLoad = 1 in 4182class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4183 Operand idxtype, string asm> 4184 : BaseLoadStorePairPostIdx<opc, V, 1, 4185 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4186 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4187 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4188 4189let mayStore = 1, mayLoad = 0 in 4190class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4191 Operand idxtype, string asm> 4192 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4193 (ins regtype:$Rt, regtype:$Rt2, 4194 GPR64sp:$Rn, idxtype:$offset), 4195 asm>, 4196 Sched<[WriteAdr, WriteSTP]>; 4197} // hasSideEffects = 0 4198 4199// (no-allocate) 4200 4201class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4202 string asm> 4203 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4204 bits<5> Rt; 4205 bits<5> Rt2; 4206 bits<5> Rn; 4207 bits<7> offset; 4208 let Inst{31-30} = opc; 4209 let Inst{29-27} = 0b101; 4210 let Inst{26} = V; 4211 let Inst{25-23} = 0b000; 4212 let Inst{22} = L; 4213 let Inst{21-15} = offset; 4214 let Inst{14-10} = Rt2; 4215 let Inst{9-5} = Rn; 4216 let Inst{4-0} = Rt; 4217 4218 let DecoderMethod = "DecodePairLdStInstruction"; 4219} 4220 4221multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4222 Operand indextype, string asm> { 4223 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4224 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4225 (outs regtype:$Rt, regtype:$Rt2), 4226 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4227 Sched<[WriteLD, WriteLDHi]>; 4228 4229 4230 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4231 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4232 GPR64sp:$Rn, 0)>; 4233} 4234 4235multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4236 Operand indextype, string asm> { 4237 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4238 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4239 (ins regtype:$Rt, regtype:$Rt2, 4240 GPR64sp:$Rn, indextype:$offset), 4241 asm>, 4242 Sched<[WriteSTP]>; 4243 4244 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4245 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4246 GPR64sp:$Rn, 0)>; 4247} 4248 4249//--- 4250// Load/store exclusive 4251//--- 4252 4253// True exclusive operations write to and/or read from the system's exclusive 4254// monitors, which as far as a compiler is concerned can be modelled as a 4255// random shared memory address. Hence LoadExclusive mayStore. 4256// 4257// Since these instructions have the undefined register bits set to 1 in 4258// their canonical form, we need a post encoder method to set those bits 4259// to 1 when encoding these instructions. We do this using the 4260// fixLoadStoreExclusive function. This function has template parameters: 4261// 4262// fixLoadStoreExclusive<int hasRs, int hasRt2> 4263// 4264// hasRs indicates that the instruction uses the Rs field, so we won't set 4265// it to 1 (and the same for Rt2). We don't need template parameters for 4266// the other register fields since Rt and Rn are always used. 4267// 4268let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4269class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4270 dag oops, dag iops, string asm, string operands> 4271 : I<oops, iops, asm, operands, "", []> { 4272 let Inst{31-30} = sz; 4273 let Inst{29-24} = 0b001000; 4274 let Inst{23} = o2; 4275 let Inst{22} = L; 4276 let Inst{21} = o1; 4277 let Inst{15} = o0; 4278 4279 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4280} 4281 4282// Neither Rs nor Rt2 operands. 4283class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4284 dag oops, dag iops, string asm, string operands> 4285 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4286 bits<5> Rt; 4287 bits<5> Rn; 4288 let Inst{20-16} = 0b11111; 4289 let Unpredictable{20-16} = 0b11111; 4290 let Inst{14-10} = 0b11111; 4291 let Unpredictable{14-10} = 0b11111; 4292 let Inst{9-5} = Rn; 4293 let Inst{4-0} = Rt; 4294 4295 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4296} 4297 4298// Simple load acquires don't set the exclusive monitor 4299let mayLoad = 1, mayStore = 0 in 4300class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4301 RegisterClass regtype, string asm> 4302 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4303 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4304 Sched<[WriteLD]>; 4305 4306class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4307 RegisterClass regtype, string asm> 4308 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4309 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4310 Sched<[WriteLD]>; 4311 4312class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4313 RegisterClass regtype, string asm> 4314 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4315 (outs regtype:$Rt, regtype:$Rt2), 4316 (ins GPR64sp0:$Rn), asm, 4317 "\t$Rt, $Rt2, [$Rn]">, 4318 Sched<[WriteLD, WriteLDHi]> { 4319 bits<5> Rt; 4320 bits<5> Rt2; 4321 bits<5> Rn; 4322 let Inst{14-10} = Rt2; 4323 let Inst{9-5} = Rn; 4324 let Inst{4-0} = Rt; 4325 4326 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4327} 4328 4329// Simple store release operations do not check the exclusive monitor. 4330let mayLoad = 0, mayStore = 1 in 4331class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4332 RegisterClass regtype, string asm> 4333 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4334 (ins regtype:$Rt, GPR64sp0:$Rn), 4335 asm, "\t$Rt, [$Rn]">, 4336 Sched<[WriteST]>; 4337 4338let mayLoad = 1, mayStore = 1 in 4339class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4340 RegisterClass regtype, string asm> 4341 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4342 (ins regtype:$Rt, GPR64sp0:$Rn), 4343 asm, "\t$Ws, $Rt, [$Rn]">, 4344 Sched<[WriteSTX]> { 4345 bits<5> Ws; 4346 bits<5> Rt; 4347 bits<5> Rn; 4348 let Inst{20-16} = Ws; 4349 let Inst{9-5} = Rn; 4350 let Inst{4-0} = Rt; 4351 4352 let Constraints = "@earlyclobber $Ws"; 4353 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4354} 4355 4356class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4357 RegisterClass regtype, string asm> 4358 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4359 (outs GPR32:$Ws), 4360 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4361 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4362 Sched<[WriteSTX]> { 4363 bits<5> Ws; 4364 bits<5> Rt; 4365 bits<5> Rt2; 4366 bits<5> Rn; 4367 let Inst{20-16} = Ws; 4368 let Inst{14-10} = Rt2; 4369 let Inst{9-5} = Rn; 4370 let Inst{4-0} = Rt; 4371 4372 let Constraints = "@earlyclobber $Ws"; 4373} 4374 4375// Armv8.5-A Memory Tagging Extension 4376class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4377 string asm_opnds, string cstr, dag oops, dag iops> 4378 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4379 Sched<[]> { 4380 bits<5> Rn; 4381 4382 let Inst{31-24} = 0b11011001; 4383 let Inst{23-22} = opc1; 4384 let Inst{21} = 1; 4385 // Inst{20-12} defined by subclass 4386 let Inst{11-10} = opc2; 4387 let Inst{9-5} = Rn; 4388 // Inst{4-0} defined by subclass 4389} 4390 4391class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4392 dag oops, dag iops> 4393 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4394 "", oops, iops> { 4395 bits<5> Rt; 4396 4397 let Inst{20-12} = 0b000000000; 4398 let Inst{4-0} = Rt; 4399 4400 let mayLoad = Load; 4401} 4402 4403class MemTagLoad<string asm_insn, string asm_opnds> 4404 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4405 (outs GPR64:$wback), 4406 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4407 bits<5> Rt; 4408 bits<9> offset; 4409 4410 let Inst{20-12} = offset; 4411 let Inst{4-0} = Rt; 4412 4413 let mayLoad = 1; 4414} 4415 4416class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4417 string asm_opnds, string cstr, dag oops, dag iops> 4418 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4419 bits<5> Rt; 4420 bits<9> offset; 4421 4422 let Inst{20-12} = offset; 4423 let Inst{4-0} = Rt; 4424 4425 let mayStore = 1; 4426} 4427 4428multiclass MemTagStore<bits<2> opc1, string insn> { 4429 def Offset : 4430 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4431 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4432 def PreIndex : 4433 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4434 "$Rn = $wback", 4435 (outs GPR64sp:$wback), 4436 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4437 def PostIndex : 4438 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4439 "$Rn = $wback", 4440 (outs GPR64sp:$wback), 4441 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4442 4443 def : InstAlias<insn # "\t$Rt, [$Rn]", 4444 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4445} 4446 4447//--- 4448// Exception generation 4449//--- 4450 4451let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4452class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4453 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>, 4454 Sched<[WriteSys]> { 4455 bits<16> imm; 4456 let Inst{31-24} = 0b11010100; 4457 let Inst{23-21} = op1; 4458 let Inst{20-5} = imm; 4459 let Inst{4-2} = 0b000; 4460 let Inst{1-0} = ll; 4461} 4462 4463//--- 4464// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4465//-- 4466let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4467class UDFType<bits<16> opc, string asm> 4468 : I<(outs), (ins uimm16:$imm), 4469 asm, "\t$imm", "", []>, 4470 Sched<[]> { 4471 bits<16> imm; 4472 let Inst{31-16} = opc; 4473 let Inst{15-0} = imm; 4474} 4475} 4476let Predicates = [HasFPARMv8] in { 4477 4478//--- 4479// Floating point to integer conversion 4480//--- 4481 4482class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4483 RegisterClass srcType, RegisterClass dstType, 4484 string asm, list<dag> pattern> 4485 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4486 asm, "\t$Rd, $Rn", "", pattern>, 4487 Sched<[WriteFCvt]> { 4488 bits<5> Rd; 4489 bits<5> Rn; 4490 let Inst{30-29} = 0b00; 4491 let Inst{28-24} = 0b11110; 4492 let Inst{23-22} = type; 4493 let Inst{21} = 1; 4494 let Inst{20-19} = rmode; 4495 let Inst{18-16} = opcode; 4496 let Inst{15-10} = 0; 4497 let Inst{9-5} = Rn; 4498 let Inst{4-0} = Rd; 4499} 4500 4501let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4502class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4503 RegisterClass srcType, RegisterClass dstType, 4504 Operand immType, string asm, list<dag> pattern> 4505 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4506 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4507 Sched<[WriteFCvt]> { 4508 bits<5> Rd; 4509 bits<5> Rn; 4510 bits<6> scale; 4511 let Inst{30-29} = 0b00; 4512 let Inst{28-24} = 0b11110; 4513 let Inst{23-22} = type; 4514 let Inst{21} = 0; 4515 let Inst{20-19} = rmode; 4516 let Inst{18-16} = opcode; 4517 let Inst{15-10} = scale; 4518 let Inst{9-5} = Rn; 4519 let Inst{4-0} = Rd; 4520} 4521 4522multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4523 SDPatternOperator OpN> { 4524 // Unscaled half-precision to 32-bit 4525 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4526 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4527 let Inst{31} = 0; // 32-bit GPR flag 4528 let Predicates = [HasFullFP16]; 4529 } 4530 4531 // Unscaled half-precision to 64-bit 4532 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4533 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4534 let Inst{31} = 1; // 64-bit GPR flag 4535 let Predicates = [HasFullFP16]; 4536 } 4537 4538 // Unscaled single-precision to 32-bit 4539 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4540 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4541 let Inst{31} = 0; // 32-bit GPR flag 4542 } 4543 4544 // Unscaled single-precision to 64-bit 4545 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4546 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4547 let Inst{31} = 1; // 64-bit GPR flag 4548 } 4549 4550 // Unscaled double-precision to 32-bit 4551 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4552 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4553 let Inst{31} = 0; // 32-bit GPR flag 4554 } 4555 4556 // Unscaled double-precision to 64-bit 4557 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4558 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4559 let Inst{31} = 1; // 64-bit GPR flag 4560 } 4561} 4562 4563multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4564 SDPatternOperator OpN> { 4565 // Scaled half-precision to 32-bit 4566 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4567 fixedpoint_f16_i32, asm, 4568 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4569 fixedpoint_f16_i32:$scale)))]> { 4570 let Inst{31} = 0; // 32-bit GPR flag 4571 let scale{5} = 1; 4572 let Predicates = [HasFullFP16]; 4573 } 4574 4575 // Scaled half-precision to 64-bit 4576 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4577 fixedpoint_f16_i64, asm, 4578 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4579 fixedpoint_f16_i64:$scale)))]> { 4580 let Inst{31} = 1; // 64-bit GPR flag 4581 let Predicates = [HasFullFP16]; 4582 } 4583 4584 // Scaled single-precision to 32-bit 4585 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4586 fixedpoint_f32_i32, asm, 4587 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4588 fixedpoint_f32_i32:$scale)))]> { 4589 let Inst{31} = 0; // 32-bit GPR flag 4590 let scale{5} = 1; 4591 } 4592 4593 // Scaled single-precision to 64-bit 4594 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4595 fixedpoint_f32_i64, asm, 4596 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4597 fixedpoint_f32_i64:$scale)))]> { 4598 let Inst{31} = 1; // 64-bit GPR flag 4599 } 4600 4601 // Scaled double-precision to 32-bit 4602 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4603 fixedpoint_f64_i32, asm, 4604 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4605 fixedpoint_f64_i32:$scale)))]> { 4606 let Inst{31} = 0; // 32-bit GPR flag 4607 let scale{5} = 1; 4608 } 4609 4610 // Scaled double-precision to 64-bit 4611 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4612 fixedpoint_f64_i64, asm, 4613 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4614 fixedpoint_f64_i64:$scale)))]> { 4615 let Inst{31} = 1; // 64-bit GPR flag 4616 } 4617} 4618 4619//--- 4620// Integer to floating point conversion 4621//--- 4622 4623let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4624class BaseIntegerToFP<bit isUnsigned, 4625 RegisterClass srcType, RegisterClass dstType, 4626 Operand immType, string asm, list<dag> pattern> 4627 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4628 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4629 Sched<[WriteFCvt]> { 4630 bits<5> Rd; 4631 bits<5> Rn; 4632 bits<6> scale; 4633 let Inst{30-24} = 0b0011110; 4634 let Inst{21-17} = 0b00001; 4635 let Inst{16} = isUnsigned; 4636 let Inst{15-10} = scale; 4637 let Inst{9-5} = Rn; 4638 let Inst{4-0} = Rd; 4639} 4640 4641class BaseIntegerToFPUnscaled<bit isUnsigned, 4642 RegisterClass srcType, RegisterClass dstType, 4643 ValueType dvt, string asm, SDPatternOperator node> 4644 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4645 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4646 Sched<[WriteFCvt]> { 4647 bits<5> Rd; 4648 bits<5> Rn; 4649 bits<6> scale; 4650 let Inst{30-24} = 0b0011110; 4651 let Inst{21-17} = 0b10001; 4652 let Inst{16} = isUnsigned; 4653 let Inst{15-10} = 0b000000; 4654 let Inst{9-5} = Rn; 4655 let Inst{4-0} = Rd; 4656} 4657 4658multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4659 // Unscaled 4660 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4661 let Inst{31} = 0; // 32-bit GPR flag 4662 let Inst{23-22} = 0b11; // 16-bit FPR flag 4663 let Predicates = [HasFullFP16]; 4664 } 4665 4666 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4667 let Inst{31} = 0; // 32-bit GPR flag 4668 let Inst{23-22} = 0b00; // 32-bit FPR flag 4669 } 4670 4671 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4672 let Inst{31} = 0; // 32-bit GPR flag 4673 let Inst{23-22} = 0b01; // 64-bit FPR flag 4674 } 4675 4676 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4677 let Inst{31} = 1; // 64-bit GPR flag 4678 let Inst{23-22} = 0b11; // 16-bit FPR flag 4679 let Predicates = [HasFullFP16]; 4680 } 4681 4682 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4683 let Inst{31} = 1; // 64-bit GPR flag 4684 let Inst{23-22} = 0b00; // 32-bit FPR flag 4685 } 4686 4687 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4688 let Inst{31} = 1; // 64-bit GPR flag 4689 let Inst{23-22} = 0b01; // 64-bit FPR flag 4690 } 4691 4692 // Scaled 4693 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4694 [(set (f16 FPR16:$Rd), 4695 (fdiv (node GPR32:$Rn), 4696 fixedpoint_f16_i32:$scale))]> { 4697 let Inst{31} = 0; // 32-bit GPR flag 4698 let Inst{23-22} = 0b11; // 16-bit FPR flag 4699 let scale{5} = 1; 4700 let Predicates = [HasFullFP16]; 4701 } 4702 4703 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4704 [(set FPR32:$Rd, 4705 (fdiv (node GPR32:$Rn), 4706 fixedpoint_f32_i32:$scale))]> { 4707 let Inst{31} = 0; // 32-bit GPR flag 4708 let Inst{23-22} = 0b00; // 32-bit FPR flag 4709 let scale{5} = 1; 4710 } 4711 4712 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4713 [(set FPR64:$Rd, 4714 (fdiv (node GPR32:$Rn), 4715 fixedpoint_f64_i32:$scale))]> { 4716 let Inst{31} = 0; // 32-bit GPR flag 4717 let Inst{23-22} = 0b01; // 64-bit FPR flag 4718 let scale{5} = 1; 4719 } 4720 4721 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4722 [(set (f16 FPR16:$Rd), 4723 (fdiv (node GPR64:$Rn), 4724 fixedpoint_f16_i64:$scale))]> { 4725 let Inst{31} = 1; // 64-bit GPR flag 4726 let Inst{23-22} = 0b11; // 16-bit FPR flag 4727 let Predicates = [HasFullFP16]; 4728 } 4729 4730 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4731 [(set FPR32:$Rd, 4732 (fdiv (node GPR64:$Rn), 4733 fixedpoint_f32_i64:$scale))]> { 4734 let Inst{31} = 1; // 64-bit GPR flag 4735 let Inst{23-22} = 0b00; // 32-bit FPR flag 4736 } 4737 4738 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4739 [(set FPR64:$Rd, 4740 (fdiv (node GPR64:$Rn), 4741 fixedpoint_f64_i64:$scale))]> { 4742 let Inst{31} = 1; // 64-bit GPR flag 4743 let Inst{23-22} = 0b01; // 64-bit FPR flag 4744 } 4745} 4746 4747//--- 4748// Unscaled integer <-> floating point conversion (i.e. FMOV) 4749//--- 4750 4751let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4752class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4753 RegisterClass srcType, RegisterClass dstType, 4754 string asm> 4755 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4756 // We use COPY_TO_REGCLASS for these bitconvert operations. 4757 // copyPhysReg() expands the resultant COPY instructions after 4758 // regalloc is done. This gives greater freedom for the allocator 4759 // and related passes (coalescing, copy propagation, et. al.) to 4760 // be more effective. 4761 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4762 Sched<[WriteFCopy]> { 4763 bits<5> Rd; 4764 bits<5> Rn; 4765 let Inst{30-24} = 0b0011110; 4766 let Inst{21} = 1; 4767 let Inst{20-19} = rmode; 4768 let Inst{18-16} = opcode; 4769 let Inst{15-10} = 0b000000; 4770 let Inst{9-5} = Rn; 4771 let Inst{4-0} = Rd; 4772} 4773 4774let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4775class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4776 RegisterClass srcType, RegisterOperand dstType, string asm, 4777 string kind> 4778 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4779 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4780 Sched<[WriteFCopy]> { 4781 bits<5> Rd; 4782 bits<5> Rn; 4783 let Inst{30-23} = 0b00111101; 4784 let Inst{21} = 1; 4785 let Inst{20-19} = rmode; 4786 let Inst{18-16} = opcode; 4787 let Inst{15-10} = 0b000000; 4788 let Inst{9-5} = Rn; 4789 let Inst{4-0} = Rd; 4790 4791 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4792} 4793 4794let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4795class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4796 RegisterOperand srcType, RegisterClass dstType, string asm, 4797 string kind> 4798 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4799 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4800 Sched<[WriteFCopy]> { 4801 bits<5> Rd; 4802 bits<5> Rn; 4803 let Inst{30-23} = 0b00111101; 4804 let Inst{21} = 1; 4805 let Inst{20-19} = rmode; 4806 let Inst{18-16} = opcode; 4807 let Inst{15-10} = 0b000000; 4808 let Inst{9-5} = Rn; 4809 let Inst{4-0} = Rd; 4810 4811 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4812} 4813 4814 4815multiclass UnscaledConversion<string asm> { 4816 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4817 let Inst{31} = 0; // 32-bit GPR flag 4818 let Inst{23-22} = 0b11; // 16-bit FPR flag 4819 let Predicates = [HasFullFP16]; 4820 } 4821 4822 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4823 let Inst{31} = 1; // 64-bit GPR flag 4824 let Inst{23-22} = 0b11; // 16-bit FPR flag 4825 let Predicates = [HasFullFP16]; 4826 } 4827 4828 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4829 let Inst{31} = 0; // 32-bit GPR flag 4830 let Inst{23-22} = 0b00; // 32-bit FPR flag 4831 } 4832 4833 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4834 let Inst{31} = 1; // 64-bit GPR flag 4835 let Inst{23-22} = 0b01; // 64-bit FPR flag 4836 } 4837 4838 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4839 let Inst{31} = 0; // 32-bit GPR flag 4840 let Inst{23-22} = 0b11; // 16-bit FPR flag 4841 let Predicates = [HasFullFP16]; 4842 } 4843 4844 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4845 let Inst{31} = 1; // 64-bit GPR flag 4846 let Inst{23-22} = 0b11; // 16-bit FPR flag 4847 let Predicates = [HasFullFP16]; 4848 } 4849 4850 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4851 let Inst{31} = 0; // 32-bit GPR flag 4852 let Inst{23-22} = 0b00; // 32-bit FPR flag 4853 } 4854 4855 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4856 let Inst{31} = 1; // 64-bit GPR flag 4857 let Inst{23-22} = 0b01; // 64-bit FPR flag 4858 } 4859 4860 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4861 asm, ".d"> { 4862 let Inst{31} = 1; 4863 let Inst{22} = 0; 4864 } 4865 4866 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4867 asm, ".d"> { 4868 let Inst{31} = 1; 4869 let Inst{22} = 0; 4870 } 4871} 4872 4873//--- 4874// Floating point conversion 4875//--- 4876 4877class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4878 RegisterClass srcType, string asm, list<dag> pattern> 4879 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4880 Sched<[WriteFCvt]> { 4881 bits<5> Rd; 4882 bits<5> Rn; 4883 let Inst{31-24} = 0b00011110; 4884 let Inst{23-22} = type; 4885 let Inst{21-17} = 0b10001; 4886 let Inst{16-15} = opcode; 4887 let Inst{14-10} = 0b10000; 4888 let Inst{9-5} = Rn; 4889 let Inst{4-0} = Rd; 4890} 4891 4892multiclass FPConversion<string asm> { 4893 // Double-precision to Half-precision 4894 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4895 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4896 4897 // Double-precision to Single-precision 4898 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4899 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4900 4901 // Half-precision to Double-precision 4902 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4903 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4904 4905 // Half-precision to Single-precision 4906 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4907 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4908 4909 // Single-precision to Double-precision 4910 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4911 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4912 4913 // Single-precision to Half-precision 4914 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4915 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 4916} 4917 4918//--- 4919// Single operand floating point data processing 4920//--- 4921 4922let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4923class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4924 ValueType vt, string asm, SDPatternOperator node> 4925 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4926 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4927 Sched<[WriteF]> { 4928 bits<5> Rd; 4929 bits<5> Rn; 4930 let Inst{31-24} = 0b00011110; 4931 let Inst{21} = 0b1; 4932 let Inst{20-15} = opcode; 4933 let Inst{14-10} = 0b10000; 4934 let Inst{9-5} = Rn; 4935 let Inst{4-0} = Rd; 4936} 4937 4938multiclass SingleOperandFPData<bits<4> opcode, string asm, 4939 SDPatternOperator node = null_frag> { 4940 4941 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 4942 let Inst{23-22} = 0b11; // 16-bit size flag 4943 let Predicates = [HasFullFP16]; 4944 } 4945 4946 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 4947 let Inst{23-22} = 0b00; // 32-bit size flag 4948 } 4949 4950 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 4951 let Inst{23-22} = 0b01; // 64-bit size flag 4952 } 4953} 4954 4955multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 4956 SDPatternOperator node = null_frag>{ 4957 4958 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 4959 let Inst{23-22} = 0b00; // 32-bit registers 4960 } 4961 4962 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 4963 let Inst{23-22} = 0b01; // 64-bit registers 4964 } 4965} 4966 4967// FRInt[32|64][Z|N] instructions 4968multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 4969 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 4970 4971//--- 4972// Two operand floating point data processing 4973//--- 4974 4975let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4976class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4977 string asm, list<dag> pat> 4978 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4979 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4980 Sched<[WriteF]> { 4981 bits<5> Rd; 4982 bits<5> Rn; 4983 bits<5> Rm; 4984 let Inst{31-24} = 0b00011110; 4985 let Inst{21} = 1; 4986 let Inst{20-16} = Rm; 4987 let Inst{15-12} = opcode; 4988 let Inst{11-10} = 0b10; 4989 let Inst{9-5} = Rn; 4990 let Inst{4-0} = Rd; 4991} 4992 4993multiclass TwoOperandFPData<bits<4> opcode, string asm, 4994 SDPatternOperator node = null_frag> { 4995 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4996 [(set (f16 FPR16:$Rd), 4997 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4998 let Inst{23-22} = 0b11; // 16-bit size flag 4999 let Predicates = [HasFullFP16]; 5000 } 5001 5002 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5003 [(set (f32 FPR32:$Rd), 5004 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5005 let Inst{23-22} = 0b00; // 32-bit size flag 5006 } 5007 5008 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5009 [(set (f64 FPR64:$Rd), 5010 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5011 let Inst{23-22} = 0b01; // 64-bit size flag 5012 } 5013} 5014 5015multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 5016 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5017 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5018 let Inst{23-22} = 0b11; // 16-bit size flag 5019 let Predicates = [HasFullFP16]; 5020 } 5021 5022 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5023 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5024 let Inst{23-22} = 0b00; // 32-bit size flag 5025 } 5026 5027 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5028 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5029 let Inst{23-22} = 0b01; // 64-bit size flag 5030 } 5031} 5032 5033 5034//--- 5035// Three operand floating point data processing 5036//--- 5037 5038class BaseThreeOperandFPData<bit isNegated, bit isSub, 5039 RegisterClass regtype, string asm, list<dag> pat> 5040 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5041 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5042 Sched<[WriteFMul]> { 5043 bits<5> Rd; 5044 bits<5> Rn; 5045 bits<5> Rm; 5046 bits<5> Ra; 5047 let Inst{31-24} = 0b00011111; 5048 let Inst{21} = isNegated; 5049 let Inst{20-16} = Rm; 5050 let Inst{15} = isSub; 5051 let Inst{14-10} = Ra; 5052 let Inst{9-5} = Rn; 5053 let Inst{4-0} = Rd; 5054} 5055 5056multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5057 SDPatternOperator node> { 5058 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5059 [(set (f16 FPR16:$Rd), 5060 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5061 let Inst{23-22} = 0b11; // 16-bit size flag 5062 let Predicates = [HasFullFP16]; 5063 } 5064 5065 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5066 [(set FPR32:$Rd, 5067 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5068 let Inst{23-22} = 0b00; // 32-bit size flag 5069 } 5070 5071 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5072 [(set FPR64:$Rd, 5073 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5074 let Inst{23-22} = 0b01; // 64-bit size flag 5075 } 5076} 5077 5078//--- 5079// Floating point data comparisons 5080//--- 5081 5082let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5083class BaseOneOperandFPComparison<bit signalAllNans, 5084 RegisterClass regtype, string asm, 5085 list<dag> pat> 5086 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5087 Sched<[WriteFCmp]> { 5088 bits<5> Rn; 5089 let Inst{31-24} = 0b00011110; 5090 let Inst{21} = 1; 5091 5092 let Inst{15-10} = 0b001000; 5093 let Inst{9-5} = Rn; 5094 let Inst{4} = signalAllNans; 5095 let Inst{3-0} = 0b1000; 5096 5097 // Rm should be 0b00000 canonically, but we need to accept any value. 5098 let PostEncoderMethod = "fixOneOperandFPComparison"; 5099} 5100 5101let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5102class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5103 string asm, list<dag> pat> 5104 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5105 Sched<[WriteFCmp]> { 5106 bits<5> Rm; 5107 bits<5> Rn; 5108 let Inst{31-24} = 0b00011110; 5109 let Inst{21} = 1; 5110 let Inst{20-16} = Rm; 5111 let Inst{15-10} = 0b001000; 5112 let Inst{9-5} = Rn; 5113 let Inst{4} = signalAllNans; 5114 let Inst{3-0} = 0b0000; 5115} 5116 5117multiclass FPComparison<bit signalAllNans, string asm, 5118 SDPatternOperator OpNode = null_frag> { 5119 let Defs = [NZCV] in { 5120 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5121 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5122 let Inst{23-22} = 0b11; 5123 let Predicates = [HasFullFP16]; 5124 } 5125 5126 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5127 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5128 let Inst{23-22} = 0b11; 5129 let Predicates = [HasFullFP16]; 5130 } 5131 5132 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5133 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5134 let Inst{23-22} = 0b00; 5135 } 5136 5137 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5138 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5139 let Inst{23-22} = 0b00; 5140 } 5141 5142 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5143 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5144 let Inst{23-22} = 0b01; 5145 } 5146 5147 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5148 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5149 let Inst{23-22} = 0b01; 5150 } 5151 } // Defs = [NZCV] 5152} 5153 5154//--- 5155// Floating point conditional comparisons 5156//--- 5157 5158let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5159class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5160 string mnemonic, list<dag> pat> 5161 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5162 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5163 Sched<[WriteFCmp]> { 5164 let Uses = [NZCV]; 5165 let Defs = [NZCV]; 5166 5167 bits<5> Rn; 5168 bits<5> Rm; 5169 bits<4> nzcv; 5170 bits<4> cond; 5171 5172 let Inst{31-24} = 0b00011110; 5173 let Inst{21} = 1; 5174 let Inst{20-16} = Rm; 5175 let Inst{15-12} = cond; 5176 let Inst{11-10} = 0b01; 5177 let Inst{9-5} = Rn; 5178 let Inst{4} = signalAllNans; 5179 let Inst{3-0} = nzcv; 5180} 5181 5182multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5183 SDPatternOperator OpNode = null_frag> { 5184 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5185 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5186 (i32 imm:$cond), NZCV))]> { 5187 let Inst{23-22} = 0b11; 5188 let Predicates = [HasFullFP16]; 5189 } 5190 5191 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5192 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5193 (i32 imm:$cond), NZCV))]> { 5194 let Inst{23-22} = 0b00; 5195 } 5196 5197 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5198 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5199 (i32 imm:$cond), NZCV))]> { 5200 let Inst{23-22} = 0b01; 5201 } 5202} 5203 5204//--- 5205// Floating point conditional select 5206//--- 5207 5208class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5209 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5210 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5211 [(set regtype:$Rd, 5212 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5213 (i32 imm:$cond), NZCV))]>, 5214 Sched<[WriteF]> { 5215 bits<5> Rd; 5216 bits<5> Rn; 5217 bits<5> Rm; 5218 bits<4> cond; 5219 5220 let Inst{31-24} = 0b00011110; 5221 let Inst{21} = 1; 5222 let Inst{20-16} = Rm; 5223 let Inst{15-12} = cond; 5224 let Inst{11-10} = 0b11; 5225 let Inst{9-5} = Rn; 5226 let Inst{4-0} = Rd; 5227} 5228 5229multiclass FPCondSelect<string asm> { 5230 let Uses = [NZCV] in { 5231 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5232 let Inst{23-22} = 0b11; 5233 let Predicates = [HasFullFP16]; 5234 } 5235 5236 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5237 let Inst{23-22} = 0b00; 5238 } 5239 5240 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5241 let Inst{23-22} = 0b01; 5242 } 5243 } // Uses = [NZCV] 5244} 5245 5246//--- 5247// Floating move immediate 5248//--- 5249 5250class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5251 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5252 [(set regtype:$Rd, fpimmtype:$imm)]>, 5253 Sched<[WriteFImm]> { 5254 bits<5> Rd; 5255 bits<8> imm; 5256 let Inst{31-24} = 0b00011110; 5257 let Inst{21} = 1; 5258 let Inst{20-13} = imm; 5259 let Inst{12-5} = 0b10000000; 5260 let Inst{4-0} = Rd; 5261} 5262 5263multiclass FPMoveImmediate<string asm> { 5264 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5265 let Inst{23-22} = 0b11; 5266 let Predicates = [HasFullFP16]; 5267 } 5268 5269 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5270 let Inst{23-22} = 0b00; 5271 } 5272 5273 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5274 let Inst{23-22} = 0b01; 5275 } 5276} 5277} // end of 'let Predicates = [HasFPARMv8]' 5278 5279//---------------------------------------------------------------------------- 5280// AdvSIMD 5281//---------------------------------------------------------------------------- 5282 5283let Predicates = [HasNEON] in { 5284 5285//---------------------------------------------------------------------------- 5286// AdvSIMD three register vector instructions 5287//---------------------------------------------------------------------------- 5288 5289let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5290class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5291 RegisterOperand regtype, string asm, string kind, 5292 list<dag> pattern> 5293 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5294 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5295 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5296 Sched<[WriteV]> { 5297 bits<5> Rd; 5298 bits<5> Rn; 5299 bits<5> Rm; 5300 let Inst{31} = 0; 5301 let Inst{30} = Q; 5302 let Inst{29} = U; 5303 let Inst{28-24} = 0b01110; 5304 let Inst{23-21} = size; 5305 let Inst{20-16} = Rm; 5306 let Inst{15-11} = opcode; 5307 let Inst{10} = 1; 5308 let Inst{9-5} = Rn; 5309 let Inst{4-0} = Rd; 5310} 5311 5312let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5313class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5314 RegisterOperand regtype, string asm, string kind, 5315 list<dag> pattern> 5316 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5317 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5318 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5319 Sched<[WriteV]> { 5320 bits<5> Rd; 5321 bits<5> Rn; 5322 bits<5> Rm; 5323 let Inst{31} = 0; 5324 let Inst{30} = Q; 5325 let Inst{29} = U; 5326 let Inst{28-24} = 0b01110; 5327 let Inst{23-21} = size; 5328 let Inst{20-16} = Rm; 5329 let Inst{15-11} = opcode; 5330 let Inst{10} = 1; 5331 let Inst{9-5} = Rn; 5332 let Inst{4-0} = Rd; 5333} 5334 5335let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5336class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5337 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5338 Sched<[WriteV]>; 5339 5340multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5341 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5342 [(set (v8i8 V64:$dst), 5343 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5344 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5345 [(set (v16i8 V128:$dst), 5346 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5347 (v16i8 V128:$Rm)))]>; 5348 5349 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5350 (v4i16 V64:$RHS))), 5351 (!cast<Instruction>(NAME#"v8i8") 5352 V64:$LHS, V64:$MHS, V64:$RHS)>; 5353 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5354 (v2i32 V64:$RHS))), 5355 (!cast<Instruction>(NAME#"v8i8") 5356 V64:$LHS, V64:$MHS, V64:$RHS)>; 5357 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5358 (v1i64 V64:$RHS))), 5359 (!cast<Instruction>(NAME#"v8i8") 5360 V64:$LHS, V64:$MHS, V64:$RHS)>; 5361 5362 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5363 (v8i16 V128:$RHS))), 5364 (!cast<Instruction>(NAME#"v16i8") 5365 V128:$LHS, V128:$MHS, V128:$RHS)>; 5366 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5367 (v4i32 V128:$RHS))), 5368 (!cast<Instruction>(NAME#"v16i8") 5369 V128:$LHS, V128:$MHS, V128:$RHS)>; 5370 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5371 (v2i64 V128:$RHS))), 5372 (!cast<Instruction>(NAME#"v16i8") 5373 V128:$LHS, V128:$MHS, V128:$RHS)>; 5374} 5375 5376// All operand sizes distinguished in the encoding. 5377multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5378 SDPatternOperator OpNode> { 5379 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5380 asm, ".8b", 5381 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5382 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5383 asm, ".16b", 5384 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5385 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5386 asm, ".4h", 5387 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5388 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5389 asm, ".8h", 5390 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5391 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5392 asm, ".2s", 5393 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5394 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5395 asm, ".4s", 5396 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5397 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5398 asm, ".2d", 5399 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5400} 5401 5402multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5403 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5404 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5405 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5406 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5407 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5408 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5409 5410 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5411 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5412 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5413 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5414 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5415 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5416 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5417 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5418} 5419 5420// As above, but D sized elements unsupported. 5421multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5422 SDPatternOperator OpNode> { 5423 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5424 asm, ".8b", 5425 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5426 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5427 asm, ".16b", 5428 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5429 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5430 asm, ".4h", 5431 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5432 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5433 asm, ".8h", 5434 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5435 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5436 asm, ".2s", 5437 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5438 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5439 asm, ".4s", 5440 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5441} 5442 5443multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5444 SDPatternOperator OpNode> { 5445 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5446 asm, ".8b", 5447 [(set (v8i8 V64:$dst), 5448 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5449 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5450 asm, ".16b", 5451 [(set (v16i8 V128:$dst), 5452 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5453 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5454 asm, ".4h", 5455 [(set (v4i16 V64:$dst), 5456 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5457 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5458 asm, ".8h", 5459 [(set (v8i16 V128:$dst), 5460 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5461 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5462 asm, ".2s", 5463 [(set (v2i32 V64:$dst), 5464 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5465 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5466 asm, ".4s", 5467 [(set (v4i32 V128:$dst), 5468 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5469} 5470 5471// As above, but only B sized elements supported. 5472multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5473 SDPatternOperator OpNode> { 5474 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5475 asm, ".8b", 5476 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5477 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5478 asm, ".16b", 5479 [(set (v16i8 V128:$Rd), 5480 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5481} 5482 5483// As above, but only floating point elements supported. 5484multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5485 string asm, SDPatternOperator OpNode> { 5486 let Predicates = [HasNEON, HasFullFP16] in { 5487 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5488 asm, ".4h", 5489 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5490 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5491 asm, ".8h", 5492 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5493 } // Predicates = [HasNEON, HasFullFP16] 5494 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5495 asm, ".2s", 5496 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5497 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5498 asm, ".4s", 5499 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5500 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5501 asm, ".2d", 5502 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5503} 5504 5505multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5506 string asm, 5507 SDPatternOperator OpNode> { 5508 let Predicates = [HasNEON, HasFullFP16] in { 5509 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5510 asm, ".4h", 5511 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5512 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5513 asm, ".8h", 5514 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5515 } // Predicates = [HasNEON, HasFullFP16] 5516 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5517 asm, ".2s", 5518 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5519 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5520 asm, ".4s", 5521 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5522 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5523 asm, ".2d", 5524 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5525} 5526 5527multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5528 string asm, SDPatternOperator OpNode> { 5529 let Predicates = [HasNEON, HasFullFP16] in { 5530 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5531 asm, ".4h", 5532 [(set (v4f16 V64:$dst), 5533 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5534 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5535 asm, ".8h", 5536 [(set (v8f16 V128:$dst), 5537 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5538 } // Predicates = [HasNEON, HasFullFP16] 5539 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5540 asm, ".2s", 5541 [(set (v2f32 V64:$dst), 5542 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5543 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5544 asm, ".4s", 5545 [(set (v4f32 V128:$dst), 5546 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5547 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5548 asm, ".2d", 5549 [(set (v2f64 V128:$dst), 5550 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5551} 5552 5553// As above, but D and B sized elements unsupported. 5554multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5555 SDPatternOperator OpNode> { 5556 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5557 asm, ".4h", 5558 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5559 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5560 asm, ".8h", 5561 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5562 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5563 asm, ".2s", 5564 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5565 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5566 asm, ".4s", 5567 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5568} 5569 5570// Logical three vector ops share opcode bits, and only use B sized elements. 5571multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5572 SDPatternOperator OpNode = null_frag> { 5573 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5574 asm, ".8b", 5575 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5576 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5577 asm, ".16b", 5578 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5579 5580 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5581 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5582 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5583 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5584 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5585 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5586 5587 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5588 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5589 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5590 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5591 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5592 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5593} 5594 5595multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5596 string asm, SDPatternOperator OpNode = null_frag> { 5597 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5598 asm, ".8b", 5599 [(set (v8i8 V64:$dst), 5600 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5601 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5602 asm, ".16b", 5603 [(set (v16i8 V128:$dst), 5604 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5605 (v16i8 V128:$Rm)))]>; 5606 5607 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5608 (v4i16 V64:$RHS))), 5609 (!cast<Instruction>(NAME#"v8i8") 5610 V64:$LHS, V64:$MHS, V64:$RHS)>; 5611 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5612 (v2i32 V64:$RHS))), 5613 (!cast<Instruction>(NAME#"v8i8") 5614 V64:$LHS, V64:$MHS, V64:$RHS)>; 5615 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5616 (v1i64 V64:$RHS))), 5617 (!cast<Instruction>(NAME#"v8i8") 5618 V64:$LHS, V64:$MHS, V64:$RHS)>; 5619 5620 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5621 (v8i16 V128:$RHS))), 5622 (!cast<Instruction>(NAME#"v16i8") 5623 V128:$LHS, V128:$MHS, V128:$RHS)>; 5624 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5625 (v4i32 V128:$RHS))), 5626 (!cast<Instruction>(NAME#"v16i8") 5627 V128:$LHS, V128:$MHS, V128:$RHS)>; 5628 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5629 (v2i64 V128:$RHS))), 5630 (!cast<Instruction>(NAME#"v16i8") 5631 V128:$LHS, V128:$MHS, V128:$RHS)>; 5632} 5633 5634// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5635// bytes from S-sized elements. 5636class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5637 string kind2, RegisterOperand RegType, 5638 ValueType AccumType, ValueType InputType, 5639 SDPatternOperator OpNode> : 5640 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5641 [(set (AccumType RegType:$dst), 5642 (OpNode (AccumType RegType:$Rd), 5643 (InputType RegType:$Rn), 5644 (InputType RegType:$Rm)))]> { 5645 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5646} 5647 5648multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5649 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5650 v2i32, v8i8, OpNode>; 5651 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5652 v4i32, v16i8, OpNode>; 5653} 5654 5655// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5656// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5657// 8H to 4S, when Q=1). 5658class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5659 string kind2, RegisterOperand RegType, 5660 ValueType AccumType, ValueType InputType, 5661 SDPatternOperator OpNode> : 5662 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5663 [(set (AccumType RegType:$dst), 5664 (OpNode (AccumType RegType:$Rd), 5665 (InputType RegType:$Rn), 5666 (InputType RegType:$Rm)))]> { 5667 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5668 let Inst{13} = b13; 5669} 5670 5671multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5672 SDPatternOperator OpNode> { 5673 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5674 v2f32, v4f16, OpNode>; 5675 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5676 v4f32, v8f16, OpNode>; 5677} 5678 5679 5680//---------------------------------------------------------------------------- 5681// AdvSIMD two register vector instructions. 5682//---------------------------------------------------------------------------- 5683 5684let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5685class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5686 bits<2> size2, RegisterOperand regtype, string asm, 5687 string dstkind, string srckind, list<dag> pattern> 5688 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5689 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5690 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5691 Sched<[WriteV]> { 5692 bits<5> Rd; 5693 bits<5> Rn; 5694 let Inst{31} = 0; 5695 let Inst{30} = Q; 5696 let Inst{29} = U; 5697 let Inst{28-24} = 0b01110; 5698 let Inst{23-22} = size; 5699 let Inst{21} = 0b1; 5700 let Inst{20-19} = size2; 5701 let Inst{18-17} = 0b00; 5702 let Inst{16-12} = opcode; 5703 let Inst{11-10} = 0b10; 5704 let Inst{9-5} = Rn; 5705 let Inst{4-0} = Rd; 5706} 5707 5708let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5709class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5710 bits<2> size2, RegisterOperand regtype, 5711 string asm, string dstkind, string srckind, 5712 list<dag> pattern> 5713 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5714 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5715 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5716 Sched<[WriteV]> { 5717 bits<5> Rd; 5718 bits<5> Rn; 5719 let Inst{31} = 0; 5720 let Inst{30} = Q; 5721 let Inst{29} = U; 5722 let Inst{28-24} = 0b01110; 5723 let Inst{23-22} = size; 5724 let Inst{21} = 0b1; 5725 let Inst{20-19} = size2; 5726 let Inst{18-17} = 0b00; 5727 let Inst{16-12} = opcode; 5728 let Inst{11-10} = 0b10; 5729 let Inst{9-5} = Rn; 5730 let Inst{4-0} = Rd; 5731} 5732 5733// Supports B, H, and S element sizes. 5734multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5735 SDPatternOperator OpNode> { 5736 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5737 asm, ".8b", ".8b", 5738 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5739 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5740 asm, ".16b", ".16b", 5741 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5742 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5743 asm, ".4h", ".4h", 5744 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5745 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5746 asm, ".8h", ".8h", 5747 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5748 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5749 asm, ".2s", ".2s", 5750 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5751 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5752 asm, ".4s", ".4s", 5753 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5754} 5755 5756class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5757 RegisterOperand regtype, string asm, string dstkind, 5758 string srckind, string amount> 5759 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5760 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5761 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5762 Sched<[WriteV]> { 5763 bits<5> Rd; 5764 bits<5> Rn; 5765 let Inst{31} = 0; 5766 let Inst{30} = Q; 5767 let Inst{29-24} = 0b101110; 5768 let Inst{23-22} = size; 5769 let Inst{21-10} = 0b100001001110; 5770 let Inst{9-5} = Rn; 5771 let Inst{4-0} = Rd; 5772} 5773 5774multiclass SIMDVectorLShiftLongBySizeBHS { 5775 let hasSideEffects = 0 in { 5776 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5777 "shll", ".8h", ".8b", "8">; 5778 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5779 "shll2", ".8h", ".16b", "8">; 5780 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5781 "shll", ".4s", ".4h", "16">; 5782 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5783 "shll2", ".4s", ".8h", "16">; 5784 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5785 "shll", ".2d", ".2s", "32">; 5786 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5787 "shll2", ".2d", ".4s", "32">; 5788 } 5789} 5790 5791// Supports all element sizes. 5792multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5793 SDPatternOperator OpNode> { 5794 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5795 asm, ".4h", ".8b", 5796 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5797 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5798 asm, ".8h", ".16b", 5799 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5800 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5801 asm, ".2s", ".4h", 5802 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5803 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5804 asm, ".4s", ".8h", 5805 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5806 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5807 asm, ".1d", ".2s", 5808 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5809 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5810 asm, ".2d", ".4s", 5811 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5812} 5813 5814multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5815 SDPatternOperator OpNode> { 5816 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5817 asm, ".4h", ".8b", 5818 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5819 (v8i8 V64:$Rn)))]>; 5820 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5821 asm, ".8h", ".16b", 5822 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5823 (v16i8 V128:$Rn)))]>; 5824 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5825 asm, ".2s", ".4h", 5826 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5827 (v4i16 V64:$Rn)))]>; 5828 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5829 asm, ".4s", ".8h", 5830 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5831 (v8i16 V128:$Rn)))]>; 5832 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5833 asm, ".1d", ".2s", 5834 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5835 (v2i32 V64:$Rn)))]>; 5836 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5837 asm, ".2d", ".4s", 5838 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5839 (v4i32 V128:$Rn)))]>; 5840} 5841 5842// Supports all element sizes, except 1xD. 5843multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5844 SDPatternOperator OpNode> { 5845 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5846 asm, ".8b", ".8b", 5847 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5848 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5849 asm, ".16b", ".16b", 5850 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5851 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5852 asm, ".4h", ".4h", 5853 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5854 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5855 asm, ".8h", ".8h", 5856 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5857 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5858 asm, ".2s", ".2s", 5859 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5860 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5861 asm, ".4s", ".4s", 5862 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5863 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5864 asm, ".2d", ".2d", 5865 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5866} 5867 5868multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5869 SDPatternOperator OpNode = null_frag> { 5870 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5871 asm, ".8b", ".8b", 5872 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5873 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5874 asm, ".16b", ".16b", 5875 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5876 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5877 asm, ".4h", ".4h", 5878 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5879 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5880 asm, ".8h", ".8h", 5881 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5882 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5883 asm, ".2s", ".2s", 5884 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5885 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5886 asm, ".4s", ".4s", 5887 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5888 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5889 asm, ".2d", ".2d", 5890 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5891} 5892 5893 5894// Supports only B element sizes. 5895multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5896 SDPatternOperator OpNode> { 5897 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5898 asm, ".8b", ".8b", 5899 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5900 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5901 asm, ".16b", ".16b", 5902 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5903 5904} 5905 5906// Supports only B and H element sizes. 5907multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5908 SDPatternOperator OpNode> { 5909 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5910 asm, ".8b", ".8b", 5911 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5912 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5913 asm, ".16b", ".16b", 5914 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5915 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5916 asm, ".4h", ".4h", 5917 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5918 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5919 asm, ".8h", ".8h", 5920 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5921} 5922 5923// Supports H, S and D element sizes, uses high bit of the size field 5924// as an extra opcode bit. 5925multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5926 SDPatternOperator OpNode> { 5927 let Predicates = [HasNEON, HasFullFP16] in { 5928 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5929 asm, ".4h", ".4h", 5930 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5931 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5932 asm, ".8h", ".8h", 5933 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5934 } // Predicates = [HasNEON, HasFullFP16] 5935 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5936 asm, ".2s", ".2s", 5937 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5938 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5939 asm, ".4s", ".4s", 5940 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5941 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5942 asm, ".2d", ".2d", 5943 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5944} 5945 5946// Supports only S and D element sizes 5947multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 5948 SDPatternOperator OpNode = null_frag> { 5949 5950 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 5951 asm, ".2s", ".2s", 5952 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5953 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 5954 asm, ".4s", ".4s", 5955 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5956 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 5957 asm, ".2d", ".2d", 5958 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5959} 5960 5961multiclass FRIntNNTVector<bit U, bit op, string asm, 5962 SDPatternOperator OpNode = null_frag> : 5963 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 5964 5965// Supports only S element size. 5966multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 5967 SDPatternOperator OpNode> { 5968 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5969 asm, ".2s", ".2s", 5970 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5971 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5972 asm, ".4s", ".4s", 5973 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5974} 5975 5976 5977multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 5978 SDPatternOperator OpNode> { 5979 let Predicates = [HasNEON, HasFullFP16] in { 5980 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5981 asm, ".4h", ".4h", 5982 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5983 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5984 asm, ".8h", ".8h", 5985 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5986 } // Predicates = [HasNEON, HasFullFP16] 5987 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5988 asm, ".2s", ".2s", 5989 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5990 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5991 asm, ".4s", ".4s", 5992 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5993 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5994 asm, ".2d", ".2d", 5995 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5996} 5997 5998multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 5999 SDPatternOperator OpNode> { 6000 let Predicates = [HasNEON, HasFullFP16] in { 6001 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6002 asm, ".4h", ".4h", 6003 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6004 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6005 asm, ".8h", ".8h", 6006 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6007 } // Predicates = [HasNEON, HasFullFP16] 6008 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6009 asm, ".2s", ".2s", 6010 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6011 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6012 asm, ".4s", ".4s", 6013 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6014 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6015 asm, ".2d", ".2d", 6016 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6017} 6018 6019 6020class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6021 RegisterOperand inreg, RegisterOperand outreg, 6022 string asm, string outkind, string inkind, 6023 list<dag> pattern> 6024 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6025 "{\t$Rd" # outkind # ", $Rn" # inkind # 6026 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6027 Sched<[WriteV]> { 6028 bits<5> Rd; 6029 bits<5> Rn; 6030 let Inst{31} = 0; 6031 let Inst{30} = Q; 6032 let Inst{29} = U; 6033 let Inst{28-24} = 0b01110; 6034 let Inst{23-22} = size; 6035 let Inst{21-17} = 0b10000; 6036 let Inst{16-12} = opcode; 6037 let Inst{11-10} = 0b10; 6038 let Inst{9-5} = Rn; 6039 let Inst{4-0} = Rd; 6040} 6041 6042class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6043 RegisterOperand inreg, RegisterOperand outreg, 6044 string asm, string outkind, string inkind, 6045 list<dag> pattern> 6046 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6047 "{\t$Rd" # outkind # ", $Rn" # inkind # 6048 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6049 Sched<[WriteV]> { 6050 bits<5> Rd; 6051 bits<5> Rn; 6052 let Inst{31} = 0; 6053 let Inst{30} = Q; 6054 let Inst{29} = U; 6055 let Inst{28-24} = 0b01110; 6056 let Inst{23-22} = size; 6057 let Inst{21-17} = 0b10000; 6058 let Inst{16-12} = opcode; 6059 let Inst{11-10} = 0b10; 6060 let Inst{9-5} = Rn; 6061 let Inst{4-0} = Rd; 6062} 6063 6064multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6065 SDPatternOperator OpNode> { 6066 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6067 asm, ".8b", ".8h", 6068 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6069 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6070 asm#"2", ".16b", ".8h", []>; 6071 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6072 asm, ".4h", ".4s", 6073 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6074 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6075 asm#"2", ".8h", ".4s", []>; 6076 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6077 asm, ".2s", ".2d", 6078 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6079 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6080 asm#"2", ".4s", ".2d", []>; 6081 6082 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6083 (!cast<Instruction>(NAME # "v16i8") 6084 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6085 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6086 (!cast<Instruction>(NAME # "v8i16") 6087 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6088 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6089 (!cast<Instruction>(NAME # "v4i32") 6090 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6091} 6092 6093class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6094 bits<5> opcode, RegisterOperand regtype, string asm, 6095 string kind, string zero, ValueType dty, 6096 ValueType sty, SDNode OpNode> 6097 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6098 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6099 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6100 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6101 Sched<[WriteV]> { 6102 bits<5> Rd; 6103 bits<5> Rn; 6104 let Inst{31} = 0; 6105 let Inst{30} = Q; 6106 let Inst{29} = U; 6107 let Inst{28-24} = 0b01110; 6108 let Inst{23-22} = size; 6109 let Inst{21} = 0b1; 6110 let Inst{20-19} = size2; 6111 let Inst{18-17} = 0b00; 6112 let Inst{16-12} = opcode; 6113 let Inst{11-10} = 0b10; 6114 let Inst{9-5} = Rn; 6115 let Inst{4-0} = Rd; 6116} 6117 6118// Comparisons support all element sizes, except 1xD. 6119multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6120 SDNode OpNode> { 6121 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6122 asm, ".8b", "0", 6123 v8i8, v8i8, OpNode>; 6124 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6125 asm, ".16b", "0", 6126 v16i8, v16i8, OpNode>; 6127 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6128 asm, ".4h", "0", 6129 v4i16, v4i16, OpNode>; 6130 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6131 asm, ".8h", "0", 6132 v8i16, v8i16, OpNode>; 6133 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6134 asm, ".2s", "0", 6135 v2i32, v2i32, OpNode>; 6136 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6137 asm, ".4s", "0", 6138 v4i32, v4i32, OpNode>; 6139 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6140 asm, ".2d", "0", 6141 v2i64, v2i64, OpNode>; 6142} 6143 6144// FP Comparisons support only S and D element sizes (and H for v8.2a). 6145multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6146 string asm, SDNode OpNode> { 6147 6148 let Predicates = [HasNEON, HasFullFP16] in { 6149 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6150 asm, ".4h", "0.0", 6151 v4i16, v4f16, OpNode>; 6152 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6153 asm, ".8h", "0.0", 6154 v8i16, v8f16, OpNode>; 6155 } // Predicates = [HasNEON, HasFullFP16] 6156 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6157 asm, ".2s", "0.0", 6158 v2i32, v2f32, OpNode>; 6159 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6160 asm, ".4s", "0.0", 6161 v4i32, v4f32, OpNode>; 6162 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6163 asm, ".2d", "0.0", 6164 v2i64, v2f64, OpNode>; 6165 6166 let Predicates = [HasNEON, HasFullFP16] in { 6167 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6168 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6169 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6170 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6171 } 6172 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6173 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6174 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6175 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6176 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6177 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6178 let Predicates = [HasNEON, HasFullFP16] in { 6179 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6180 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6181 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6182 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6183 } 6184 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6185 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6186 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6187 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6188 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6189 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6190} 6191 6192let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6193class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6194 RegisterOperand outtype, RegisterOperand intype, 6195 string asm, string VdTy, string VnTy, 6196 list<dag> pattern> 6197 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6198 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6199 Sched<[WriteV]> { 6200 bits<5> Rd; 6201 bits<5> Rn; 6202 let Inst{31} = 0; 6203 let Inst{30} = Q; 6204 let Inst{29} = U; 6205 let Inst{28-24} = 0b01110; 6206 let Inst{23-22} = size; 6207 let Inst{21-17} = 0b10000; 6208 let Inst{16-12} = opcode; 6209 let Inst{11-10} = 0b10; 6210 let Inst{9-5} = Rn; 6211 let Inst{4-0} = Rd; 6212} 6213 6214class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6215 RegisterOperand outtype, RegisterOperand intype, 6216 string asm, string VdTy, string VnTy, 6217 list<dag> pattern> 6218 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6219 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6220 Sched<[WriteV]> { 6221 bits<5> Rd; 6222 bits<5> Rn; 6223 let Inst{31} = 0; 6224 let Inst{30} = Q; 6225 let Inst{29} = U; 6226 let Inst{28-24} = 0b01110; 6227 let Inst{23-22} = size; 6228 let Inst{21-17} = 0b10000; 6229 let Inst{16-12} = opcode; 6230 let Inst{11-10} = 0b10; 6231 let Inst{9-5} = Rn; 6232 let Inst{4-0} = Rd; 6233} 6234 6235multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6236 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6237 asm, ".4s", ".4h", []>; 6238 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6239 asm#"2", ".4s", ".8h", []>; 6240 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6241 asm, ".2d", ".2s", []>; 6242 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6243 asm#"2", ".2d", ".4s", []>; 6244} 6245 6246multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6247 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6248 asm, ".4h", ".4s", []>; 6249 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6250 asm#"2", ".8h", ".4s", []>; 6251 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6252 asm, ".2s", ".2d", []>; 6253 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6254 asm#"2", ".4s", ".2d", []>; 6255} 6256 6257multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6258 Intrinsic OpNode> { 6259 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6260 asm, ".2s", ".2d", 6261 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6262 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6263 asm#"2", ".4s", ".2d", []>; 6264 6265 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6266 (!cast<Instruction>(NAME # "v4f32") 6267 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6268} 6269 6270//---------------------------------------------------------------------------- 6271// AdvSIMD three register different-size vector instructions. 6272//---------------------------------------------------------------------------- 6273 6274let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6275class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6276 RegisterOperand outtype, RegisterOperand intype1, 6277 RegisterOperand intype2, string asm, 6278 string outkind, string inkind1, string inkind2, 6279 list<dag> pattern> 6280 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6281 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6282 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6283 Sched<[WriteV]> { 6284 bits<5> Rd; 6285 bits<5> Rn; 6286 bits<5> Rm; 6287 let Inst{31} = 0; 6288 let Inst{30} = size{0}; 6289 let Inst{29} = U; 6290 let Inst{28-24} = 0b01110; 6291 let Inst{23-22} = size{2-1}; 6292 let Inst{21} = 1; 6293 let Inst{20-16} = Rm; 6294 let Inst{15-12} = opcode; 6295 let Inst{11-10} = 0b00; 6296 let Inst{9-5} = Rn; 6297 let Inst{4-0} = Rd; 6298} 6299 6300let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6301class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6302 RegisterOperand outtype, RegisterOperand intype1, 6303 RegisterOperand intype2, string asm, 6304 string outkind, string inkind1, string inkind2, 6305 list<dag> pattern> 6306 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6307 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6308 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6309 Sched<[WriteV]> { 6310 bits<5> Rd; 6311 bits<5> Rn; 6312 bits<5> Rm; 6313 let Inst{31} = 0; 6314 let Inst{30} = size{0}; 6315 let Inst{29} = U; 6316 let Inst{28-24} = 0b01110; 6317 let Inst{23-22} = size{2-1}; 6318 let Inst{21} = 1; 6319 let Inst{20-16} = Rm; 6320 let Inst{15-12} = opcode; 6321 let Inst{11-10} = 0b00; 6322 let Inst{9-5} = Rn; 6323 let Inst{4-0} = Rd; 6324} 6325 6326// FIXME: TableGen doesn't know how to deal with expanded types that also 6327// change the element count (in this case, placing the results in 6328// the high elements of the result register rather than the low 6329// elements). Until that's fixed, we can't code-gen those. 6330multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6331 Intrinsic IntOp> { 6332 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6333 V64, V128, V128, 6334 asm, ".8b", ".8h", ".8h", 6335 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6336 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6337 V128, V128, V128, 6338 asm#"2", ".16b", ".8h", ".8h", 6339 []>; 6340 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6341 V64, V128, V128, 6342 asm, ".4h", ".4s", ".4s", 6343 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6344 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6345 V128, V128, V128, 6346 asm#"2", ".8h", ".4s", ".4s", 6347 []>; 6348 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6349 V64, V128, V128, 6350 asm, ".2s", ".2d", ".2d", 6351 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6352 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6353 V128, V128, V128, 6354 asm#"2", ".4s", ".2d", ".2d", 6355 []>; 6356 6357 6358 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6359 // a version attached to an instruction. 6360 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6361 (v8i16 V128:$Rm))), 6362 (!cast<Instruction>(NAME # "v8i16_v16i8") 6363 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6364 V128:$Rn, V128:$Rm)>; 6365 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6366 (v4i32 V128:$Rm))), 6367 (!cast<Instruction>(NAME # "v4i32_v8i16") 6368 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6369 V128:$Rn, V128:$Rm)>; 6370 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6371 (v2i64 V128:$Rm))), 6372 (!cast<Instruction>(NAME # "v2i64_v4i32") 6373 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6374 V128:$Rn, V128:$Rm)>; 6375} 6376 6377multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6378 Intrinsic IntOp> { 6379 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6380 V128, V64, V64, 6381 asm, ".8h", ".8b", ".8b", 6382 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6383 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6384 V128, V128, V128, 6385 asm#"2", ".8h", ".16b", ".16b", []>; 6386 let Predicates = [HasAES] in { 6387 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6388 V128, V64, V64, 6389 asm, ".1q", ".1d", ".1d", []>; 6390 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6391 V128, V128, V128, 6392 asm#"2", ".1q", ".2d", ".2d", []>; 6393 } 6394 6395 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6396 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6397 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6398} 6399 6400multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6401 SDPatternOperator OpNode> { 6402 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6403 V128, V64, V64, 6404 asm, ".4s", ".4h", ".4h", 6405 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6406 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6407 V128, V128, V128, 6408 asm#"2", ".4s", ".8h", ".8h", 6409 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6410 (extract_high_v8i16 V128:$Rm)))]>; 6411 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6412 V128, V64, V64, 6413 asm, ".2d", ".2s", ".2s", 6414 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6415 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6416 V128, V128, V128, 6417 asm#"2", ".2d", ".4s", ".4s", 6418 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6419 (extract_high_v4i32 V128:$Rm)))]>; 6420} 6421 6422multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6423 SDPatternOperator OpNode = null_frag> { 6424 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6425 V128, V64, V64, 6426 asm, ".8h", ".8b", ".8b", 6427 [(set (v8i16 V128:$Rd), 6428 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6429 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6430 V128, V128, V128, 6431 asm#"2", ".8h", ".16b", ".16b", 6432 [(set (v8i16 V128:$Rd), 6433 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6434 (extract_high_v16i8 V128:$Rm)))))]>; 6435 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6436 V128, V64, V64, 6437 asm, ".4s", ".4h", ".4h", 6438 [(set (v4i32 V128:$Rd), 6439 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6440 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6441 V128, V128, V128, 6442 asm#"2", ".4s", ".8h", ".8h", 6443 [(set (v4i32 V128:$Rd), 6444 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6445 (extract_high_v8i16 V128:$Rm)))))]>; 6446 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6447 V128, V64, V64, 6448 asm, ".2d", ".2s", ".2s", 6449 [(set (v2i64 V128:$Rd), 6450 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6451 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6452 V128, V128, V128, 6453 asm#"2", ".2d", ".4s", ".4s", 6454 [(set (v2i64 V128:$Rd), 6455 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6456 (extract_high_v4i32 V128:$Rm)))))]>; 6457} 6458 6459multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6460 string asm, 6461 SDPatternOperator OpNode> { 6462 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6463 V128, V64, V64, 6464 asm, ".8h", ".8b", ".8b", 6465 [(set (v8i16 V128:$dst), 6466 (add (v8i16 V128:$Rd), 6467 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6468 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6469 V128, V128, V128, 6470 asm#"2", ".8h", ".16b", ".16b", 6471 [(set (v8i16 V128:$dst), 6472 (add (v8i16 V128:$Rd), 6473 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6474 (extract_high_v16i8 V128:$Rm))))))]>; 6475 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6476 V128, V64, V64, 6477 asm, ".4s", ".4h", ".4h", 6478 [(set (v4i32 V128:$dst), 6479 (add (v4i32 V128:$Rd), 6480 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6481 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6482 V128, V128, V128, 6483 asm#"2", ".4s", ".8h", ".8h", 6484 [(set (v4i32 V128:$dst), 6485 (add (v4i32 V128:$Rd), 6486 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6487 (extract_high_v8i16 V128:$Rm))))))]>; 6488 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6489 V128, V64, V64, 6490 asm, ".2d", ".2s", ".2s", 6491 [(set (v2i64 V128:$dst), 6492 (add (v2i64 V128:$Rd), 6493 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6494 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6495 V128, V128, V128, 6496 asm#"2", ".2d", ".4s", ".4s", 6497 [(set (v2i64 V128:$dst), 6498 (add (v2i64 V128:$Rd), 6499 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6500 (extract_high_v4i32 V128:$Rm))))))]>; 6501} 6502 6503multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6504 SDPatternOperator OpNode = null_frag> { 6505 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6506 V128, V64, V64, 6507 asm, ".8h", ".8b", ".8b", 6508 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6509 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6510 V128, V128, V128, 6511 asm#"2", ".8h", ".16b", ".16b", 6512 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6513 (extract_high_v16i8 V128:$Rm)))]>; 6514 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6515 V128, V64, V64, 6516 asm, ".4s", ".4h", ".4h", 6517 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6518 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6519 V128, V128, V128, 6520 asm#"2", ".4s", ".8h", ".8h", 6521 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6522 (extract_high_v8i16 V128:$Rm)))]>; 6523 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6524 V128, V64, V64, 6525 asm, ".2d", ".2s", ".2s", 6526 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6527 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6528 V128, V128, V128, 6529 asm#"2", ".2d", ".4s", ".4s", 6530 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6531 (extract_high_v4i32 V128:$Rm)))]>; 6532} 6533 6534multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6535 string asm, 6536 SDPatternOperator OpNode> { 6537 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6538 V128, V64, V64, 6539 asm, ".8h", ".8b", ".8b", 6540 [(set (v8i16 V128:$dst), 6541 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6542 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6543 V128, V128, V128, 6544 asm#"2", ".8h", ".16b", ".16b", 6545 [(set (v8i16 V128:$dst), 6546 (OpNode (v8i16 V128:$Rd), 6547 (extract_high_v16i8 V128:$Rn), 6548 (extract_high_v16i8 V128:$Rm)))]>; 6549 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6550 V128, V64, V64, 6551 asm, ".4s", ".4h", ".4h", 6552 [(set (v4i32 V128:$dst), 6553 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6554 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6555 V128, V128, V128, 6556 asm#"2", ".4s", ".8h", ".8h", 6557 [(set (v4i32 V128:$dst), 6558 (OpNode (v4i32 V128:$Rd), 6559 (extract_high_v8i16 V128:$Rn), 6560 (extract_high_v8i16 V128:$Rm)))]>; 6561 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6562 V128, V64, V64, 6563 asm, ".2d", ".2s", ".2s", 6564 [(set (v2i64 V128:$dst), 6565 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6566 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6567 V128, V128, V128, 6568 asm#"2", ".2d", ".4s", ".4s", 6569 [(set (v2i64 V128:$dst), 6570 (OpNode (v2i64 V128:$Rd), 6571 (extract_high_v4i32 V128:$Rn), 6572 (extract_high_v4i32 V128:$Rm)))]>; 6573} 6574 6575multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6576 SDPatternOperator Accum> { 6577 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6578 V128, V64, V64, 6579 asm, ".4s", ".4h", ".4h", 6580 [(set (v4i32 V128:$dst), 6581 (Accum (v4i32 V128:$Rd), 6582 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6583 (v4i16 V64:$Rm)))))]>; 6584 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6585 V128, V128, V128, 6586 asm#"2", ".4s", ".8h", ".8h", 6587 [(set (v4i32 V128:$dst), 6588 (Accum (v4i32 V128:$Rd), 6589 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6590 (extract_high_v8i16 V128:$Rm)))))]>; 6591 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6592 V128, V64, V64, 6593 asm, ".2d", ".2s", ".2s", 6594 [(set (v2i64 V128:$dst), 6595 (Accum (v2i64 V128:$Rd), 6596 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6597 (v2i32 V64:$Rm)))))]>; 6598 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6599 V128, V128, V128, 6600 asm#"2", ".2d", ".4s", ".4s", 6601 [(set (v2i64 V128:$dst), 6602 (Accum (v2i64 V128:$Rd), 6603 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6604 (extract_high_v4i32 V128:$Rm)))))]>; 6605} 6606 6607multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6608 SDPatternOperator OpNode> { 6609 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6610 V128, V128, V64, 6611 asm, ".8h", ".8h", ".8b", 6612 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6613 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6614 V128, V128, V128, 6615 asm#"2", ".8h", ".8h", ".16b", 6616 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6617 (extract_high_v16i8 V128:$Rm)))]>; 6618 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6619 V128, V128, V64, 6620 asm, ".4s", ".4s", ".4h", 6621 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6622 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6623 V128, V128, V128, 6624 asm#"2", ".4s", ".4s", ".8h", 6625 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6626 (extract_high_v8i16 V128:$Rm)))]>; 6627 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6628 V128, V128, V64, 6629 asm, ".2d", ".2d", ".2s", 6630 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6631 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6632 V128, V128, V128, 6633 asm#"2", ".2d", ".2d", ".4s", 6634 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6635 (extract_high_v4i32 V128:$Rm)))]>; 6636} 6637 6638//---------------------------------------------------------------------------- 6639// AdvSIMD bitwise extract from vector 6640//---------------------------------------------------------------------------- 6641 6642class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6643 string asm, string kind> 6644 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6645 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6646 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6647 [(set (vty regtype:$Rd), 6648 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6649 Sched<[WriteV]> { 6650 bits<5> Rd; 6651 bits<5> Rn; 6652 bits<5> Rm; 6653 bits<4> imm; 6654 let Inst{31} = 0; 6655 let Inst{30} = size; 6656 let Inst{29-21} = 0b101110000; 6657 let Inst{20-16} = Rm; 6658 let Inst{15} = 0; 6659 let Inst{14-11} = imm; 6660 let Inst{10} = 0; 6661 let Inst{9-5} = Rn; 6662 let Inst{4-0} = Rd; 6663} 6664 6665 6666multiclass SIMDBitwiseExtract<string asm> { 6667 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6668 let imm{3} = 0; 6669 } 6670 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6671} 6672 6673//---------------------------------------------------------------------------- 6674// AdvSIMD zip vector 6675//---------------------------------------------------------------------------- 6676 6677class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6678 string asm, string kind, SDNode OpNode, ValueType valty> 6679 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6680 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6681 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6682 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6683 Sched<[WriteV]> { 6684 bits<5> Rd; 6685 bits<5> Rn; 6686 bits<5> Rm; 6687 let Inst{31} = 0; 6688 let Inst{30} = size{0}; 6689 let Inst{29-24} = 0b001110; 6690 let Inst{23-22} = size{2-1}; 6691 let Inst{21} = 0; 6692 let Inst{20-16} = Rm; 6693 let Inst{15} = 0; 6694 let Inst{14-12} = opc; 6695 let Inst{11-10} = 0b10; 6696 let Inst{9-5} = Rn; 6697 let Inst{4-0} = Rd; 6698} 6699 6700multiclass SIMDZipVector<bits<3>opc, string asm, 6701 SDNode OpNode> { 6702 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6703 asm, ".8b", OpNode, v8i8>; 6704 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6705 asm, ".16b", OpNode, v16i8>; 6706 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6707 asm, ".4h", OpNode, v4i16>; 6708 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6709 asm, ".8h", OpNode, v8i16>; 6710 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6711 asm, ".2s", OpNode, v2i32>; 6712 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6713 asm, ".4s", OpNode, v4i32>; 6714 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6715 asm, ".2d", OpNode, v2i64>; 6716 6717 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6718 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6719 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6720 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6721 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6722 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6723 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6724 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6725 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6726 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6727} 6728 6729//---------------------------------------------------------------------------- 6730// AdvSIMD three register scalar instructions 6731//---------------------------------------------------------------------------- 6732 6733let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6734class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6735 RegisterClass regtype, string asm, 6736 list<dag> pattern> 6737 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6738 "\t$Rd, $Rn, $Rm", "", pattern>, 6739 Sched<[WriteV]> { 6740 bits<5> Rd; 6741 bits<5> Rn; 6742 bits<5> Rm; 6743 let Inst{31-30} = 0b01; 6744 let Inst{29} = U; 6745 let Inst{28-24} = 0b11110; 6746 let Inst{23-21} = size; 6747 let Inst{20-16} = Rm; 6748 let Inst{15-11} = opcode; 6749 let Inst{10} = 1; 6750 let Inst{9-5} = Rn; 6751 let Inst{4-0} = Rd; 6752} 6753 6754let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6755class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6756 dag oops, dag iops, string asm, 6757 list<dag> pattern> 6758 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6759 Sched<[WriteV]> { 6760 bits<5> Rd; 6761 bits<5> Rn; 6762 bits<5> Rm; 6763 let Inst{31-30} = 0b01; 6764 let Inst{29} = U; 6765 let Inst{28-24} = 0b11110; 6766 let Inst{23-22} = size; 6767 let Inst{21} = R; 6768 let Inst{20-16} = Rm; 6769 let Inst{15-11} = opcode; 6770 let Inst{10} = 1; 6771 let Inst{9-5} = Rn; 6772 let Inst{4-0} = Rd; 6773} 6774 6775multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6776 SDPatternOperator OpNode> { 6777 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6778 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6779} 6780 6781multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6782 SDPatternOperator OpNode> { 6783 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6784 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6785 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6786 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6787 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6788 6789 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6790 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6791 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6792 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6793} 6794 6795multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6796 SDPatternOperator OpNode> { 6797 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6798 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6799 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6800} 6801 6802multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 6803 SDPatternOperator OpNode = null_frag> { 6804 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6805 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6806 asm, []>; 6807 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6808 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6809 asm, []>; 6810} 6811 6812multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6813 SDPatternOperator OpNode = null_frag> { 6814 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6815 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6816 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6817 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6818 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6819 let Predicates = [HasNEON, HasFullFP16] in { 6820 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6821 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6822 } // Predicates = [HasNEON, HasFullFP16] 6823 } 6824 6825 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6826 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6827} 6828 6829multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6830 SDPatternOperator OpNode = null_frag> { 6831 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6832 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6833 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6834 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6835 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6836 let Predicates = [HasNEON, HasFullFP16] in { 6837 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6838 []>; 6839 } // Predicates = [HasNEON, HasFullFP16] 6840 } 6841 6842 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6843 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6844} 6845 6846class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6847 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6848 : I<oops, iops, asm, 6849 "\t$Rd, $Rn, $Rm", cstr, pat>, 6850 Sched<[WriteV]> { 6851 bits<5> Rd; 6852 bits<5> Rn; 6853 bits<5> Rm; 6854 let Inst{31-30} = 0b01; 6855 let Inst{29} = U; 6856 let Inst{28-24} = 0b11110; 6857 let Inst{23-22} = size; 6858 let Inst{21} = 1; 6859 let Inst{20-16} = Rm; 6860 let Inst{15-11} = opcode; 6861 let Inst{10} = 0; 6862 let Inst{9-5} = Rn; 6863 let Inst{4-0} = Rd; 6864} 6865 6866let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6867multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6868 SDPatternOperator OpNode = null_frag> { 6869 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6870 (outs FPR32:$Rd), 6871 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6872 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6873 (outs FPR64:$Rd), 6874 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6875 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6876} 6877 6878let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6879multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6880 SDPatternOperator OpNode = null_frag> { 6881 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6882 (outs FPR32:$dst), 6883 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6884 asm, "$Rd = $dst", []>; 6885 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6886 (outs FPR64:$dst), 6887 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6888 asm, "$Rd = $dst", 6889 [(set (i64 FPR64:$dst), 6890 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6891} 6892 6893//---------------------------------------------------------------------------- 6894// AdvSIMD two register scalar instructions 6895//---------------------------------------------------------------------------- 6896 6897let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6898class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6899 RegisterClass regtype, RegisterClass regtype2, 6900 string asm, list<dag> pat> 6901 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6902 "\t$Rd, $Rn", "", pat>, 6903 Sched<[WriteV]> { 6904 bits<5> Rd; 6905 bits<5> Rn; 6906 let Inst{31-30} = 0b01; 6907 let Inst{29} = U; 6908 let Inst{28-24} = 0b11110; 6909 let Inst{23-22} = size; 6910 let Inst{21} = 0b1; 6911 let Inst{20-19} = size2; 6912 let Inst{18-17} = 0b00; 6913 let Inst{16-12} = opcode; 6914 let Inst{11-10} = 0b10; 6915 let Inst{9-5} = Rn; 6916 let Inst{4-0} = Rd; 6917} 6918 6919let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6920class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6921 RegisterClass regtype, RegisterClass regtype2, 6922 string asm, list<dag> pat> 6923 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6924 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6925 Sched<[WriteV]> { 6926 bits<5> Rd; 6927 bits<5> Rn; 6928 let Inst{31-30} = 0b01; 6929 let Inst{29} = U; 6930 let Inst{28-24} = 0b11110; 6931 let Inst{23-22} = size; 6932 let Inst{21-17} = 0b10000; 6933 let Inst{16-12} = opcode; 6934 let Inst{11-10} = 0b10; 6935 let Inst{9-5} = Rn; 6936 let Inst{4-0} = Rd; 6937} 6938 6939 6940let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6941class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6942 RegisterClass regtype, string asm, string zero> 6943 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6944 "\t$Rd, $Rn, #" # zero, "", []>, 6945 Sched<[WriteV]> { 6946 bits<5> Rd; 6947 bits<5> Rn; 6948 let Inst{31-30} = 0b01; 6949 let Inst{29} = U; 6950 let Inst{28-24} = 0b11110; 6951 let Inst{23-22} = size; 6952 let Inst{21} = 0b1; 6953 let Inst{20-19} = size2; 6954 let Inst{18-17} = 0b00; 6955 let Inst{16-12} = opcode; 6956 let Inst{11-10} = 0b10; 6957 let Inst{9-5} = Rn; 6958 let Inst{4-0} = Rd; 6959} 6960 6961class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 6962 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 6963 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 6964 Sched<[WriteV]> { 6965 bits<5> Rd; 6966 bits<5> Rn; 6967 let Inst{31-17} = 0b011111100110000; 6968 let Inst{16-12} = opcode; 6969 let Inst{11-10} = 0b10; 6970 let Inst{9-5} = Rn; 6971 let Inst{4-0} = Rd; 6972} 6973 6974multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 6975 SDPatternOperator OpNode> { 6976 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 6977 6978 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 6979 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6980} 6981 6982multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 6983 SDPatternOperator OpNode> { 6984 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 6985 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 6986 let Predicates = [HasNEON, HasFullFP16] in { 6987 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 6988 } 6989 6990 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6991 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 6992 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6993 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 6994 let Predicates = [HasNEON, HasFullFP16] in { 6995 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6996 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 6997 } 6998 6999 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7000 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7001} 7002 7003multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7004 SDPatternOperator OpNode = null_frag> { 7005 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7006 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7007 7008 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7009 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7010} 7011 7012multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 7013 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7014 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7015 let Predicates = [HasNEON, HasFullFP16] in { 7016 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7017 } 7018} 7019 7020multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7021 SDPatternOperator OpNode> { 7022 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7023 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7024 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7025 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7026 let Predicates = [HasNEON, HasFullFP16] in { 7027 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7028 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7029 } 7030} 7031 7032multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7033 SDPatternOperator OpNode = null_frag> { 7034 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7035 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7036 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7037 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7038 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7039 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7040 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7041 } 7042 7043 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7044 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7045} 7046 7047multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7048 Intrinsic OpNode> { 7049 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7050 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7051 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7052 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7053 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7054 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7055 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7056 } 7057 7058 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7059 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7060} 7061 7062 7063 7064let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7065multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7066 SDPatternOperator OpNode = null_frag> { 7067 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7068 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7069 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7070 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7071} 7072 7073//---------------------------------------------------------------------------- 7074// AdvSIMD scalar pairwise instructions 7075//---------------------------------------------------------------------------- 7076 7077let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7078class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7079 RegisterOperand regtype, RegisterOperand vectype, 7080 string asm, string kind> 7081 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7082 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7083 Sched<[WriteV]> { 7084 bits<5> Rd; 7085 bits<5> Rn; 7086 let Inst{31-30} = 0b01; 7087 let Inst{29} = U; 7088 let Inst{28-24} = 0b11110; 7089 let Inst{23-22} = size; 7090 let Inst{21-17} = 0b11000; 7091 let Inst{16-12} = opcode; 7092 let Inst{11-10} = 0b10; 7093 let Inst{9-5} = Rn; 7094 let Inst{4-0} = Rd; 7095} 7096 7097multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7098 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7099 asm, ".2d">; 7100} 7101 7102multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7103 let Predicates = [HasNEON, HasFullFP16] in { 7104 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7105 asm, ".2h">; 7106 } 7107 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7108 asm, ".2s">; 7109 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7110 asm, ".2d">; 7111} 7112 7113//---------------------------------------------------------------------------- 7114// AdvSIMD across lanes instructions 7115//---------------------------------------------------------------------------- 7116 7117let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7118class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7119 RegisterClass regtype, RegisterOperand vectype, 7120 string asm, string kind, list<dag> pattern> 7121 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7122 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7123 Sched<[WriteV]> { 7124 bits<5> Rd; 7125 bits<5> Rn; 7126 let Inst{31} = 0; 7127 let Inst{30} = Q; 7128 let Inst{29} = U; 7129 let Inst{28-24} = 0b01110; 7130 let Inst{23-22} = size; 7131 let Inst{21-17} = 0b11000; 7132 let Inst{16-12} = opcode; 7133 let Inst{11-10} = 0b10; 7134 let Inst{9-5} = Rn; 7135 let Inst{4-0} = Rd; 7136} 7137 7138multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7139 string asm> { 7140 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7141 asm, ".8b", []>; 7142 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7143 asm, ".16b", []>; 7144 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7145 asm, ".4h", []>; 7146 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7147 asm, ".8h", []>; 7148 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7149 asm, ".4s", []>; 7150} 7151 7152multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7153 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7154 asm, ".8b", []>; 7155 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7156 asm, ".16b", []>; 7157 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7158 asm, ".4h", []>; 7159 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7160 asm, ".8h", []>; 7161 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7162 asm, ".4s", []>; 7163} 7164 7165multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7166 Intrinsic intOp> { 7167 let Predicates = [HasNEON, HasFullFP16] in { 7168 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7169 asm, ".4h", 7170 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7171 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7172 asm, ".8h", 7173 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7174 } // Predicates = [HasNEON, HasFullFP16] 7175 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7176 asm, ".4s", 7177 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7178} 7179 7180//---------------------------------------------------------------------------- 7181// AdvSIMD INS/DUP instructions 7182//---------------------------------------------------------------------------- 7183 7184// FIXME: There has got to be a better way to factor these. ugh. 7185 7186class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7187 string operands, string constraints, list<dag> pattern> 7188 : I<outs, ins, asm, operands, constraints, pattern>, 7189 Sched<[WriteV]> { 7190 bits<5> Rd; 7191 bits<5> Rn; 7192 let Inst{31} = 0; 7193 let Inst{30} = Q; 7194 let Inst{29} = op; 7195 let Inst{28-21} = 0b01110000; 7196 let Inst{15} = 0; 7197 let Inst{10} = 1; 7198 let Inst{9-5} = Rn; 7199 let Inst{4-0} = Rd; 7200} 7201 7202class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7203 RegisterOperand vecreg, RegisterClass regtype> 7204 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7205 "{\t$Rd" # size # ", $Rn" # 7206 "|" # size # "\t$Rd, $Rn}", "", 7207 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7208 let Inst{20-16} = imm5; 7209 let Inst{14-11} = 0b0001; 7210} 7211 7212class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7213 ValueType vectype, ValueType insreg, 7214 RegisterOperand vecreg, Operand idxtype, 7215 ValueType elttype, SDNode OpNode> 7216 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7217 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7218 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7219 [(set (vectype vecreg:$Rd), 7220 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7221 let Inst{14-11} = 0b0000; 7222} 7223 7224class SIMDDup64FromElement 7225 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7226 VectorIndexD, i64, AArch64duplane64> { 7227 bits<1> idx; 7228 let Inst{20} = idx; 7229 let Inst{19-16} = 0b1000; 7230} 7231 7232class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7233 RegisterOperand vecreg> 7234 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7235 VectorIndexS, i64, AArch64duplane32> { 7236 bits<2> idx; 7237 let Inst{20-19} = idx; 7238 let Inst{18-16} = 0b100; 7239} 7240 7241class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7242 RegisterOperand vecreg> 7243 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7244 VectorIndexH, i64, AArch64duplane16> { 7245 bits<3> idx; 7246 let Inst{20-18} = idx; 7247 let Inst{17-16} = 0b10; 7248} 7249 7250class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7251 RegisterOperand vecreg> 7252 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7253 VectorIndexB, i64, AArch64duplane8> { 7254 bits<4> idx; 7255 let Inst{20-17} = idx; 7256 let Inst{16} = 1; 7257} 7258 7259class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7260 Operand idxtype, string asm, list<dag> pattern> 7261 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7262 "{\t$Rd, $Rn" # size # "$idx" # 7263 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7264 let Inst{14-11} = imm4; 7265} 7266 7267class SIMDSMov<bit Q, string size, RegisterClass regtype, 7268 Operand idxtype> 7269 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7270class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7271 Operand idxtype> 7272 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7273 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7274 7275class SIMDMovAlias<string asm, string size, Instruction inst, 7276 RegisterClass regtype, Operand idxtype> 7277 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7278 "|" # size # "\t$dst, $src$idx}", 7279 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7280 7281multiclass SMov { 7282 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7283 bits<4> idx; 7284 let Inst{20-17} = idx; 7285 let Inst{16} = 1; 7286 } 7287 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7288 bits<4> idx; 7289 let Inst{20-17} = idx; 7290 let Inst{16} = 1; 7291 } 7292 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7293 bits<3> idx; 7294 let Inst{20-18} = idx; 7295 let Inst{17-16} = 0b10; 7296 } 7297 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7298 bits<3> idx; 7299 let Inst{20-18} = idx; 7300 let Inst{17-16} = 0b10; 7301 } 7302 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7303 bits<2> idx; 7304 let Inst{20-19} = idx; 7305 let Inst{18-16} = 0b100; 7306 } 7307} 7308 7309multiclass UMov { 7310 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7311 bits<4> idx; 7312 let Inst{20-17} = idx; 7313 let Inst{16} = 1; 7314 } 7315 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7316 bits<3> idx; 7317 let Inst{20-18} = idx; 7318 let Inst{17-16} = 0b10; 7319 } 7320 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7321 bits<2> idx; 7322 let Inst{20-19} = idx; 7323 let Inst{18-16} = 0b100; 7324 } 7325 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7326 bits<1> idx; 7327 let Inst{20} = idx; 7328 let Inst{19-16} = 0b1000; 7329 } 7330 def : SIMDMovAlias<"mov", ".s", 7331 !cast<Instruction>(NAME#"vi32"), 7332 GPR32, VectorIndexS>; 7333 def : SIMDMovAlias<"mov", ".d", 7334 !cast<Instruction>(NAME#"vi64"), 7335 GPR64, VectorIndexD>; 7336} 7337 7338class SIMDInsFromMain<string size, ValueType vectype, 7339 RegisterClass regtype, Operand idxtype> 7340 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7341 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7342 "{\t$Rd" # size # "$idx, $Rn" # 7343 "|" # size # "\t$Rd$idx, $Rn}", 7344 "$Rd = $dst", 7345 [(set V128:$dst, 7346 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7347 let Inst{14-11} = 0b0011; 7348} 7349 7350class SIMDInsFromElement<string size, ValueType vectype, 7351 ValueType elttype, Operand idxtype> 7352 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7353 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7354 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7355 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7356 "$Rd = $dst", 7357 [(set V128:$dst, 7358 (vector_insert 7359 (vectype V128:$Rd), 7360 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7361 idxtype:$idx))]>; 7362 7363class SIMDInsMainMovAlias<string size, Instruction inst, 7364 RegisterClass regtype, Operand idxtype> 7365 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7366 "|" # size #"\t$dst$idx, $src}", 7367 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7368class SIMDInsElementMovAlias<string size, Instruction inst, 7369 Operand idxtype> 7370 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7371 # "|" # size #"\t$dst$idx, $src$idx2}", 7372 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7373 7374 7375multiclass SIMDIns { 7376 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7377 bits<4> idx; 7378 let Inst{20-17} = idx; 7379 let Inst{16} = 1; 7380 } 7381 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7382 bits<3> idx; 7383 let Inst{20-18} = idx; 7384 let Inst{17-16} = 0b10; 7385 } 7386 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7387 bits<2> idx; 7388 let Inst{20-19} = idx; 7389 let Inst{18-16} = 0b100; 7390 } 7391 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7392 bits<1> idx; 7393 let Inst{20} = idx; 7394 let Inst{19-16} = 0b1000; 7395 } 7396 7397 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7398 bits<4> idx; 7399 bits<4> idx2; 7400 let Inst{20-17} = idx; 7401 let Inst{16} = 1; 7402 let Inst{14-11} = idx2; 7403 } 7404 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7405 bits<3> idx; 7406 bits<3> idx2; 7407 let Inst{20-18} = idx; 7408 let Inst{17-16} = 0b10; 7409 let Inst{14-12} = idx2; 7410 let Inst{11} = {?}; 7411 } 7412 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7413 bits<2> idx; 7414 bits<2> idx2; 7415 let Inst{20-19} = idx; 7416 let Inst{18-16} = 0b100; 7417 let Inst{14-13} = idx2; 7418 let Inst{12-11} = {?,?}; 7419 } 7420 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7421 bits<1> idx; 7422 bits<1> idx2; 7423 let Inst{20} = idx; 7424 let Inst{19-16} = 0b1000; 7425 let Inst{14} = idx2; 7426 let Inst{13-11} = {?,?,?}; 7427 } 7428 7429 // For all forms of the INS instruction, the "mov" mnemonic is the 7430 // preferred alias. Why they didn't just call the instruction "mov" in 7431 // the first place is a very good question indeed... 7432 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7433 GPR32, VectorIndexB>; 7434 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7435 GPR32, VectorIndexH>; 7436 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7437 GPR32, VectorIndexS>; 7438 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7439 GPR64, VectorIndexD>; 7440 7441 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7442 VectorIndexB>; 7443 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7444 VectorIndexH>; 7445 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7446 VectorIndexS>; 7447 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7448 VectorIndexD>; 7449} 7450 7451//---------------------------------------------------------------------------- 7452// AdvSIMD TBL/TBX 7453//---------------------------------------------------------------------------- 7454 7455let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7456class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7457 RegisterOperand listtype, string asm, string kind> 7458 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7459 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7460 Sched<[WriteV]> { 7461 bits<5> Vd; 7462 bits<5> Vn; 7463 bits<5> Vm; 7464 let Inst{31} = 0; 7465 let Inst{30} = Q; 7466 let Inst{29-21} = 0b001110000; 7467 let Inst{20-16} = Vm; 7468 let Inst{15} = 0; 7469 let Inst{14-13} = len; 7470 let Inst{12} = op; 7471 let Inst{11-10} = 0b00; 7472 let Inst{9-5} = Vn; 7473 let Inst{4-0} = Vd; 7474} 7475 7476let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7477class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7478 RegisterOperand listtype, string asm, string kind> 7479 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7480 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7481 Sched<[WriteV]> { 7482 bits<5> Vd; 7483 bits<5> Vn; 7484 bits<5> Vm; 7485 let Inst{31} = 0; 7486 let Inst{30} = Q; 7487 let Inst{29-21} = 0b001110000; 7488 let Inst{20-16} = Vm; 7489 let Inst{15} = 0; 7490 let Inst{14-13} = len; 7491 let Inst{12} = op; 7492 let Inst{11-10} = 0b00; 7493 let Inst{9-5} = Vn; 7494 let Inst{4-0} = Vd; 7495} 7496 7497class SIMDTableLookupAlias<string asm, Instruction inst, 7498 RegisterOperand vectype, RegisterOperand listtype> 7499 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7500 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7501 7502multiclass SIMDTableLookup<bit op, string asm> { 7503 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7504 asm, ".8b">; 7505 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7506 asm, ".8b">; 7507 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7508 asm, ".8b">; 7509 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7510 asm, ".8b">; 7511 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7512 asm, ".16b">; 7513 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7514 asm, ".16b">; 7515 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7516 asm, ".16b">; 7517 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7518 asm, ".16b">; 7519 7520 def : SIMDTableLookupAlias<asm # ".8b", 7521 !cast<Instruction>(NAME#"v8i8One"), 7522 V64, VecListOne128>; 7523 def : SIMDTableLookupAlias<asm # ".8b", 7524 !cast<Instruction>(NAME#"v8i8Two"), 7525 V64, VecListTwo128>; 7526 def : SIMDTableLookupAlias<asm # ".8b", 7527 !cast<Instruction>(NAME#"v8i8Three"), 7528 V64, VecListThree128>; 7529 def : SIMDTableLookupAlias<asm # ".8b", 7530 !cast<Instruction>(NAME#"v8i8Four"), 7531 V64, VecListFour128>; 7532 def : SIMDTableLookupAlias<asm # ".16b", 7533 !cast<Instruction>(NAME#"v16i8One"), 7534 V128, VecListOne128>; 7535 def : SIMDTableLookupAlias<asm # ".16b", 7536 !cast<Instruction>(NAME#"v16i8Two"), 7537 V128, VecListTwo128>; 7538 def : SIMDTableLookupAlias<asm # ".16b", 7539 !cast<Instruction>(NAME#"v16i8Three"), 7540 V128, VecListThree128>; 7541 def : SIMDTableLookupAlias<asm # ".16b", 7542 !cast<Instruction>(NAME#"v16i8Four"), 7543 V128, VecListFour128>; 7544} 7545 7546multiclass SIMDTableLookupTied<bit op, string asm> { 7547 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7548 asm, ".8b">; 7549 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7550 asm, ".8b">; 7551 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7552 asm, ".8b">; 7553 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7554 asm, ".8b">; 7555 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7556 asm, ".16b">; 7557 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7558 asm, ".16b">; 7559 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7560 asm, ".16b">; 7561 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7562 asm, ".16b">; 7563 7564 def : SIMDTableLookupAlias<asm # ".8b", 7565 !cast<Instruction>(NAME#"v8i8One"), 7566 V64, VecListOne128>; 7567 def : SIMDTableLookupAlias<asm # ".8b", 7568 !cast<Instruction>(NAME#"v8i8Two"), 7569 V64, VecListTwo128>; 7570 def : SIMDTableLookupAlias<asm # ".8b", 7571 !cast<Instruction>(NAME#"v8i8Three"), 7572 V64, VecListThree128>; 7573 def : SIMDTableLookupAlias<asm # ".8b", 7574 !cast<Instruction>(NAME#"v8i8Four"), 7575 V64, VecListFour128>; 7576 def : SIMDTableLookupAlias<asm # ".16b", 7577 !cast<Instruction>(NAME#"v16i8One"), 7578 V128, VecListOne128>; 7579 def : SIMDTableLookupAlias<asm # ".16b", 7580 !cast<Instruction>(NAME#"v16i8Two"), 7581 V128, VecListTwo128>; 7582 def : SIMDTableLookupAlias<asm # ".16b", 7583 !cast<Instruction>(NAME#"v16i8Three"), 7584 V128, VecListThree128>; 7585 def : SIMDTableLookupAlias<asm # ".16b", 7586 !cast<Instruction>(NAME#"v16i8Four"), 7587 V128, VecListFour128>; 7588} 7589 7590 7591//---------------------------------------------------------------------------- 7592// AdvSIMD scalar CPY 7593//---------------------------------------------------------------------------- 7594let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7595class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 7596 string kind, Operand idxtype> 7597 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 7598 "{\t$dst, $src" # kind # "$idx" # 7599 "|\t$dst, $src$idx}", "", []>, 7600 Sched<[WriteV]> { 7601 bits<5> dst; 7602 bits<5> src; 7603 let Inst{31-21} = 0b01011110000; 7604 let Inst{15-10} = 0b000001; 7605 let Inst{9-5} = src; 7606 let Inst{4-0} = dst; 7607} 7608 7609class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 7610 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7611 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7612 # "|\t$dst, $src$index}", 7613 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7614 7615 7616multiclass SIMDScalarCPY<string asm> { 7617 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 7618 bits<4> idx; 7619 let Inst{20-17} = idx; 7620 let Inst{16} = 1; 7621 } 7622 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 7623 bits<3> idx; 7624 let Inst{20-18} = idx; 7625 let Inst{17-16} = 0b10; 7626 } 7627 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 7628 bits<2> idx; 7629 let Inst{20-19} = idx; 7630 let Inst{18-16} = 0b100; 7631 } 7632 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 7633 bits<1> idx; 7634 let Inst{20} = idx; 7635 let Inst{19-16} = 0b1000; 7636 } 7637 7638 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7639 VectorIndexD:$idx)))), 7640 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7641 7642 // 'DUP' mnemonic aliases. 7643 def : SIMDScalarCPYAlias<"dup", ".b", 7644 !cast<Instruction>(NAME#"i8"), 7645 FPR8, V128, VectorIndexB>; 7646 def : SIMDScalarCPYAlias<"dup", ".h", 7647 !cast<Instruction>(NAME#"i16"), 7648 FPR16, V128, VectorIndexH>; 7649 def : SIMDScalarCPYAlias<"dup", ".s", 7650 !cast<Instruction>(NAME#"i32"), 7651 FPR32, V128, VectorIndexS>; 7652 def : SIMDScalarCPYAlias<"dup", ".d", 7653 !cast<Instruction>(NAME#"i64"), 7654 FPR64, V128, VectorIndexD>; 7655} 7656 7657//---------------------------------------------------------------------------- 7658// AdvSIMD modified immediate instructions 7659//---------------------------------------------------------------------------- 7660 7661class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7662 string asm, string op_string, 7663 string cstr, list<dag> pattern> 7664 : I<oops, iops, asm, op_string, cstr, pattern>, 7665 Sched<[WriteV]> { 7666 bits<5> Rd; 7667 bits<8> imm8; 7668 let Inst{31} = 0; 7669 let Inst{30} = Q; 7670 let Inst{29} = op; 7671 let Inst{28-19} = 0b0111100000; 7672 let Inst{18-16} = imm8{7-5}; 7673 let Inst{11} = op2; 7674 let Inst{10} = 1; 7675 let Inst{9-5} = imm8{4-0}; 7676 let Inst{4-0} = Rd; 7677} 7678 7679class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7680 Operand immtype, dag opt_shift_iop, 7681 string opt_shift, string asm, string kind, 7682 list<dag> pattern> 7683 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7684 !con((ins immtype:$imm8), opt_shift_iop), asm, 7685 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7686 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7687 "", pattern> { 7688 let DecoderMethod = "DecodeModImmInstruction"; 7689} 7690 7691class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7692 Operand immtype, dag opt_shift_iop, 7693 string opt_shift, string asm, string kind, 7694 list<dag> pattern> 7695 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7696 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7697 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7698 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7699 "$Rd = $dst", pattern> { 7700 let DecoderMethod = "DecodeModImmTiedInstruction"; 7701} 7702 7703class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7704 RegisterOperand vectype, string asm, 7705 string kind, list<dag> pattern> 7706 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7707 (ins logical_vec_shift:$shift), 7708 "$shift", asm, kind, pattern> { 7709 bits<2> shift; 7710 let Inst{15} = b15_b12{1}; 7711 let Inst{14-13} = shift; 7712 let Inst{12} = b15_b12{0}; 7713} 7714 7715class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7716 RegisterOperand vectype, string asm, 7717 string kind, list<dag> pattern> 7718 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7719 (ins logical_vec_shift:$shift), 7720 "$shift", asm, kind, pattern> { 7721 bits<2> shift; 7722 let Inst{15} = b15_b12{1}; 7723 let Inst{14-13} = shift; 7724 let Inst{12} = b15_b12{0}; 7725} 7726 7727 7728class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7729 RegisterOperand vectype, string asm, 7730 string kind, list<dag> pattern> 7731 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7732 (ins logical_vec_hw_shift:$shift), 7733 "$shift", asm, kind, pattern> { 7734 bits<2> shift; 7735 let Inst{15} = b15_b12{1}; 7736 let Inst{14} = 0; 7737 let Inst{13} = shift{0}; 7738 let Inst{12} = b15_b12{0}; 7739} 7740 7741class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7742 RegisterOperand vectype, string asm, 7743 string kind, list<dag> pattern> 7744 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7745 (ins logical_vec_hw_shift:$shift), 7746 "$shift", asm, kind, pattern> { 7747 bits<2> shift; 7748 let Inst{15} = b15_b12{1}; 7749 let Inst{14} = 0; 7750 let Inst{13} = shift{0}; 7751 let Inst{12} = b15_b12{0}; 7752} 7753 7754multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7755 string asm> { 7756 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7757 asm, ".4h", []>; 7758 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7759 asm, ".8h", []>; 7760 7761 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7762 asm, ".2s", []>; 7763 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7764 asm, ".4s", []>; 7765} 7766 7767multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7768 bits<2> w_cmode, string asm, 7769 SDNode OpNode> { 7770 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7771 asm, ".4h", 7772 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7773 imm0_255:$imm8, 7774 (i32 imm:$shift)))]>; 7775 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7776 asm, ".8h", 7777 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7778 imm0_255:$imm8, 7779 (i32 imm:$shift)))]>; 7780 7781 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7782 asm, ".2s", 7783 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7784 imm0_255:$imm8, 7785 (i32 imm:$shift)))]>; 7786 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7787 asm, ".4s", 7788 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7789 imm0_255:$imm8, 7790 (i32 imm:$shift)))]>; 7791} 7792 7793class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7794 RegisterOperand vectype, string asm, 7795 string kind, list<dag> pattern> 7796 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7797 (ins move_vec_shift:$shift), 7798 "$shift", asm, kind, pattern> { 7799 bits<1> shift; 7800 let Inst{15-13} = cmode{3-1}; 7801 let Inst{12} = shift; 7802} 7803 7804class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7805 RegisterOperand vectype, 7806 Operand imm_type, string asm, 7807 string kind, list<dag> pattern> 7808 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7809 asm, kind, pattern> { 7810 let Inst{15-12} = cmode; 7811} 7812 7813class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7814 list<dag> pattern> 7815 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7816 "\t$Rd, $imm8", "", pattern> { 7817 let Inst{15-12} = cmode; 7818 let DecoderMethod = "DecodeModImmInstruction"; 7819} 7820 7821//---------------------------------------------------------------------------- 7822// AdvSIMD indexed element 7823//---------------------------------------------------------------------------- 7824 7825let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7826class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7827 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7828 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7829 string apple_kind, string dst_kind, string lhs_kind, 7830 string rhs_kind, list<dag> pattern> 7831 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7832 asm, 7833 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7834 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7835 Sched<[WriteV]> { 7836 bits<5> Rd; 7837 bits<5> Rn; 7838 bits<5> Rm; 7839 7840 let Inst{31} = 0; 7841 let Inst{30} = Q; 7842 let Inst{29} = U; 7843 let Inst{28} = Scalar; 7844 let Inst{27-24} = 0b1111; 7845 let Inst{23-22} = size; 7846 // Bit 21 must be set by the derived class. 7847 let Inst{20-16} = Rm; 7848 let Inst{15-12} = opc; 7849 // Bit 11 must be set by the derived class. 7850 let Inst{10} = 0; 7851 let Inst{9-5} = Rn; 7852 let Inst{4-0} = Rd; 7853} 7854 7855let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7856class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7857 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7858 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7859 string apple_kind, string dst_kind, string lhs_kind, 7860 string rhs_kind, list<dag> pattern> 7861 : I<(outs dst_reg:$dst), 7862 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7863 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7864 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7865 Sched<[WriteV]> { 7866 bits<5> Rd; 7867 bits<5> Rn; 7868 bits<5> Rm; 7869 7870 let Inst{31} = 0; 7871 let Inst{30} = Q; 7872 let Inst{29} = U; 7873 let Inst{28} = Scalar; 7874 let Inst{27-24} = 0b1111; 7875 let Inst{23-22} = size; 7876 // Bit 21 must be set by the derived class. 7877 let Inst{20-16} = Rm; 7878 let Inst{15-12} = opc; 7879 // Bit 11 must be set by the derived class. 7880 let Inst{10} = 0; 7881 let Inst{9-5} = Rn; 7882 let Inst{4-0} = Rd; 7883} 7884 7885 7886//---------------------------------------------------------------------------- 7887// Armv8.6 BFloat16 Extension 7888//---------------------------------------------------------------------------- 7889let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 7890 7891class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 7892 string kind2, RegisterOperand RegType, 7893 ValueType AccumType, ValueType InputType> 7894 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 7895 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 7896 (InputType RegType:$Rn), 7897 (InputType RegType:$Rm)))]> { 7898 let AsmString = !strconcat(asm, 7899 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 7900 ", $Rm" # kind2 # "}"); 7901} 7902 7903multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 7904 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 7905 v2f32, v4bf16>; 7906 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 7907 v4f32, v8bf16>; 7908} 7909 7910class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 7911 string dst_kind, string lhs_kind, 7912 string rhs_kind, 7913 RegisterOperand RegType, 7914 ValueType AccumType, 7915 ValueType InputType> 7916 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 7917 RegType, RegType, V128, VectorIndexS, 7918 asm, "", dst_kind, lhs_kind, rhs_kind, 7919 [(set (AccumType RegType:$dst), 7920 (AccumType (int_aarch64_neon_bfdot 7921 (AccumType RegType:$Rd), 7922 (InputType RegType:$Rn), 7923 (InputType (bitconvert (AccumType 7924 (AArch64duplane32 (v4f32 V128:$Rm), 7925 VectorIndexS:$idx)))))))]> { 7926 7927 bits<2> idx; 7928 let Inst{21} = idx{0}; // L 7929 let Inst{11} = idx{1}; // H 7930} 7931 7932multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 7933 7934 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 7935 ".2h", V64, v2f32, v4bf16>; 7936 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 7937 ".2h", V128, v4f32, v8bf16>; 7938} 7939 7940class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 7941 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 7942 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 7943 (v8bf16 V128:$Rn), 7944 (v8bf16 V128:$Rm)))]> { 7945 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 7946} 7947 7948class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 7949 : I<(outs V128:$dst), 7950 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 7951 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 7952 [(set (v4f32 V128:$dst), 7953 (v4f32 (OpNode (v4f32 V128:$Rd), 7954 (v8bf16 V128:$Rn), 7955 (v8bf16 7956 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 7957 VectorIndexH:$idx)))))]>, 7958 Sched<[WriteV]> { 7959 bits<5> Rd; 7960 bits<5> Rn; 7961 bits<4> Rm; 7962 bits<3> idx; 7963 7964 let Inst{31} = 0; 7965 let Inst{30} = Q; 7966 let Inst{29-22} = 0b00111111; 7967 let Inst{21-20} = idx{1-0}; 7968 let Inst{19-16} = Rm; 7969 let Inst{15-12} = 0b1111; 7970 let Inst{11} = idx{2}; // H 7971 let Inst{10} = 0; 7972 let Inst{9-5} = Rn; 7973 let Inst{4-0} = Rd; 7974} 7975 7976class SIMDThreeSameVectorBF16MatrixMul<string asm> 7977 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 7978 V128, asm, ".4s", 7979 [(set (v4f32 V128:$dst), 7980 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 7981 (v8bf16 V128:$Rn), 7982 (v8bf16 V128:$Rm)))]> { 7983 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 7984 ", $Rm", ".8h", "}"); 7985} 7986 7987class SIMD_BFCVTN 7988 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 7989 "bfcvtn", ".4h", ".4s", 7990 [(set (v8bf16 V128:$Rd), 7991 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 7992 7993class SIMD_BFCVTN2 7994 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 7995 "bfcvtn2", ".8h", ".4s", 7996 [(set (v8bf16 V128:$dst), 7997 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 7998 7999class BF16ToSinglePrecision<string asm> 8000 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8001 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8002 Sched<[WriteFCvt]> { 8003 bits<5> Rd; 8004 bits<5> Rn; 8005 let Inst{31-10} = 0b0001111001100011010000; 8006 let Inst{9-5} = Rn; 8007 let Inst{4-0} = Rd; 8008} 8009} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8010 8011//---------------------------------------------------------------------------- 8012// Armv8.6 Matrix Multiply Extension 8013//---------------------------------------------------------------------------- 8014 8015class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8016 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8017 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8018 (v16i8 V128:$Rn), 8019 (v16i8 V128:$Rm)))]> { 8020 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8021} 8022 8023//---------------------------------------------------------------------------- 8024// ARMv8.2-A Dot Product Instructions (Indexed) 8025class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8026 string dst_kind, string lhs_kind, string rhs_kind, 8027 RegisterOperand RegType, 8028 ValueType AccumType, ValueType InputType, 8029 SDPatternOperator OpNode> : 8030 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8031 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8032 [(set (AccumType RegType:$dst), 8033 (AccumType (OpNode (AccumType RegType:$Rd), 8034 (InputType RegType:$Rn), 8035 (InputType (bitconvert (AccumType 8036 (AArch64duplane32 (v4i32 V128:$Rm), 8037 VectorIndexS:$idx)))))))]> { 8038 bits<2> idx; 8039 let Inst{21} = idx{0}; // L 8040 let Inst{11} = idx{1}; // H 8041} 8042 8043multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8044 SDPatternOperator OpNode> { 8045 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8046 V64, v2i32, v8i8, OpNode>; 8047 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8048 V128, v4i32, v16i8, OpNode>; 8049} 8050 8051// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8052class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8053 string dst_kind, string lhs_kind, 8054 string rhs_kind, RegisterOperand RegType, 8055 ValueType AccumType, ValueType InputType, 8056 SDPatternOperator OpNode> : 8057 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8058 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8059 [(set (AccumType RegType:$dst), 8060 (AccumType (OpNode (AccumType RegType:$Rd), 8061 (InputType RegType:$Rn), 8062 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8063 VectorIndexH:$idx)))))]> { 8064 // idx = H:L:M 8065 bits<3> idx; 8066 let Inst{11} = idx{2}; // H 8067 let Inst{21} = idx{1}; // L 8068 let Inst{20} = idx{0}; // M 8069} 8070 8071multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8072 SDPatternOperator OpNode> { 8073 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8074 V64, v2f32, v4f16, OpNode>; 8075 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8076 V128, v4f32, v8f16, OpNode>; 8077} 8078 8079multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8080 SDPatternOperator OpNode> { 8081 let Predicates = [HasNEON, HasFullFP16] in { 8082 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8083 V64, V64, 8084 V128_lo, VectorIndexH, 8085 asm, ".4h", ".4h", ".4h", ".h", 8086 [(set (v4f16 V64:$Rd), 8087 (OpNode (v4f16 V64:$Rn), 8088 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8089 bits<3> idx; 8090 let Inst{11} = idx{2}; 8091 let Inst{21} = idx{1}; 8092 let Inst{20} = idx{0}; 8093 } 8094 8095 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8096 V128, V128, 8097 V128_lo, VectorIndexH, 8098 asm, ".8h", ".8h", ".8h", ".h", 8099 [(set (v8f16 V128:$Rd), 8100 (OpNode (v8f16 V128:$Rn), 8101 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8102 bits<3> idx; 8103 let Inst{11} = idx{2}; 8104 let Inst{21} = idx{1}; 8105 let Inst{20} = idx{0}; 8106 } 8107 } // Predicates = [HasNEON, HasFullFP16] 8108 8109 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8110 V64, V64, 8111 V128, VectorIndexS, 8112 asm, ".2s", ".2s", ".2s", ".s", 8113 [(set (v2f32 V64:$Rd), 8114 (OpNode (v2f32 V64:$Rn), 8115 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8116 bits<2> idx; 8117 let Inst{11} = idx{1}; 8118 let Inst{21} = idx{0}; 8119 } 8120 8121 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8122 V128, V128, 8123 V128, VectorIndexS, 8124 asm, ".4s", ".4s", ".4s", ".s", 8125 [(set (v4f32 V128:$Rd), 8126 (OpNode (v4f32 V128:$Rn), 8127 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8128 bits<2> idx; 8129 let Inst{11} = idx{1}; 8130 let Inst{21} = idx{0}; 8131 } 8132 8133 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8134 V128, V128, 8135 V128, VectorIndexD, 8136 asm, ".2d", ".2d", ".2d", ".d", 8137 [(set (v2f64 V128:$Rd), 8138 (OpNode (v2f64 V128:$Rn), 8139 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8140 bits<1> idx; 8141 let Inst{11} = idx{0}; 8142 let Inst{21} = 0; 8143 } 8144 8145 let Predicates = [HasNEON, HasFullFP16] in { 8146 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8147 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8148 asm, ".h", "", "", ".h", 8149 [(set (f16 FPR16Op:$Rd), 8150 (OpNode (f16 FPR16Op:$Rn), 8151 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8152 VectorIndexH:$idx))))]> { 8153 bits<3> idx; 8154 let Inst{11} = idx{2}; 8155 let Inst{21} = idx{1}; 8156 let Inst{20} = idx{0}; 8157 } 8158 } // Predicates = [HasNEON, HasFullFP16] 8159 8160 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8161 FPR32Op, FPR32Op, V128, VectorIndexS, 8162 asm, ".s", "", "", ".s", 8163 [(set (f32 FPR32Op:$Rd), 8164 (OpNode (f32 FPR32Op:$Rn), 8165 (f32 (vector_extract (v4f32 V128:$Rm), 8166 VectorIndexS:$idx))))]> { 8167 bits<2> idx; 8168 let Inst{11} = idx{1}; 8169 let Inst{21} = idx{0}; 8170 } 8171 8172 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8173 FPR64Op, FPR64Op, V128, VectorIndexD, 8174 asm, ".d", "", "", ".d", 8175 [(set (f64 FPR64Op:$Rd), 8176 (OpNode (f64 FPR64Op:$Rn), 8177 (f64 (vector_extract (v2f64 V128:$Rm), 8178 VectorIndexD:$idx))))]> { 8179 bits<1> idx; 8180 let Inst{11} = idx{0}; 8181 let Inst{21} = 0; 8182 } 8183} 8184 8185multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8186 let Predicates = [HasNEON, HasFullFP16] in { 8187 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8188 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8189 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8190 VectorIndexH:$idx))), 8191 (!cast<Instruction>(INST # "v8i16_indexed") 8192 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8193 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8194 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8195 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8196 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8197 8198 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8199 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8200 VectorIndexH:$idx))), 8201 (!cast<Instruction>(INST # "v4i16_indexed") 8202 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8203 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8204 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8205 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8206 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8207 8208 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8209 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8210 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8211 V128_lo:$Rm, VectorIndexH:$idx)>; 8212 } // Predicates = [HasNEON, HasFullFP16] 8213 8214 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8215 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8216 (AArch64duplane32 (v4f32 V128:$Rm), 8217 VectorIndexS:$idx))), 8218 (!cast<Instruction>(INST # v2i32_indexed) 8219 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8220 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8221 (AArch64dup (f32 FPR32Op:$Rm)))), 8222 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8223 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8224 8225 8226 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8227 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8228 (AArch64duplane32 (v4f32 V128:$Rm), 8229 VectorIndexS:$idx))), 8230 (!cast<Instruction>(INST # "v4i32_indexed") 8231 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8232 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8233 (AArch64dup (f32 FPR32Op:$Rm)))), 8234 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8235 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8236 8237 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8238 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8239 (AArch64duplane64 (v2f64 V128:$Rm), 8240 VectorIndexD:$idx))), 8241 (!cast<Instruction>(INST # "v2i64_indexed") 8242 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8243 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8244 (AArch64dup (f64 FPR64Op:$Rm)))), 8245 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8246 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8247 8248 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8249 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8250 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8251 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8252 V128:$Rm, VectorIndexS:$idx)>; 8253 8254 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8255 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8256 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8257 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8258 V128:$Rm, VectorIndexD:$idx)>; 8259} 8260 8261multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8262 let Predicates = [HasNEON, HasFullFP16] in { 8263 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8264 V128_lo, VectorIndexH, 8265 asm, ".4h", ".4h", ".4h", ".h", []> { 8266 bits<3> idx; 8267 let Inst{11} = idx{2}; 8268 let Inst{21} = idx{1}; 8269 let Inst{20} = idx{0}; 8270 } 8271 8272 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8273 V128, V128, 8274 V128_lo, VectorIndexH, 8275 asm, ".8h", ".8h", ".8h", ".h", []> { 8276 bits<3> idx; 8277 let Inst{11} = idx{2}; 8278 let Inst{21} = idx{1}; 8279 let Inst{20} = idx{0}; 8280 } 8281 } // Predicates = [HasNEON, HasFullFP16] 8282 8283 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8284 V128, VectorIndexS, 8285 asm, ".2s", ".2s", ".2s", ".s", []> { 8286 bits<2> idx; 8287 let Inst{11} = idx{1}; 8288 let Inst{21} = idx{0}; 8289 } 8290 8291 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8292 V128, V128, 8293 V128, VectorIndexS, 8294 asm, ".4s", ".4s", ".4s", ".s", []> { 8295 bits<2> idx; 8296 let Inst{11} = idx{1}; 8297 let Inst{21} = idx{0}; 8298 } 8299 8300 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8301 V128, V128, 8302 V128, VectorIndexD, 8303 asm, ".2d", ".2d", ".2d", ".d", []> { 8304 bits<1> idx; 8305 let Inst{11} = idx{0}; 8306 let Inst{21} = 0; 8307 } 8308 8309 let Predicates = [HasNEON, HasFullFP16] in { 8310 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8311 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8312 asm, ".h", "", "", ".h", []> { 8313 bits<3> idx; 8314 let Inst{11} = idx{2}; 8315 let Inst{21} = idx{1}; 8316 let Inst{20} = idx{0}; 8317 } 8318 } // Predicates = [HasNEON, HasFullFP16] 8319 8320 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8321 FPR32Op, FPR32Op, V128, VectorIndexS, 8322 asm, ".s", "", "", ".s", []> { 8323 bits<2> idx; 8324 let Inst{11} = idx{1}; 8325 let Inst{21} = idx{0}; 8326 } 8327 8328 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8329 FPR64Op, FPR64Op, V128, VectorIndexD, 8330 asm, ".d", "", "", ".d", []> { 8331 bits<1> idx; 8332 let Inst{11} = idx{0}; 8333 let Inst{21} = 0; 8334 } 8335} 8336 8337multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8338 SDPatternOperator OpNodeLaneQ> { 8339 8340 def : Pat<(v4i16 (OpNodeLane 8341 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8342 VectorIndexS32b:$idx)), 8343 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8344 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8345 (UImmS1XForm $idx))>; 8346 8347 def : Pat<(v4i16 (OpNodeLaneQ 8348 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8349 VectorIndexH32b:$idx)), 8350 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8351 (UImmS1XForm $idx))>; 8352 8353 def : Pat<(v8i16 (OpNodeLane 8354 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8355 VectorIndexS32b:$idx)), 8356 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8357 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8358 (UImmS1XForm $idx))>; 8359 8360 def : Pat<(v8i16 (OpNodeLaneQ 8361 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8362 VectorIndexH32b:$idx)), 8363 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8364 (UImmS1XForm $idx))>; 8365 8366 def : Pat<(v2i32 (OpNodeLane 8367 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8368 VectorIndexD32b:$idx)), 8369 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8370 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8371 (UImmS1XForm $idx))>; 8372 8373 def : Pat<(v2i32 (OpNodeLaneQ 8374 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8375 VectorIndexS32b:$idx)), 8376 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8377 (UImmS1XForm $idx))>; 8378 8379 def : Pat<(v4i32 (OpNodeLane 8380 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8381 VectorIndexD32b:$idx)), 8382 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8383 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8384 (UImmS1XForm $idx))>; 8385 8386 def : Pat<(v4i32 (OpNodeLaneQ 8387 (v4i32 V128:$Rn), 8388 (v4i32 V128:$Rm), 8389 VectorIndexS32b:$idx)), 8390 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8391 (UImmS1XForm $idx))>; 8392 8393} 8394 8395multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8396 SDPatternOperator OpNode> { 8397 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8398 V128_lo, VectorIndexH, 8399 asm, ".4h", ".4h", ".4h", ".h", 8400 [(set (v4i16 V64:$Rd), 8401 (OpNode (v4i16 V64:$Rn), 8402 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8403 bits<3> idx; 8404 let Inst{11} = idx{2}; 8405 let Inst{21} = idx{1}; 8406 let Inst{20} = idx{0}; 8407 } 8408 8409 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8410 V128, V128, 8411 V128_lo, VectorIndexH, 8412 asm, ".8h", ".8h", ".8h", ".h", 8413 [(set (v8i16 V128:$Rd), 8414 (OpNode (v8i16 V128:$Rn), 8415 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8416 bits<3> idx; 8417 let Inst{11} = idx{2}; 8418 let Inst{21} = idx{1}; 8419 let Inst{20} = idx{0}; 8420 } 8421 8422 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8423 V64, V64, 8424 V128, VectorIndexS, 8425 asm, ".2s", ".2s", ".2s", ".s", 8426 [(set (v2i32 V64:$Rd), 8427 (OpNode (v2i32 V64:$Rn), 8428 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8429 bits<2> idx; 8430 let Inst{11} = idx{1}; 8431 let Inst{21} = idx{0}; 8432 } 8433 8434 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8435 V128, V128, 8436 V128, VectorIndexS, 8437 asm, ".4s", ".4s", ".4s", ".s", 8438 [(set (v4i32 V128:$Rd), 8439 (OpNode (v4i32 V128:$Rn), 8440 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8441 bits<2> idx; 8442 let Inst{11} = idx{1}; 8443 let Inst{21} = idx{0}; 8444 } 8445 8446 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8447 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8448 asm, ".h", "", "", ".h", []> { 8449 bits<3> idx; 8450 let Inst{11} = idx{2}; 8451 let Inst{21} = idx{1}; 8452 let Inst{20} = idx{0}; 8453 } 8454 8455 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8456 FPR32Op, FPR32Op, V128, VectorIndexS, 8457 asm, ".s", "", "", ".s", 8458 [(set (i32 FPR32Op:$Rd), 8459 (OpNode FPR32Op:$Rn, 8460 (i32 (vector_extract (v4i32 V128:$Rm), 8461 VectorIndexS:$idx))))]> { 8462 bits<2> idx; 8463 let Inst{11} = idx{1}; 8464 let Inst{21} = idx{0}; 8465 } 8466} 8467 8468multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8469 SDPatternOperator OpNode> { 8470 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8471 V64, V64, 8472 V128_lo, VectorIndexH, 8473 asm, ".4h", ".4h", ".4h", ".h", 8474 [(set (v4i16 V64:$Rd), 8475 (OpNode (v4i16 V64:$Rn), 8476 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8477 bits<3> idx; 8478 let Inst{11} = idx{2}; 8479 let Inst{21} = idx{1}; 8480 let Inst{20} = idx{0}; 8481 } 8482 8483 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8484 V128, V128, 8485 V128_lo, VectorIndexH, 8486 asm, ".8h", ".8h", ".8h", ".h", 8487 [(set (v8i16 V128:$Rd), 8488 (OpNode (v8i16 V128:$Rn), 8489 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8490 bits<3> idx; 8491 let Inst{11} = idx{2}; 8492 let Inst{21} = idx{1}; 8493 let Inst{20} = idx{0}; 8494 } 8495 8496 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8497 V64, V64, 8498 V128, VectorIndexS, 8499 asm, ".2s", ".2s", ".2s", ".s", 8500 [(set (v2i32 V64:$Rd), 8501 (OpNode (v2i32 V64:$Rn), 8502 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8503 bits<2> idx; 8504 let Inst{11} = idx{1}; 8505 let Inst{21} = idx{0}; 8506 } 8507 8508 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8509 V128, V128, 8510 V128, VectorIndexS, 8511 asm, ".4s", ".4s", ".4s", ".s", 8512 [(set (v4i32 V128:$Rd), 8513 (OpNode (v4i32 V128:$Rn), 8514 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8515 bits<2> idx; 8516 let Inst{11} = idx{1}; 8517 let Inst{21} = idx{0}; 8518 } 8519} 8520 8521multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8522 SDPatternOperator OpNode> { 8523 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8524 V128_lo, VectorIndexH, 8525 asm, ".4h", ".4h", ".4h", ".h", 8526 [(set (v4i16 V64:$dst), 8527 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8528 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8529 bits<3> idx; 8530 let Inst{11} = idx{2}; 8531 let Inst{21} = idx{1}; 8532 let Inst{20} = idx{0}; 8533 } 8534 8535 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8536 V128, V128, 8537 V128_lo, VectorIndexH, 8538 asm, ".8h", ".8h", ".8h", ".h", 8539 [(set (v8i16 V128:$dst), 8540 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8541 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8542 bits<3> idx; 8543 let Inst{11} = idx{2}; 8544 let Inst{21} = idx{1}; 8545 let Inst{20} = idx{0}; 8546 } 8547 8548 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8549 V64, V64, 8550 V128, VectorIndexS, 8551 asm, ".2s", ".2s", ".2s", ".s", 8552 [(set (v2i32 V64:$dst), 8553 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8554 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8555 bits<2> idx; 8556 let Inst{11} = idx{1}; 8557 let Inst{21} = idx{0}; 8558 } 8559 8560 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8561 V128, V128, 8562 V128, VectorIndexS, 8563 asm, ".4s", ".4s", ".4s", ".s", 8564 [(set (v4i32 V128:$dst), 8565 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8566 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8567 bits<2> idx; 8568 let Inst{11} = idx{1}; 8569 let Inst{21} = idx{0}; 8570 } 8571} 8572 8573multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8574 SDPatternOperator OpNode> { 8575 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8576 V128, V64, 8577 V128_lo, VectorIndexH, 8578 asm, ".4s", ".4s", ".4h", ".h", 8579 [(set (v4i32 V128:$Rd), 8580 (OpNode (v4i16 V64:$Rn), 8581 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8582 bits<3> idx; 8583 let Inst{11} = idx{2}; 8584 let Inst{21} = idx{1}; 8585 let Inst{20} = idx{0}; 8586 } 8587 8588 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8589 V128, V128, 8590 V128_lo, VectorIndexH, 8591 asm#"2", ".4s", ".4s", ".8h", ".h", 8592 [(set (v4i32 V128:$Rd), 8593 (OpNode (extract_high_v8i16 V128:$Rn), 8594 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8595 VectorIndexH:$idx))))]> { 8596 8597 bits<3> idx; 8598 let Inst{11} = idx{2}; 8599 let Inst{21} = idx{1}; 8600 let Inst{20} = idx{0}; 8601 } 8602 8603 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8604 V128, V64, 8605 V128, VectorIndexS, 8606 asm, ".2d", ".2d", ".2s", ".s", 8607 [(set (v2i64 V128:$Rd), 8608 (OpNode (v2i32 V64:$Rn), 8609 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8610 bits<2> idx; 8611 let Inst{11} = idx{1}; 8612 let Inst{21} = idx{0}; 8613 } 8614 8615 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8616 V128, V128, 8617 V128, VectorIndexS, 8618 asm#"2", ".2d", ".2d", ".4s", ".s", 8619 [(set (v2i64 V128:$Rd), 8620 (OpNode (extract_high_v4i32 V128:$Rn), 8621 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8622 VectorIndexS:$idx))))]> { 8623 bits<2> idx; 8624 let Inst{11} = idx{1}; 8625 let Inst{21} = idx{0}; 8626 } 8627 8628 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8629 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8630 asm, ".h", "", "", ".h", []> { 8631 bits<3> idx; 8632 let Inst{11} = idx{2}; 8633 let Inst{21} = idx{1}; 8634 let Inst{20} = idx{0}; 8635 } 8636 8637 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8638 FPR64Op, FPR32Op, V128, VectorIndexS, 8639 asm, ".s", "", "", ".s", []> { 8640 bits<2> idx; 8641 let Inst{11} = idx{1}; 8642 let Inst{21} = idx{0}; 8643 } 8644} 8645 8646multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8647 SDPatternOperator Accum> { 8648 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8649 V128, V64, 8650 V128_lo, VectorIndexH, 8651 asm, ".4s", ".4s", ".4h", ".h", 8652 [(set (v4i32 V128:$dst), 8653 (Accum (v4i32 V128:$Rd), 8654 (v4i32 (int_aarch64_neon_sqdmull 8655 (v4i16 V64:$Rn), 8656 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8657 VectorIndexH:$idx))))))]> { 8658 bits<3> idx; 8659 let Inst{11} = idx{2}; 8660 let Inst{21} = idx{1}; 8661 let Inst{20} = idx{0}; 8662 } 8663 8664 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8665 // intermediate EXTRACT_SUBREG would be untyped. 8666 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8667 (i32 (vector_extract (v4i32 8668 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8669 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8670 VectorIndexH:$idx)))), 8671 (i64 0))))), 8672 (EXTRACT_SUBREG 8673 (!cast<Instruction>(NAME # v4i16_indexed) 8674 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8675 V128_lo:$Rm, VectorIndexH:$idx), 8676 ssub)>; 8677 8678 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8679 V128, V128, 8680 V128_lo, VectorIndexH, 8681 asm#"2", ".4s", ".4s", ".8h", ".h", 8682 [(set (v4i32 V128:$dst), 8683 (Accum (v4i32 V128:$Rd), 8684 (v4i32 (int_aarch64_neon_sqdmull 8685 (extract_high_v8i16 V128:$Rn), 8686 (extract_high_v8i16 8687 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8688 VectorIndexH:$idx))))))]> { 8689 bits<3> idx; 8690 let Inst{11} = idx{2}; 8691 let Inst{21} = idx{1}; 8692 let Inst{20} = idx{0}; 8693 } 8694 8695 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8696 V128, V64, 8697 V128, VectorIndexS, 8698 asm, ".2d", ".2d", ".2s", ".s", 8699 [(set (v2i64 V128:$dst), 8700 (Accum (v2i64 V128:$Rd), 8701 (v2i64 (int_aarch64_neon_sqdmull 8702 (v2i32 V64:$Rn), 8703 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8704 VectorIndexS:$idx))))))]> { 8705 bits<2> idx; 8706 let Inst{11} = idx{1}; 8707 let Inst{21} = idx{0}; 8708 } 8709 8710 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8711 V128, V128, 8712 V128, VectorIndexS, 8713 asm#"2", ".2d", ".2d", ".4s", ".s", 8714 [(set (v2i64 V128:$dst), 8715 (Accum (v2i64 V128:$Rd), 8716 (v2i64 (int_aarch64_neon_sqdmull 8717 (extract_high_v4i32 V128:$Rn), 8718 (extract_high_v4i32 8719 (AArch64duplane32 (v4i32 V128:$Rm), 8720 VectorIndexS:$idx))))))]> { 8721 bits<2> idx; 8722 let Inst{11} = idx{1}; 8723 let Inst{21} = idx{0}; 8724 } 8725 8726 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8727 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8728 asm, ".h", "", "", ".h", []> { 8729 bits<3> idx; 8730 let Inst{11} = idx{2}; 8731 let Inst{21} = idx{1}; 8732 let Inst{20} = idx{0}; 8733 } 8734 8735 8736 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8737 FPR64Op, FPR32Op, V128, VectorIndexS, 8738 asm, ".s", "", "", ".s", 8739 [(set (i64 FPR64Op:$dst), 8740 (Accum (i64 FPR64Op:$Rd), 8741 (i64 (int_aarch64_neon_sqdmulls_scalar 8742 (i32 FPR32Op:$Rn), 8743 (i32 (vector_extract (v4i32 V128:$Rm), 8744 VectorIndexS:$idx))))))]> { 8745 8746 bits<2> idx; 8747 let Inst{11} = idx{1}; 8748 let Inst{21} = idx{0}; 8749 } 8750} 8751 8752multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8753 SDPatternOperator OpNode> { 8754 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8755 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8756 V128, V64, 8757 V128_lo, VectorIndexH, 8758 asm, ".4s", ".4s", ".4h", ".h", 8759 [(set (v4i32 V128:$Rd), 8760 (OpNode (v4i16 V64:$Rn), 8761 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8762 bits<3> idx; 8763 let Inst{11} = idx{2}; 8764 let Inst{21} = idx{1}; 8765 let Inst{20} = idx{0}; 8766 } 8767 8768 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8769 V128, V128, 8770 V128_lo, VectorIndexH, 8771 asm#"2", ".4s", ".4s", ".8h", ".h", 8772 [(set (v4i32 V128:$Rd), 8773 (OpNode (extract_high_v8i16 V128:$Rn), 8774 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8775 VectorIndexH:$idx))))]> { 8776 8777 bits<3> idx; 8778 let Inst{11} = idx{2}; 8779 let Inst{21} = idx{1}; 8780 let Inst{20} = idx{0}; 8781 } 8782 8783 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8784 V128, V64, 8785 V128, VectorIndexS, 8786 asm, ".2d", ".2d", ".2s", ".s", 8787 [(set (v2i64 V128:$Rd), 8788 (OpNode (v2i32 V64:$Rn), 8789 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8790 bits<2> idx; 8791 let Inst{11} = idx{1}; 8792 let Inst{21} = idx{0}; 8793 } 8794 8795 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8796 V128, V128, 8797 V128, VectorIndexS, 8798 asm#"2", ".2d", ".2d", ".4s", ".s", 8799 [(set (v2i64 V128:$Rd), 8800 (OpNode (extract_high_v4i32 V128:$Rn), 8801 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8802 VectorIndexS:$idx))))]> { 8803 bits<2> idx; 8804 let Inst{11} = idx{1}; 8805 let Inst{21} = idx{0}; 8806 } 8807 } 8808} 8809 8810multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8811 SDPatternOperator OpNode> { 8812 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8813 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8814 V128, V64, 8815 V128_lo, VectorIndexH, 8816 asm, ".4s", ".4s", ".4h", ".h", 8817 [(set (v4i32 V128:$dst), 8818 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8819 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8820 bits<3> idx; 8821 let Inst{11} = idx{2}; 8822 let Inst{21} = idx{1}; 8823 let Inst{20} = idx{0}; 8824 } 8825 8826 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8827 V128, V128, 8828 V128_lo, VectorIndexH, 8829 asm#"2", ".4s", ".4s", ".8h", ".h", 8830 [(set (v4i32 V128:$dst), 8831 (OpNode (v4i32 V128:$Rd), 8832 (extract_high_v8i16 V128:$Rn), 8833 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8834 VectorIndexH:$idx))))]> { 8835 bits<3> idx; 8836 let Inst{11} = idx{2}; 8837 let Inst{21} = idx{1}; 8838 let Inst{20} = idx{0}; 8839 } 8840 8841 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8842 V128, V64, 8843 V128, VectorIndexS, 8844 asm, ".2d", ".2d", ".2s", ".s", 8845 [(set (v2i64 V128:$dst), 8846 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8847 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8848 bits<2> idx; 8849 let Inst{11} = idx{1}; 8850 let Inst{21} = idx{0}; 8851 } 8852 8853 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8854 V128, V128, 8855 V128, VectorIndexS, 8856 asm#"2", ".2d", ".2d", ".4s", ".s", 8857 [(set (v2i64 V128:$dst), 8858 (OpNode (v2i64 V128:$Rd), 8859 (extract_high_v4i32 V128:$Rn), 8860 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8861 VectorIndexS:$idx))))]> { 8862 bits<2> idx; 8863 let Inst{11} = idx{1}; 8864 let Inst{21} = idx{0}; 8865 } 8866 } 8867} 8868 8869//---------------------------------------------------------------------------- 8870// AdvSIMD scalar shift by immediate 8871//---------------------------------------------------------------------------- 8872 8873let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8874class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8875 RegisterClass regtype1, RegisterClass regtype2, 8876 Operand immtype, string asm, list<dag> pattern> 8877 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8878 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8879 Sched<[WriteV]> { 8880 bits<5> Rd; 8881 bits<5> Rn; 8882 bits<7> imm; 8883 let Inst{31-30} = 0b01; 8884 let Inst{29} = U; 8885 let Inst{28-23} = 0b111110; 8886 let Inst{22-16} = fixed_imm; 8887 let Inst{15-11} = opc; 8888 let Inst{10} = 1; 8889 let Inst{9-5} = Rn; 8890 let Inst{4-0} = Rd; 8891} 8892 8893let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8894class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 8895 RegisterClass regtype1, RegisterClass regtype2, 8896 Operand immtype, string asm, list<dag> pattern> 8897 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 8898 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 8899 Sched<[WriteV]> { 8900 bits<5> Rd; 8901 bits<5> Rn; 8902 bits<7> imm; 8903 let Inst{31-30} = 0b01; 8904 let Inst{29} = U; 8905 let Inst{28-23} = 0b111110; 8906 let Inst{22-16} = fixed_imm; 8907 let Inst{15-11} = opc; 8908 let Inst{10} = 1; 8909 let Inst{9-5} = Rn; 8910 let Inst{4-0} = Rd; 8911} 8912 8913 8914multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 8915 let Predicates = [HasNEON, HasFullFP16] in { 8916 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8917 FPR16, FPR16, vecshiftR16, asm, []> { 8918 let Inst{19-16} = imm{3-0}; 8919 } 8920 } // Predicates = [HasNEON, HasFullFP16] 8921 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8922 FPR32, FPR32, vecshiftR32, asm, []> { 8923 let Inst{20-16} = imm{4-0}; 8924 } 8925 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8926 FPR64, FPR64, vecshiftR64, asm, []> { 8927 let Inst{21-16} = imm{5-0}; 8928 } 8929} 8930 8931multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 8932 SDPatternOperator OpNode> { 8933 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8934 FPR64, FPR64, vecshiftR64, asm, 8935 [(set (i64 FPR64:$Rd), 8936 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 8937 let Inst{21-16} = imm{5-0}; 8938 } 8939 8940 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 8941 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 8942} 8943 8944multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 8945 SDPatternOperator OpNode = null_frag> { 8946 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8947 FPR64, FPR64, vecshiftR64, asm, 8948 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 8949 (i32 vecshiftR64:$imm)))]> { 8950 let Inst{21-16} = imm{5-0}; 8951 } 8952 8953 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 8954 (i32 vecshiftR64:$imm))), 8955 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 8956 vecshiftR64:$imm)>; 8957} 8958 8959multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 8960 SDPatternOperator OpNode> { 8961 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8962 FPR64, FPR64, vecshiftL64, asm, 8963 [(set (i64 FPR64:$Rd), 8964 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8965 let Inst{21-16} = imm{5-0}; 8966 } 8967 8968 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 8969 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 8970} 8971 8972let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8973multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 8974 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8975 FPR64, FPR64, vecshiftL64, asm, []> { 8976 let Inst{21-16} = imm{5-0}; 8977 } 8978} 8979 8980let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8981multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 8982 SDPatternOperator OpNode = null_frag> { 8983 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8984 FPR8, FPR16, vecshiftR8, asm, []> { 8985 let Inst{18-16} = imm{2-0}; 8986 } 8987 8988 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8989 FPR16, FPR32, vecshiftR16, asm, []> { 8990 let Inst{19-16} = imm{3-0}; 8991 } 8992 8993 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8994 FPR32, FPR64, vecshiftR32, asm, 8995 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 8996 let Inst{20-16} = imm{4-0}; 8997 } 8998} 8999 9000multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9001 SDPatternOperator OpNode> { 9002 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9003 FPR8, FPR8, vecshiftL8, asm, []> { 9004 let Inst{18-16} = imm{2-0}; 9005 } 9006 9007 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9008 FPR16, FPR16, vecshiftL16, asm, []> { 9009 let Inst{19-16} = imm{3-0}; 9010 } 9011 9012 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9013 FPR32, FPR32, vecshiftL32, asm, 9014 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9015 let Inst{20-16} = imm{4-0}; 9016 } 9017 9018 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9019 FPR64, FPR64, vecshiftL64, asm, 9020 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9021 let Inst{21-16} = imm{5-0}; 9022 } 9023 9024 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9025 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9026} 9027 9028multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9029 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9030 FPR8, FPR8, vecshiftR8, asm, []> { 9031 let Inst{18-16} = imm{2-0}; 9032 } 9033 9034 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9035 FPR16, FPR16, vecshiftR16, asm, []> { 9036 let Inst{19-16} = imm{3-0}; 9037 } 9038 9039 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9040 FPR32, FPR32, vecshiftR32, asm, []> { 9041 let Inst{20-16} = imm{4-0}; 9042 } 9043 9044 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9045 FPR64, FPR64, vecshiftR64, asm, []> { 9046 let Inst{21-16} = imm{5-0}; 9047 } 9048} 9049 9050//---------------------------------------------------------------------------- 9051// AdvSIMD vector x indexed element 9052//---------------------------------------------------------------------------- 9053 9054let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9055class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9056 RegisterOperand dst_reg, RegisterOperand src_reg, 9057 Operand immtype, 9058 string asm, string dst_kind, string src_kind, 9059 list<dag> pattern> 9060 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9061 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9062 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9063 Sched<[WriteV]> { 9064 bits<5> Rd; 9065 bits<5> Rn; 9066 let Inst{31} = 0; 9067 let Inst{30} = Q; 9068 let Inst{29} = U; 9069 let Inst{28-23} = 0b011110; 9070 let Inst{22-16} = fixed_imm; 9071 let Inst{15-11} = opc; 9072 let Inst{10} = 1; 9073 let Inst{9-5} = Rn; 9074 let Inst{4-0} = Rd; 9075} 9076 9077let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9078class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9079 RegisterOperand vectype1, RegisterOperand vectype2, 9080 Operand immtype, 9081 string asm, string dst_kind, string src_kind, 9082 list<dag> pattern> 9083 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9084 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9085 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9086 Sched<[WriteV]> { 9087 bits<5> Rd; 9088 bits<5> Rn; 9089 let Inst{31} = 0; 9090 let Inst{30} = Q; 9091 let Inst{29} = U; 9092 let Inst{28-23} = 0b011110; 9093 let Inst{22-16} = fixed_imm; 9094 let Inst{15-11} = opc; 9095 let Inst{10} = 1; 9096 let Inst{9-5} = Rn; 9097 let Inst{4-0} = Rd; 9098} 9099 9100multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9101 Intrinsic OpNode> { 9102 let Predicates = [HasNEON, HasFullFP16] in { 9103 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9104 V64, V64, vecshiftR16, 9105 asm, ".4h", ".4h", 9106 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9107 bits<4> imm; 9108 let Inst{19-16} = imm; 9109 } 9110 9111 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9112 V128, V128, vecshiftR16, 9113 asm, ".8h", ".8h", 9114 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9115 bits<4> imm; 9116 let Inst{19-16} = imm; 9117 } 9118 } // Predicates = [HasNEON, HasFullFP16] 9119 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9120 V64, V64, vecshiftR32, 9121 asm, ".2s", ".2s", 9122 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9123 bits<5> imm; 9124 let Inst{20-16} = imm; 9125 } 9126 9127 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9128 V128, V128, vecshiftR32, 9129 asm, ".4s", ".4s", 9130 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9131 bits<5> imm; 9132 let Inst{20-16} = imm; 9133 } 9134 9135 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9136 V128, V128, vecshiftR64, 9137 asm, ".2d", ".2d", 9138 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9139 bits<6> imm; 9140 let Inst{21-16} = imm; 9141 } 9142} 9143 9144multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9145 Intrinsic OpNode> { 9146 let Predicates = [HasNEON, HasFullFP16] in { 9147 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9148 V64, V64, vecshiftR16, 9149 asm, ".4h", ".4h", 9150 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9151 bits<4> imm; 9152 let Inst{19-16} = imm; 9153 } 9154 9155 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9156 V128, V128, vecshiftR16, 9157 asm, ".8h", ".8h", 9158 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9159 bits<4> imm; 9160 let Inst{19-16} = imm; 9161 } 9162 } // Predicates = [HasNEON, HasFullFP16] 9163 9164 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9165 V64, V64, vecshiftR32, 9166 asm, ".2s", ".2s", 9167 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9168 bits<5> imm; 9169 let Inst{20-16} = imm; 9170 } 9171 9172 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9173 V128, V128, vecshiftR32, 9174 asm, ".4s", ".4s", 9175 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9176 bits<5> imm; 9177 let Inst{20-16} = imm; 9178 } 9179 9180 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9181 V128, V128, vecshiftR64, 9182 asm, ".2d", ".2d", 9183 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9184 bits<6> imm; 9185 let Inst{21-16} = imm; 9186 } 9187} 9188 9189multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9190 SDPatternOperator OpNode> { 9191 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9192 V64, V128, vecshiftR16Narrow, 9193 asm, ".8b", ".8h", 9194 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9195 bits<3> imm; 9196 let Inst{18-16} = imm; 9197 } 9198 9199 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9200 V128, V128, vecshiftR16Narrow, 9201 asm#"2", ".16b", ".8h", []> { 9202 bits<3> imm; 9203 let Inst{18-16} = imm; 9204 let hasSideEffects = 0; 9205 } 9206 9207 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9208 V64, V128, vecshiftR32Narrow, 9209 asm, ".4h", ".4s", 9210 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9211 bits<4> imm; 9212 let Inst{19-16} = imm; 9213 } 9214 9215 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9216 V128, V128, vecshiftR32Narrow, 9217 asm#"2", ".8h", ".4s", []> { 9218 bits<4> imm; 9219 let Inst{19-16} = imm; 9220 let hasSideEffects = 0; 9221 } 9222 9223 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9224 V64, V128, vecshiftR64Narrow, 9225 asm, ".2s", ".2d", 9226 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9227 bits<5> imm; 9228 let Inst{20-16} = imm; 9229 } 9230 9231 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9232 V128, V128, vecshiftR64Narrow, 9233 asm#"2", ".4s", ".2d", []> { 9234 bits<5> imm; 9235 let Inst{20-16} = imm; 9236 let hasSideEffects = 0; 9237 } 9238 9239 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9240 // themselves, so put them here instead. 9241 9242 // Patterns involving what's effectively an insert high and a normal 9243 // intrinsic, represented by CONCAT_VECTORS. 9244 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9245 vecshiftR16Narrow:$imm)), 9246 (!cast<Instruction>(NAME # "v16i8_shift") 9247 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9248 V128:$Rn, vecshiftR16Narrow:$imm)>; 9249 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9250 vecshiftR32Narrow:$imm)), 9251 (!cast<Instruction>(NAME # "v8i16_shift") 9252 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9253 V128:$Rn, vecshiftR32Narrow:$imm)>; 9254 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9255 vecshiftR64Narrow:$imm)), 9256 (!cast<Instruction>(NAME # "v4i32_shift") 9257 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9258 V128:$Rn, vecshiftR64Narrow:$imm)>; 9259} 9260 9261multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9262 SDPatternOperator OpNode> { 9263 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9264 V64, V64, vecshiftL8, 9265 asm, ".8b", ".8b", 9266 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9267 (i32 vecshiftL8:$imm)))]> { 9268 bits<3> imm; 9269 let Inst{18-16} = imm; 9270 } 9271 9272 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9273 V128, V128, vecshiftL8, 9274 asm, ".16b", ".16b", 9275 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9276 (i32 vecshiftL8:$imm)))]> { 9277 bits<3> imm; 9278 let Inst{18-16} = imm; 9279 } 9280 9281 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9282 V64, V64, vecshiftL16, 9283 asm, ".4h", ".4h", 9284 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9285 (i32 vecshiftL16:$imm)))]> { 9286 bits<4> imm; 9287 let Inst{19-16} = imm; 9288 } 9289 9290 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9291 V128, V128, vecshiftL16, 9292 asm, ".8h", ".8h", 9293 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9294 (i32 vecshiftL16:$imm)))]> { 9295 bits<4> imm; 9296 let Inst{19-16} = imm; 9297 } 9298 9299 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9300 V64, V64, vecshiftL32, 9301 asm, ".2s", ".2s", 9302 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9303 (i32 vecshiftL32:$imm)))]> { 9304 bits<5> imm; 9305 let Inst{20-16} = imm; 9306 } 9307 9308 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9309 V128, V128, vecshiftL32, 9310 asm, ".4s", ".4s", 9311 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9312 (i32 vecshiftL32:$imm)))]> { 9313 bits<5> imm; 9314 let Inst{20-16} = imm; 9315 } 9316 9317 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9318 V128, V128, vecshiftL64, 9319 asm, ".2d", ".2d", 9320 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9321 (i32 vecshiftL64:$imm)))]> { 9322 bits<6> imm; 9323 let Inst{21-16} = imm; 9324 } 9325} 9326 9327multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9328 SDPatternOperator OpNode> { 9329 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9330 V64, V64, vecshiftR8, 9331 asm, ".8b", ".8b", 9332 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9333 (i32 vecshiftR8:$imm)))]> { 9334 bits<3> imm; 9335 let Inst{18-16} = imm; 9336 } 9337 9338 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9339 V128, V128, vecshiftR8, 9340 asm, ".16b", ".16b", 9341 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9342 (i32 vecshiftR8:$imm)))]> { 9343 bits<3> imm; 9344 let Inst{18-16} = imm; 9345 } 9346 9347 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9348 V64, V64, vecshiftR16, 9349 asm, ".4h", ".4h", 9350 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9351 (i32 vecshiftR16:$imm)))]> { 9352 bits<4> imm; 9353 let Inst{19-16} = imm; 9354 } 9355 9356 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9357 V128, V128, vecshiftR16, 9358 asm, ".8h", ".8h", 9359 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9360 (i32 vecshiftR16:$imm)))]> { 9361 bits<4> imm; 9362 let Inst{19-16} = imm; 9363 } 9364 9365 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9366 V64, V64, vecshiftR32, 9367 asm, ".2s", ".2s", 9368 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9369 (i32 vecshiftR32:$imm)))]> { 9370 bits<5> imm; 9371 let Inst{20-16} = imm; 9372 } 9373 9374 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9375 V128, V128, vecshiftR32, 9376 asm, ".4s", ".4s", 9377 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9378 (i32 vecshiftR32:$imm)))]> { 9379 bits<5> imm; 9380 let Inst{20-16} = imm; 9381 } 9382 9383 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9384 V128, V128, vecshiftR64, 9385 asm, ".2d", ".2d", 9386 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9387 (i32 vecshiftR64:$imm)))]> { 9388 bits<6> imm; 9389 let Inst{21-16} = imm; 9390 } 9391} 9392 9393let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9394multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9395 SDPatternOperator OpNode = null_frag> { 9396 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9397 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9398 [(set (v8i8 V64:$dst), 9399 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9400 (i32 vecshiftR8:$imm)))]> { 9401 bits<3> imm; 9402 let Inst{18-16} = imm; 9403 } 9404 9405 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9406 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9407 [(set (v16i8 V128:$dst), 9408 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9409 (i32 vecshiftR8:$imm)))]> { 9410 bits<3> imm; 9411 let Inst{18-16} = imm; 9412 } 9413 9414 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9415 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9416 [(set (v4i16 V64:$dst), 9417 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9418 (i32 vecshiftR16:$imm)))]> { 9419 bits<4> imm; 9420 let Inst{19-16} = imm; 9421 } 9422 9423 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9424 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9425 [(set (v8i16 V128:$dst), 9426 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9427 (i32 vecshiftR16:$imm)))]> { 9428 bits<4> imm; 9429 let Inst{19-16} = imm; 9430 } 9431 9432 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9433 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9434 [(set (v2i32 V64:$dst), 9435 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9436 (i32 vecshiftR32:$imm)))]> { 9437 bits<5> imm; 9438 let Inst{20-16} = imm; 9439 } 9440 9441 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9442 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9443 [(set (v4i32 V128:$dst), 9444 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9445 (i32 vecshiftR32:$imm)))]> { 9446 bits<5> imm; 9447 let Inst{20-16} = imm; 9448 } 9449 9450 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9451 V128, V128, vecshiftR64, 9452 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9453 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9454 (i32 vecshiftR64:$imm)))]> { 9455 bits<6> imm; 9456 let Inst{21-16} = imm; 9457 } 9458} 9459 9460multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9461 SDPatternOperator OpNode = null_frag> { 9462 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9463 V64, V64, vecshiftL8, 9464 asm, ".8b", ".8b", 9465 [(set (v8i8 V64:$dst), 9466 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9467 (i32 vecshiftL8:$imm)))]> { 9468 bits<3> imm; 9469 let Inst{18-16} = imm; 9470 } 9471 9472 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9473 V128, V128, vecshiftL8, 9474 asm, ".16b", ".16b", 9475 [(set (v16i8 V128:$dst), 9476 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9477 (i32 vecshiftL8:$imm)))]> { 9478 bits<3> imm; 9479 let Inst{18-16} = imm; 9480 } 9481 9482 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9483 V64, V64, vecshiftL16, 9484 asm, ".4h", ".4h", 9485 [(set (v4i16 V64:$dst), 9486 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9487 (i32 vecshiftL16:$imm)))]> { 9488 bits<4> imm; 9489 let Inst{19-16} = imm; 9490 } 9491 9492 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9493 V128, V128, vecshiftL16, 9494 asm, ".8h", ".8h", 9495 [(set (v8i16 V128:$dst), 9496 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9497 (i32 vecshiftL16:$imm)))]> { 9498 bits<4> imm; 9499 let Inst{19-16} = imm; 9500 } 9501 9502 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9503 V64, V64, vecshiftL32, 9504 asm, ".2s", ".2s", 9505 [(set (v2i32 V64:$dst), 9506 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9507 (i32 vecshiftL32:$imm)))]> { 9508 bits<5> imm; 9509 let Inst{20-16} = imm; 9510 } 9511 9512 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9513 V128, V128, vecshiftL32, 9514 asm, ".4s", ".4s", 9515 [(set (v4i32 V128:$dst), 9516 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9517 (i32 vecshiftL32:$imm)))]> { 9518 bits<5> imm; 9519 let Inst{20-16} = imm; 9520 } 9521 9522 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9523 V128, V128, vecshiftL64, 9524 asm, ".2d", ".2d", 9525 [(set (v2i64 V128:$dst), 9526 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9527 (i32 vecshiftL64:$imm)))]> { 9528 bits<6> imm; 9529 let Inst{21-16} = imm; 9530 } 9531} 9532 9533multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9534 SDPatternOperator OpNode> { 9535 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9536 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9537 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9538 bits<3> imm; 9539 let Inst{18-16} = imm; 9540 } 9541 9542 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9543 V128, V128, vecshiftL8, 9544 asm#"2", ".8h", ".16b", 9545 [(set (v8i16 V128:$Rd), 9546 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 9547 bits<3> imm; 9548 let Inst{18-16} = imm; 9549 } 9550 9551 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9552 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9553 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9554 bits<4> imm; 9555 let Inst{19-16} = imm; 9556 } 9557 9558 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9559 V128, V128, vecshiftL16, 9560 asm#"2", ".4s", ".8h", 9561 [(set (v4i32 V128:$Rd), 9562 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 9563 9564 bits<4> imm; 9565 let Inst{19-16} = imm; 9566 } 9567 9568 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9569 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9570 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9571 bits<5> imm; 9572 let Inst{20-16} = imm; 9573 } 9574 9575 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9576 V128, V128, vecshiftL32, 9577 asm#"2", ".2d", ".4s", 9578 [(set (v2i64 V128:$Rd), 9579 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9580 bits<5> imm; 9581 let Inst{20-16} = imm; 9582 } 9583} 9584 9585 9586//--- 9587// Vector load/store 9588//--- 9589// SIMD ldX/stX no-index memory references don't allow the optional 9590// ", #0" constant and handle post-indexing explicitly, so we use 9591// a more specialized parse method for them. Otherwise, it's the same as 9592// the general GPR64sp handling. 9593 9594class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9595 string asm, dag oops, dag iops, list<dag> pattern> 9596 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9597 bits<5> Vt; 9598 bits<5> Rn; 9599 let Inst{31} = 0; 9600 let Inst{30} = Q; 9601 let Inst{29-23} = 0b0011000; 9602 let Inst{22} = L; 9603 let Inst{21-16} = 0b000000; 9604 let Inst{15-12} = opcode; 9605 let Inst{11-10} = size; 9606 let Inst{9-5} = Rn; 9607 let Inst{4-0} = Vt; 9608} 9609 9610class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9611 string asm, dag oops, dag iops> 9612 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9613 bits<5> Vt; 9614 bits<5> Rn; 9615 bits<5> Xm; 9616 let Inst{31} = 0; 9617 let Inst{30} = Q; 9618 let Inst{29-23} = 0b0011001; 9619 let Inst{22} = L; 9620 let Inst{21} = 0; 9621 let Inst{20-16} = Xm; 9622 let Inst{15-12} = opcode; 9623 let Inst{11-10} = size; 9624 let Inst{9-5} = Rn; 9625 let Inst{4-0} = Vt; 9626} 9627 9628// The immediate form of AdvSIMD post-indexed addressing is encoded with 9629// register post-index addressing from the zero register. 9630multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9631 int Offset, int Size> { 9632 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9633 // "ld1\t$Vt, [$Rn], #16" 9634 // may get mapped to 9635 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9636 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9637 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9638 GPR64sp:$Rn, 9639 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9640 XZR), 1>; 9641 9642 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9643 // "ld1.8b\t$Vt, [$Rn], #16" 9644 // may get mapped to 9645 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9646 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9647 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9648 GPR64sp:$Rn, 9649 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9650 XZR), 0>; 9651 9652 // E.g. "ld1.8b { v0, v1 }, [x1]" 9653 // "ld1\t$Vt, [$Rn]" 9654 // may get mapped to 9655 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9656 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9657 (!cast<Instruction>(BaseName # Count # "v" # layout) 9658 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9659 GPR64sp:$Rn), 0>; 9660 9661 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9662 // "ld1\t$Vt, [$Rn], $Xm" 9663 // may get mapped to 9664 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9665 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9666 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9667 GPR64sp:$Rn, 9668 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9669 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9670} 9671 9672multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9673 int Offset128, int Offset64, bits<4> opcode> { 9674 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9675 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9676 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9677 (ins GPR64sp:$Rn), []>; 9678 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9679 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9680 (ins GPR64sp:$Rn), []>; 9681 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9682 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9683 (ins GPR64sp:$Rn), []>; 9684 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9685 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9686 (ins GPR64sp:$Rn), []>; 9687 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9688 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9689 (ins GPR64sp:$Rn), []>; 9690 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9691 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9692 (ins GPR64sp:$Rn), []>; 9693 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9694 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9695 (ins GPR64sp:$Rn), []>; 9696 9697 9698 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9699 (outs GPR64sp:$wback, 9700 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9701 (ins GPR64sp:$Rn, 9702 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9703 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9704 (outs GPR64sp:$wback, 9705 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9706 (ins GPR64sp:$Rn, 9707 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9708 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9709 (outs GPR64sp:$wback, 9710 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9711 (ins GPR64sp:$Rn, 9712 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9713 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9714 (outs GPR64sp:$wback, 9715 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9716 (ins GPR64sp:$Rn, 9717 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9718 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9719 (outs GPR64sp:$wback, 9720 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9721 (ins GPR64sp:$Rn, 9722 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9723 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9724 (outs GPR64sp:$wback, 9725 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9726 (ins GPR64sp:$Rn, 9727 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9728 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9729 (outs GPR64sp:$wback, 9730 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9731 (ins GPR64sp:$Rn, 9732 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9733 } 9734 9735 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9736 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9737 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9738 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9739 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9740 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9741 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9742} 9743 9744// Only ld1/st1 has a v1d version. 9745multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9746 int Offset128, int Offset64, bits<4> opcode> { 9747 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9748 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9749 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9750 GPR64sp:$Rn), []>; 9751 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9752 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9753 GPR64sp:$Rn), []>; 9754 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9755 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9756 GPR64sp:$Rn), []>; 9757 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9758 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9759 GPR64sp:$Rn), []>; 9760 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9761 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9762 GPR64sp:$Rn), []>; 9763 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9764 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9765 GPR64sp:$Rn), []>; 9766 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9767 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9768 GPR64sp:$Rn), []>; 9769 9770 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9771 (outs GPR64sp:$wback), 9772 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9773 GPR64sp:$Rn, 9774 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9775 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9776 (outs GPR64sp:$wback), 9777 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9778 GPR64sp:$Rn, 9779 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9780 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9781 (outs GPR64sp:$wback), 9782 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9783 GPR64sp:$Rn, 9784 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9785 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9786 (outs GPR64sp:$wback), 9787 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9788 GPR64sp:$Rn, 9789 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9790 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9791 (outs GPR64sp:$wback), 9792 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9793 GPR64sp:$Rn, 9794 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9795 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9796 (outs GPR64sp:$wback), 9797 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9798 GPR64sp:$Rn, 9799 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9800 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9801 (outs GPR64sp:$wback), 9802 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9803 GPR64sp:$Rn, 9804 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9805 } 9806 9807 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9808 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9809 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9810 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9811 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9812 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9813 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9814} 9815 9816multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9817 int Offset128, int Offset64, bits<4> opcode> 9818 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9819 9820 // LD1 instructions have extra "1d" variants. 9821 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9822 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9823 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9824 (ins GPR64sp:$Rn), []>; 9825 9826 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9827 (outs GPR64sp:$wback, 9828 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9829 (ins GPR64sp:$Rn, 9830 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9831 } 9832 9833 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9834} 9835 9836multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9837 int Offset128, int Offset64, bits<4> opcode> 9838 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9839 9840 // ST1 instructions have extra "1d" variants. 9841 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9842 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9843 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9844 GPR64sp:$Rn), []>; 9845 9846 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9847 (outs GPR64sp:$wback), 9848 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9849 GPR64sp:$Rn, 9850 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9851 } 9852 9853 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9854} 9855 9856multiclass SIMDLd1Multiple<string asm> { 9857 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9858 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9859 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9860 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9861} 9862 9863multiclass SIMDSt1Multiple<string asm> { 9864 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9865 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9866 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9867 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9868} 9869 9870multiclass SIMDLd2Multiple<string asm> { 9871 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9872} 9873 9874multiclass SIMDSt2Multiple<string asm> { 9875 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9876} 9877 9878multiclass SIMDLd3Multiple<string asm> { 9879 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9880} 9881 9882multiclass SIMDSt3Multiple<string asm> { 9883 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9884} 9885 9886multiclass SIMDLd4Multiple<string asm> { 9887 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9888} 9889 9890multiclass SIMDSt4Multiple<string asm> { 9891 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9892} 9893 9894//--- 9895// AdvSIMD Load/store single-element 9896//--- 9897 9898class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 9899 string asm, string operands, string cst, 9900 dag oops, dag iops, list<dag> pattern> 9901 : I<oops, iops, asm, operands, cst, pattern> { 9902 bits<5> Vt; 9903 bits<5> Rn; 9904 let Inst{31} = 0; 9905 let Inst{29-24} = 0b001101; 9906 let Inst{22} = L; 9907 let Inst{21} = R; 9908 let Inst{15-13} = opcode; 9909 let Inst{9-5} = Rn; 9910 let Inst{4-0} = Vt; 9911} 9912 9913class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 9914 string asm, string operands, string cst, 9915 dag oops, dag iops, list<dag> pattern> 9916 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 9917 bits<5> Vt; 9918 bits<5> Rn; 9919 let Inst{31} = 0; 9920 let Inst{29-24} = 0b001101; 9921 let Inst{22} = L; 9922 let Inst{21} = R; 9923 let Inst{15-13} = opcode; 9924 let Inst{9-5} = Rn; 9925 let Inst{4-0} = Vt; 9926} 9927 9928 9929let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9930class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 9931 DAGOperand listtype> 9932 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 9933 (outs listtype:$Vt), (ins GPR64sp:$Rn), 9934 []> { 9935 let Inst{30} = Q; 9936 let Inst{23} = 0; 9937 let Inst{20-16} = 0b00000; 9938 let Inst{12} = S; 9939 let Inst{11-10} = size; 9940} 9941let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9942class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 9943 string asm, DAGOperand listtype, DAGOperand GPR64pi> 9944 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 9945 "$Rn = $wback", 9946 (outs GPR64sp:$wback, listtype:$Vt), 9947 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 9948 bits<5> Xm; 9949 let Inst{30} = Q; 9950 let Inst{23} = 1; 9951 let Inst{20-16} = Xm; 9952 let Inst{12} = S; 9953 let Inst{11-10} = size; 9954} 9955 9956multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 9957 int Offset, int Size> { 9958 // E.g. "ld1r { v0.8b }, [x1], #1" 9959 // "ld1r.8b\t$Vt, [$Rn], #1" 9960 // may get mapped to 9961 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9962 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9963 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9964 GPR64sp:$Rn, 9965 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9966 XZR), 1>; 9967 9968 // E.g. "ld1r.8b { v0 }, [x1], #1" 9969 // "ld1r.8b\t$Vt, [$Rn], #1" 9970 // may get mapped to 9971 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9972 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9973 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9974 GPR64sp:$Rn, 9975 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9976 XZR), 0>; 9977 9978 // E.g. "ld1r.8b { v0 }, [x1]" 9979 // "ld1r.8b\t$Vt, [$Rn]" 9980 // may get mapped to 9981 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9982 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9983 (!cast<Instruction>(BaseName # "v" # layout) 9984 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9985 GPR64sp:$Rn), 0>; 9986 9987 // E.g. "ld1r.8b { v0 }, [x1], x2" 9988 // "ld1r.8b\t$Vt, [$Rn], $Xm" 9989 // may get mapped to 9990 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9991 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9992 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9993 GPR64sp:$Rn, 9994 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9995 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9996} 9997 9998multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 9999 int Offset1, int Offset2, int Offset4, int Offset8> { 10000 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10001 !cast<DAGOperand>("VecList" # Count # "8b")>; 10002 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10003 !cast<DAGOperand>("VecList" # Count #"16b")>; 10004 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10005 !cast<DAGOperand>("VecList" # Count #"4h")>; 10006 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10007 !cast<DAGOperand>("VecList" # Count #"8h")>; 10008 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10009 !cast<DAGOperand>("VecList" # Count #"2s")>; 10010 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10011 !cast<DAGOperand>("VecList" # Count #"4s")>; 10012 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10013 !cast<DAGOperand>("VecList" # Count #"1d")>; 10014 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10015 !cast<DAGOperand>("VecList" # Count #"2d")>; 10016 10017 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10018 !cast<DAGOperand>("VecList" # Count # "8b"), 10019 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10020 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10021 !cast<DAGOperand>("VecList" # Count # "16b"), 10022 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10023 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10024 !cast<DAGOperand>("VecList" # Count # "4h"), 10025 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10026 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10027 !cast<DAGOperand>("VecList" # Count # "8h"), 10028 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10029 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10030 !cast<DAGOperand>("VecList" # Count # "2s"), 10031 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10032 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10033 !cast<DAGOperand>("VecList" # Count # "4s"), 10034 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10035 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10036 !cast<DAGOperand>("VecList" # Count # "1d"), 10037 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10038 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10039 !cast<DAGOperand>("VecList" # Count # "2d"), 10040 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10041 10042 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10043 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10044 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10045 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10046 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10047 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10048 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10049 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10050} 10051 10052class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10053 dag oops, dag iops, list<dag> pattern> 10054 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10055 pattern> { 10056 // idx encoded in Q:S:size fields. 10057 bits<4> idx; 10058 let Inst{30} = idx{3}; 10059 let Inst{23} = 0; 10060 let Inst{20-16} = 0b00000; 10061 let Inst{12} = idx{2}; 10062 let Inst{11-10} = idx{1-0}; 10063} 10064class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10065 dag oops, dag iops, list<dag> pattern> 10066 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10067 oops, iops, pattern> { 10068 // idx encoded in Q:S:size fields. 10069 bits<4> idx; 10070 let Inst{30} = idx{3}; 10071 let Inst{23} = 0; 10072 let Inst{20-16} = 0b00000; 10073 let Inst{12} = idx{2}; 10074 let Inst{11-10} = idx{1-0}; 10075} 10076class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10077 dag oops, dag iops> 10078 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10079 "$Rn = $wback", oops, iops, []> { 10080 // idx encoded in Q:S:size fields. 10081 bits<4> idx; 10082 bits<5> Xm; 10083 let Inst{30} = idx{3}; 10084 let Inst{23} = 1; 10085 let Inst{20-16} = Xm; 10086 let Inst{12} = idx{2}; 10087 let Inst{11-10} = idx{1-0}; 10088} 10089class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10090 dag oops, dag iops> 10091 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10092 "$Rn = $wback", oops, iops, []> { 10093 // idx encoded in Q:S:size fields. 10094 bits<4> idx; 10095 bits<5> Xm; 10096 let Inst{30} = idx{3}; 10097 let Inst{23} = 1; 10098 let Inst{20-16} = Xm; 10099 let Inst{12} = idx{2}; 10100 let Inst{11-10} = idx{1-0}; 10101} 10102 10103class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10104 dag oops, dag iops, list<dag> pattern> 10105 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10106 pattern> { 10107 // idx encoded in Q:S:size<1> fields. 10108 bits<3> idx; 10109 let Inst{30} = idx{2}; 10110 let Inst{23} = 0; 10111 let Inst{20-16} = 0b00000; 10112 let Inst{12} = idx{1}; 10113 let Inst{11} = idx{0}; 10114 let Inst{10} = size; 10115} 10116class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10117 dag oops, dag iops, list<dag> pattern> 10118 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10119 oops, iops, pattern> { 10120 // idx encoded in Q:S:size<1> fields. 10121 bits<3> idx; 10122 let Inst{30} = idx{2}; 10123 let Inst{23} = 0; 10124 let Inst{20-16} = 0b00000; 10125 let Inst{12} = idx{1}; 10126 let Inst{11} = idx{0}; 10127 let Inst{10} = size; 10128} 10129 10130class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10131 dag oops, dag iops> 10132 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10133 "$Rn = $wback", oops, iops, []> { 10134 // idx encoded in Q:S:size<1> fields. 10135 bits<3> idx; 10136 bits<5> Xm; 10137 let Inst{30} = idx{2}; 10138 let Inst{23} = 1; 10139 let Inst{20-16} = Xm; 10140 let Inst{12} = idx{1}; 10141 let Inst{11} = idx{0}; 10142 let Inst{10} = size; 10143} 10144class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10145 dag oops, dag iops> 10146 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10147 "$Rn = $wback", oops, iops, []> { 10148 // idx encoded in Q:S:size<1> fields. 10149 bits<3> idx; 10150 bits<5> Xm; 10151 let Inst{30} = idx{2}; 10152 let Inst{23} = 1; 10153 let Inst{20-16} = Xm; 10154 let Inst{12} = idx{1}; 10155 let Inst{11} = idx{0}; 10156 let Inst{10} = size; 10157} 10158class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10159 dag oops, dag iops, list<dag> pattern> 10160 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10161 pattern> { 10162 // idx encoded in Q:S fields. 10163 bits<2> idx; 10164 let Inst{30} = idx{1}; 10165 let Inst{23} = 0; 10166 let Inst{20-16} = 0b00000; 10167 let Inst{12} = idx{0}; 10168 let Inst{11-10} = size; 10169} 10170class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10171 dag oops, dag iops, list<dag> pattern> 10172 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10173 oops, iops, pattern> { 10174 // idx encoded in Q:S fields. 10175 bits<2> idx; 10176 let Inst{30} = idx{1}; 10177 let Inst{23} = 0; 10178 let Inst{20-16} = 0b00000; 10179 let Inst{12} = idx{0}; 10180 let Inst{11-10} = size; 10181} 10182class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10183 string asm, dag oops, dag iops> 10184 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10185 "$Rn = $wback", oops, iops, []> { 10186 // idx encoded in Q:S fields. 10187 bits<2> idx; 10188 bits<5> Xm; 10189 let Inst{30} = idx{1}; 10190 let Inst{23} = 1; 10191 let Inst{20-16} = Xm; 10192 let Inst{12} = idx{0}; 10193 let Inst{11-10} = size; 10194} 10195class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10196 string asm, dag oops, dag iops> 10197 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10198 "$Rn = $wback", oops, iops, []> { 10199 // idx encoded in Q:S fields. 10200 bits<2> idx; 10201 bits<5> Xm; 10202 let Inst{30} = idx{1}; 10203 let Inst{23} = 1; 10204 let Inst{20-16} = Xm; 10205 let Inst{12} = idx{0}; 10206 let Inst{11-10} = size; 10207} 10208class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10209 dag oops, dag iops, list<dag> pattern> 10210 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10211 pattern> { 10212 // idx encoded in Q field. 10213 bits<1> idx; 10214 let Inst{30} = idx; 10215 let Inst{23} = 0; 10216 let Inst{20-16} = 0b00000; 10217 let Inst{12} = 0; 10218 let Inst{11-10} = size; 10219} 10220class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10221 dag oops, dag iops, list<dag> pattern> 10222 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10223 oops, iops, pattern> { 10224 // idx encoded in Q field. 10225 bits<1> idx; 10226 let Inst{30} = idx; 10227 let Inst{23} = 0; 10228 let Inst{20-16} = 0b00000; 10229 let Inst{12} = 0; 10230 let Inst{11-10} = size; 10231} 10232class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10233 string asm, dag oops, dag iops> 10234 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10235 "$Rn = $wback", oops, iops, []> { 10236 // idx encoded in Q field. 10237 bits<1> idx; 10238 bits<5> Xm; 10239 let Inst{30} = idx; 10240 let Inst{23} = 1; 10241 let Inst{20-16} = Xm; 10242 let Inst{12} = 0; 10243 let Inst{11-10} = size; 10244} 10245class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10246 string asm, dag oops, dag iops> 10247 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10248 "$Rn = $wback", oops, iops, []> { 10249 // idx encoded in Q field. 10250 bits<1> idx; 10251 bits<5> Xm; 10252 let Inst{30} = idx; 10253 let Inst{23} = 1; 10254 let Inst{20-16} = Xm; 10255 let Inst{12} = 0; 10256 let Inst{11-10} = size; 10257} 10258 10259let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10260multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10261 RegisterOperand listtype, 10262 RegisterOperand GPR64pi> { 10263 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10264 (outs listtype:$dst), 10265 (ins listtype:$Vt, VectorIndexB:$idx, 10266 GPR64sp:$Rn), []>; 10267 10268 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10269 (outs GPR64sp:$wback, listtype:$dst), 10270 (ins listtype:$Vt, VectorIndexB:$idx, 10271 GPR64sp:$Rn, GPR64pi:$Xm)>; 10272} 10273let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10274multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10275 RegisterOperand listtype, 10276 RegisterOperand GPR64pi> { 10277 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10278 (outs listtype:$dst), 10279 (ins listtype:$Vt, VectorIndexH:$idx, 10280 GPR64sp:$Rn), []>; 10281 10282 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10283 (outs GPR64sp:$wback, listtype:$dst), 10284 (ins listtype:$Vt, VectorIndexH:$idx, 10285 GPR64sp:$Rn, GPR64pi:$Xm)>; 10286} 10287let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10288multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10289 RegisterOperand listtype, 10290 RegisterOperand GPR64pi> { 10291 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10292 (outs listtype:$dst), 10293 (ins listtype:$Vt, VectorIndexS:$idx, 10294 GPR64sp:$Rn), []>; 10295 10296 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10297 (outs GPR64sp:$wback, listtype:$dst), 10298 (ins listtype:$Vt, VectorIndexS:$idx, 10299 GPR64sp:$Rn, GPR64pi:$Xm)>; 10300} 10301let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10302multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10303 RegisterOperand listtype, RegisterOperand GPR64pi> { 10304 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10305 (outs listtype:$dst), 10306 (ins listtype:$Vt, VectorIndexD:$idx, 10307 GPR64sp:$Rn), []>; 10308 10309 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10310 (outs GPR64sp:$wback, listtype:$dst), 10311 (ins listtype:$Vt, VectorIndexD:$idx, 10312 GPR64sp:$Rn, GPR64pi:$Xm)>; 10313} 10314let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10315multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10316 RegisterOperand listtype, RegisterOperand GPR64pi> { 10317 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10318 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10319 GPR64sp:$Rn), []>; 10320 10321 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10322 (outs GPR64sp:$wback), 10323 (ins listtype:$Vt, VectorIndexB:$idx, 10324 GPR64sp:$Rn, GPR64pi:$Xm)>; 10325} 10326let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10327multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10328 RegisterOperand listtype, RegisterOperand GPR64pi> { 10329 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10330 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10331 GPR64sp:$Rn), []>; 10332 10333 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10334 (outs GPR64sp:$wback), 10335 (ins listtype:$Vt, VectorIndexH:$idx, 10336 GPR64sp:$Rn, GPR64pi:$Xm)>; 10337} 10338let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10339multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10340 RegisterOperand listtype, RegisterOperand GPR64pi> { 10341 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10342 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10343 GPR64sp:$Rn), []>; 10344 10345 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10346 (outs GPR64sp:$wback), 10347 (ins listtype:$Vt, VectorIndexS:$idx, 10348 GPR64sp:$Rn, GPR64pi:$Xm)>; 10349} 10350let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10351multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10352 RegisterOperand listtype, RegisterOperand GPR64pi> { 10353 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10354 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10355 GPR64sp:$Rn), []>; 10356 10357 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10358 (outs GPR64sp:$wback), 10359 (ins listtype:$Vt, VectorIndexD:$idx, 10360 GPR64sp:$Rn, GPR64pi:$Xm)>; 10361} 10362 10363multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10364 string Count, int Offset, Operand idxtype> { 10365 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10366 // "ld1\t$Vt, [$Rn], #1" 10367 // may get mapped to 10368 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10369 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10370 (!cast<Instruction>(NAME # Type # "_POST") 10371 GPR64sp:$Rn, 10372 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10373 idxtype:$idx, XZR), 1>; 10374 10375 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10376 // "ld1.8b\t$Vt, [$Rn], #1" 10377 // may get mapped to 10378 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10379 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10380 (!cast<Instruction>(NAME # Type # "_POST") 10381 GPR64sp:$Rn, 10382 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10383 idxtype:$idx, XZR), 0>; 10384 10385 // E.g. "ld1.8b { v0 }[0], [x1]" 10386 // "ld1.8b\t$Vt, [$Rn]" 10387 // may get mapped to 10388 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10389 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10390 (!cast<Instruction>(NAME # Type) 10391 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10392 idxtype:$idx, GPR64sp:$Rn), 0>; 10393 10394 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10395 // "ld1.8b\t$Vt, [$Rn], $Xm" 10396 // may get mapped to 10397 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10398 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10399 (!cast<Instruction>(NAME # Type # "_POST") 10400 GPR64sp:$Rn, 10401 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10402 idxtype:$idx, 10403 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10404} 10405 10406multiclass SIMDLdSt1SingleAliases<string asm> { 10407 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10408 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10409 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10410 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10411} 10412 10413multiclass SIMDLdSt2SingleAliases<string asm> { 10414 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10415 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10416 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10417 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10418} 10419 10420multiclass SIMDLdSt3SingleAliases<string asm> { 10421 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10422 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10423 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10424 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10425} 10426 10427multiclass SIMDLdSt4SingleAliases<string asm> { 10428 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10429 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10430 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10431 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10432} 10433} // end of 'let Predicates = [HasNEON]' 10434 10435//---------------------------------------------------------------------------- 10436// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10437//---------------------------------------------------------------------------- 10438 10439let Predicates = [HasNEON, HasRDM] in { 10440 10441class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10442 RegisterOperand regtype, string asm, 10443 string kind, list<dag> pattern> 10444 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10445 pattern> { 10446} 10447multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10448 SDPatternOperator Accum> { 10449 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10450 [(set (v4i16 V64:$dst), 10451 (Accum (v4i16 V64:$Rd), 10452 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 10453 (v4i16 V64:$Rm)))))]>; 10454 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10455 [(set (v8i16 V128:$dst), 10456 (Accum (v8i16 V128:$Rd), 10457 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 10458 (v8i16 V128:$Rm)))))]>; 10459 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10460 [(set (v2i32 V64:$dst), 10461 (Accum (v2i32 V64:$Rd), 10462 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 10463 (v2i32 V64:$Rm)))))]>; 10464 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10465 [(set (v4i32 V128:$dst), 10466 (Accum (v4i32 V128:$Rd), 10467 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 10468 (v4i32 V128:$Rm)))))]>; 10469} 10470 10471multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10472 SDPatternOperator Accum> { 10473 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10474 V64, V64, V128_lo, VectorIndexH, 10475 asm, ".4h", ".4h", ".4h", ".h", 10476 [(set (v4i16 V64:$dst), 10477 (Accum (v4i16 V64:$Rd), 10478 (v4i16 (int_aarch64_neon_sqrdmulh 10479 (v4i16 V64:$Rn), 10480 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10481 VectorIndexH:$idx))))))]> { 10482 bits<3> idx; 10483 let Inst{11} = idx{2}; 10484 let Inst{21} = idx{1}; 10485 let Inst{20} = idx{0}; 10486 } 10487 10488 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10489 V128, V128, V128_lo, VectorIndexH, 10490 asm, ".8h", ".8h", ".8h", ".h", 10491 [(set (v8i16 V128:$dst), 10492 (Accum (v8i16 V128:$Rd), 10493 (v8i16 (int_aarch64_neon_sqrdmulh 10494 (v8i16 V128:$Rn), 10495 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10496 VectorIndexH:$idx))))))]> { 10497 bits<3> idx; 10498 let Inst{11} = idx{2}; 10499 let Inst{21} = idx{1}; 10500 let Inst{20} = idx{0}; 10501 } 10502 10503 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10504 V64, V64, V128, VectorIndexS, 10505 asm, ".2s", ".2s", ".2s", ".s", 10506 [(set (v2i32 V64:$dst), 10507 (Accum (v2i32 V64:$Rd), 10508 (v2i32 (int_aarch64_neon_sqrdmulh 10509 (v2i32 V64:$Rn), 10510 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10511 VectorIndexS:$idx))))))]> { 10512 bits<2> idx; 10513 let Inst{11} = idx{1}; 10514 let Inst{21} = idx{0}; 10515 } 10516 10517 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10518 // an intermediate EXTRACT_SUBREG would be untyped. 10519 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 10520 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 10521 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10522 (i32 (vector_extract 10523 (v4i32 (insert_subvector 10524 (undef), 10525 (v2i32 (int_aarch64_neon_sqrdmulh 10526 (v2i32 V64:$Rn), 10527 (v2i32 (AArch64duplane32 10528 (v4i32 V128:$Rm), 10529 VectorIndexS:$idx)))), 10530 (i64 0))), 10531 (i64 0))))), 10532 (EXTRACT_SUBREG 10533 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 10534 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 10535 FPR32Op:$Rd, 10536 ssub)), 10537 V64:$Rn, 10538 V128:$Rm, 10539 VectorIndexS:$idx)), 10540 ssub)>; 10541 10542 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10543 V128, V128, V128, VectorIndexS, 10544 asm, ".4s", ".4s", ".4s", ".s", 10545 [(set (v4i32 V128:$dst), 10546 (Accum (v4i32 V128:$Rd), 10547 (v4i32 (int_aarch64_neon_sqrdmulh 10548 (v4i32 V128:$Rn), 10549 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10550 VectorIndexS:$idx))))))]> { 10551 bits<2> idx; 10552 let Inst{11} = idx{1}; 10553 let Inst{21} = idx{0}; 10554 } 10555 10556 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10557 // an intermediate EXTRACT_SUBREG would be untyped. 10558 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10559 (i32 (vector_extract 10560 (v4i32 (int_aarch64_neon_sqrdmulh 10561 (v4i32 V128:$Rn), 10562 (v4i32 (AArch64duplane32 10563 (v4i32 V128:$Rm), 10564 VectorIndexS:$idx)))), 10565 (i64 0))))), 10566 (EXTRACT_SUBREG 10567 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 10568 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 10569 FPR32Op:$Rd, 10570 ssub)), 10571 V128:$Rn, 10572 V128:$Rm, 10573 VectorIndexS:$idx)), 10574 ssub)>; 10575 10576 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10577 FPR16Op, FPR16Op, V128_lo, 10578 VectorIndexH, asm, ".h", "", "", ".h", 10579 []> { 10580 bits<3> idx; 10581 let Inst{11} = idx{2}; 10582 let Inst{21} = idx{1}; 10583 let Inst{20} = idx{0}; 10584 } 10585 10586 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10587 FPR32Op, FPR32Op, V128, VectorIndexS, 10588 asm, ".s", "", "", ".s", 10589 [(set (i32 FPR32Op:$dst), 10590 (Accum (i32 FPR32Op:$Rd), 10591 (i32 (int_aarch64_neon_sqrdmulh 10592 (i32 FPR32Op:$Rn), 10593 (i32 (vector_extract (v4i32 V128:$Rm), 10594 VectorIndexS:$idx))))))]> { 10595 bits<2> idx; 10596 let Inst{11} = idx{1}; 10597 let Inst{21} = idx{0}; 10598 } 10599} 10600} // let Predicates = [HasNeon, HasRDM] 10601 10602//---------------------------------------------------------------------------- 10603// ARMv8.3 Complex ADD/MLA instructions 10604//---------------------------------------------------------------------------- 10605 10606class ComplexRotationOperand<int Angle, int Remainder, string Type> 10607 : AsmOperandClass { 10608 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10609 let DiagnosticType = "InvalidComplexRotation" # Type; 10610 let Name = "ComplexRotation" # Type; 10611} 10612def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10613 SDNodeXForm<imm, [{ 10614 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10615}]>> { 10616 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10617 let PrintMethod = "printComplexRotationOp<90, 0>"; 10618} 10619def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10620 SDNodeXForm<imm, [{ 10621 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10622}]>> { 10623 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10624 let PrintMethod = "printComplexRotationOp<180, 90>"; 10625} 10626let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10627class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10628 RegisterOperand regtype, Operand rottype, 10629 string asm, string kind, list<dag> pattern> 10630 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10631 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10632 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10633 Sched<[WriteV]> { 10634 bits<5> Rd; 10635 bits<5> Rn; 10636 bits<5> Rm; 10637 bits<1> rot; 10638 let Inst{31} = 0; 10639 let Inst{30} = Q; 10640 let Inst{29} = U; 10641 let Inst{28-24} = 0b01110; 10642 let Inst{23-22} = size; 10643 let Inst{21} = 0; 10644 let Inst{20-16} = Rm; 10645 let Inst{15-13} = opcode; 10646 // Non-tied version (FCADD) only has one rotation bit 10647 let Inst{12} = rot; 10648 let Inst{11} = 0; 10649 let Inst{10} = 1; 10650 let Inst{9-5} = Rn; 10651 let Inst{4-0} = Rd; 10652} 10653 10654//8.3 CompNum - Floating-point complex number support 10655multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10656 string asm, SDPatternOperator OpNode>{ 10657 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10658 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10659 asm, ".4h", 10660 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10661 (v4f16 V64:$Rn), 10662 (v4f16 V64:$Rm), 10663 (i32 rottype:$rot)))]>; 10664 10665 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10666 asm, ".8h", 10667 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10668 (v8f16 V128:$Rn), 10669 (v8f16 V128:$Rm), 10670 (i32 rottype:$rot)))]>; 10671 } 10672 10673 let Predicates = [HasComplxNum, HasNEON] in { 10674 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10675 asm, ".2s", 10676 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10677 (v2f32 V64:$Rn), 10678 (v2f32 V64:$Rm), 10679 (i32 rottype:$rot)))]>; 10680 10681 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10682 asm, ".4s", 10683 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10684 (v4f32 V128:$Rn), 10685 (v4f32 V128:$Rm), 10686 (i32 rottype:$rot)))]>; 10687 10688 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10689 asm, ".2d", 10690 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10691 (v2f64 V128:$Rn), 10692 (v2f64 V128:$Rm), 10693 (i32 rottype:$rot)))]>; 10694 } 10695} 10696 10697let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10698class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10699 bits<3> opcode, 10700 RegisterOperand regtype, 10701 Operand rottype, string asm, 10702 string kind, list<dag> pattern> 10703 : I<(outs regtype:$dst), 10704 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10705 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10706 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10707 Sched<[WriteV]> { 10708 bits<5> Rd; 10709 bits<5> Rn; 10710 bits<5> Rm; 10711 bits<2> rot; 10712 let Inst{31} = 0; 10713 let Inst{30} = Q; 10714 let Inst{29} = U; 10715 let Inst{28-24} = 0b01110; 10716 let Inst{23-22} = size; 10717 let Inst{21} = 0; 10718 let Inst{20-16} = Rm; 10719 let Inst{15-13} = opcode; 10720 let Inst{12-11} = rot; 10721 let Inst{10} = 1; 10722 let Inst{9-5} = Rn; 10723 let Inst{4-0} = Rd; 10724} 10725 10726multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10727 Operand rottype, string asm, 10728 SDPatternOperator OpNode> { 10729 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10730 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10731 rottype, asm, ".4h", 10732 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10733 (v4f16 V64:$Rn), 10734 (v4f16 V64:$Rm), 10735 (i32 rottype:$rot)))]>; 10736 10737 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10738 rottype, asm, ".8h", 10739 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10740 (v8f16 V128:$Rn), 10741 (v8f16 V128:$Rm), 10742 (i32 rottype:$rot)))]>; 10743 } 10744 10745 let Predicates = [HasComplxNum, HasNEON] in { 10746 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10747 rottype, asm, ".2s", 10748 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10749 (v2f32 V64:$Rn), 10750 (v2f32 V64:$Rm), 10751 (i32 rottype:$rot)))]>; 10752 10753 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10754 rottype, asm, ".4s", 10755 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10756 (v4f32 V128:$Rn), 10757 (v4f32 V128:$Rm), 10758 (i32 rottype:$rot)))]>; 10759 10760 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10761 rottype, asm, ".2d", 10762 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10763 (v2f64 V128:$Rn), 10764 (v2f64 V128:$Rm), 10765 (i32 rottype:$rot)))]>; 10766 } 10767} 10768 10769let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10770class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10771 bit opc1, bit opc2, RegisterOperand dst_reg, 10772 RegisterOperand lhs_reg, 10773 RegisterOperand rhs_reg, Operand vec_idx, 10774 Operand rottype, string asm, string apple_kind, 10775 string dst_kind, string lhs_kind, 10776 string rhs_kind, list<dag> pattern> 10777 : I<(outs dst_reg:$dst), 10778 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10779 asm, 10780 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10781 "$idx, $rot" # "|" # apple_kind # 10782 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10783 Sched<[WriteV]> { 10784 bits<5> Rd; 10785 bits<5> Rn; 10786 bits<5> Rm; 10787 bits<2> rot; 10788 10789 let Inst{31} = 0; 10790 let Inst{30} = Q; 10791 let Inst{29} = U; 10792 let Inst{28} = Scalar; 10793 let Inst{27-24} = 0b1111; 10794 let Inst{23-22} = size; 10795 // Bit 21 must be set by the derived class. 10796 let Inst{20-16} = Rm; 10797 let Inst{15} = opc1; 10798 let Inst{14-13} = rot; 10799 let Inst{12} = opc2; 10800 // Bit 11 must be set by the derived class. 10801 let Inst{10} = 0; 10802 let Inst{9-5} = Rn; 10803 let Inst{4-0} = Rd; 10804} 10805 10806// The complex instructions index by pairs of elements, so the VectorIndexes 10807// don't match the lane types, and the index bits are different to the other 10808// classes. 10809multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype, 10810 string asm, SDPatternOperator OpNode> { 10811 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10812 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10813 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10814 ".4h", ".h", []> { 10815 bits<1> idx; 10816 let Inst{11} = 0; 10817 let Inst{21} = idx{0}; 10818 } 10819 10820 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10821 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10822 ".8h", ".8h", ".h", []> { 10823 bits<2> idx; 10824 let Inst{11} = idx{1}; 10825 let Inst{21} = idx{0}; 10826 } 10827 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10828 10829 let Predicates = [HasComplxNum, HasNEON] in { 10830 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10831 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10832 ".4s", ".4s", ".s", []> { 10833 bits<1> idx; 10834 let Inst{11} = idx{0}; 10835 let Inst{21} = 0; 10836 } 10837 } // Predicates = [HasComplxNum, HasNEON] 10838} 10839 10840//---------------------------------------------------------------------------- 10841// Crypto extensions 10842//---------------------------------------------------------------------------- 10843 10844let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10845class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10846 list<dag> pat> 10847 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10848 Sched<[WriteV]>{ 10849 bits<5> Rd; 10850 bits<5> Rn; 10851 let Inst{31-16} = 0b0100111000101000; 10852 let Inst{15-12} = opc; 10853 let Inst{11-10} = 0b10; 10854 let Inst{9-5} = Rn; 10855 let Inst{4-0} = Rd; 10856} 10857 10858class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10859 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10860 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10861 10862class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10863 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10864 "$Rd = $dst", 10865 [(set (v16i8 V128:$dst), 10866 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10867 10868let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10869class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10870 dag oops, dag iops, list<dag> pat> 10871 : I<oops, iops, asm, 10872 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10873 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10874 Sched<[WriteV]>{ 10875 bits<5> Rd; 10876 bits<5> Rn; 10877 bits<5> Rm; 10878 let Inst{31-21} = 0b01011110000; 10879 let Inst{20-16} = Rm; 10880 let Inst{15} = 0; 10881 let Inst{14-12} = opc; 10882 let Inst{11-10} = 0b00; 10883 let Inst{9-5} = Rn; 10884 let Inst{4-0} = Rd; 10885} 10886 10887class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10888 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10889 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10890 [(set (v4i32 FPR128:$dst), 10891 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10892 (v4i32 V128:$Rm)))]>; 10893 10894class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10895 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10896 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10897 [(set (v4i32 V128:$dst), 10898 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10899 (v4i32 V128:$Rm)))]>; 10900 10901class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10902 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10903 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10904 [(set (v4i32 FPR128:$dst), 10905 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10906 (v4i32 V128:$Rm)))]>; 10907 10908let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10909class SHA2OpInst<bits<4> opc, string asm, string kind, 10910 string cstr, dag oops, dag iops, 10911 list<dag> pat> 10912 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10913 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10914 Sched<[WriteV]>{ 10915 bits<5> Rd; 10916 bits<5> Rn; 10917 let Inst{31-16} = 0b0101111000101000; 10918 let Inst{15-12} = opc; 10919 let Inst{11-10} = 0b10; 10920 let Inst{9-5} = Rn; 10921 let Inst{4-0} = Rd; 10922} 10923 10924class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10925 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10926 (ins V128:$Rd, V128:$Rn), 10927 [(set (v4i32 V128:$dst), 10928 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10929 10930class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10931 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10932 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10933 10934// Armv8.2-A Crypto extensions 10935class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10936 list<dag> pattern> 10937 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> { 10938 bits<5> Vd; 10939 bits<5> Vn; 10940 let Inst{31-25} = 0b1100111; 10941 let Inst{9-5} = Vn; 10942 let Inst{4-0} = Vd; 10943} 10944 10945class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10946 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 10947 "$Vd = $Vdst", []> { 10948 let Inst{31-25} = 0b1100111; 10949 let Inst{24-21} = 0b0110; 10950 let Inst{20-15} = 0b000001; 10951 let Inst{14} = op0; 10952 let Inst{13-12} = 0b00; 10953 let Inst{11-10} = op1; 10954} 10955class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 10956 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 10957class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 10958 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 10959 10960class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 10961 string asmops, string cst> 10962 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 10963 bits<5> Vm; 10964 let Inst{24-21} = 0b0011; 10965 let Inst{20-16} = Vm; 10966 let Inst{15} = 0b1; 10967 let Inst{14} = op0; 10968 let Inst{13-12} = 0b00; 10969 let Inst{11-10} = op1; 10970} 10971class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 10972 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10973 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 10974class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 10975 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10976 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10977class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 10978 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10979 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 10980class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 10981 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10982 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10983class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 10984 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 10985 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10986 10987class CryptoRRRR<bits<2>op0, string asm, string asmops> 10988 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 10989 asmops, "", []> { 10990 bits<5> Vm; 10991 bits<5> Va; 10992 let Inst{24-23} = 0b00; 10993 let Inst{22-21} = op0; 10994 let Inst{20-16} = Vm; 10995 let Inst{15} = 0b0; 10996 let Inst{14-10} = Va; 10997} 10998class CryptoRRRR_16B<bits<2>op0, string asm> 10999 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11000 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11001} 11002class CryptoRRRR_4S<bits<2>op0, string asm> 11003 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11004 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11005} 11006 11007class CryptoRRRi6<string asm> 11008 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11009 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11010 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11011 bits<6> imm; 11012 bits<5> Vm; 11013 let Inst{24-21} = 0b0100; 11014 let Inst{20-16} = Vm; 11015 let Inst{15-10} = imm; 11016 let Inst{9-5} = Vn; 11017 let Inst{4-0} = Vd; 11018} 11019 11020class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11021 : BaseCryptoV82<(outs V128:$Vdst), 11022 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11023 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11024 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11025 bits<2> imm; 11026 bits<5> Vm; 11027 let Inst{24-21} = 0b0010; 11028 let Inst{20-16} = Vm; 11029 let Inst{15} = 0b1; 11030 let Inst{14} = op0; 11031 let Inst{13-12} = imm; 11032 let Inst{11-10} = op1; 11033} 11034 11035//---------------------------------------------------------------------------- 11036// v8.1 atomic instructions extension: 11037// * CAS 11038// * CASP 11039// * SWP 11040// * LDOPregister<OP>, and aliases STOPregister<OP> 11041 11042// Instruction encodings: 11043// 11044// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11045// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11046// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11047// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11048// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11049// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11050 11051// Instruction syntax: 11052// 11053// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11054// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11055// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11056// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11057// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11058// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11059// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11060// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11061// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11062// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11063 11064let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11065class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11066 string cstr, list<dag> pattern> 11067 : I<oops, iops, asm, operands, cstr, pattern> { 11068 bits<2> Sz; 11069 bit NP; 11070 bit Acq; 11071 bit Rel; 11072 bits<5> Rs; 11073 bits<5> Rn; 11074 bits<5> Rt; 11075 let Inst{31-30} = Sz; 11076 let Inst{29-24} = 0b001000; 11077 let Inst{23} = NP; 11078 let Inst{22} = Acq; 11079 let Inst{21} = 0b1; 11080 let Inst{20-16} = Rs; 11081 let Inst{15} = Rel; 11082 let Inst{14-10} = 0b11111; 11083 let Inst{9-5} = Rn; 11084 let Inst{4-0} = Rt; 11085 let Predicates = [HasLSE]; 11086} 11087 11088class BaseCAS<string order, string size, RegisterClass RC> 11089 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11090 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11091 "$out = $Rs",[]>, 11092 Sched<[WriteAtomic]> { 11093 let NP = 1; 11094} 11095 11096multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11097 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11098 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11099 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11100 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11101} 11102 11103class BaseCASP<string order, string size, RegisterOperand RC> 11104 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11105 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11106 "$out = $Rs",[]>, 11107 Sched<[WriteAtomic]> { 11108 let NP = 0; 11109} 11110 11111multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11112 let Sz = 0b00, Acq = Acq, Rel = Rel in 11113 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11114 let Sz = 0b01, Acq = Acq, Rel = Rel in 11115 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11116} 11117 11118let Predicates = [HasLSE] in 11119class BaseSWP<string order, string size, RegisterClass RC> 11120 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11121 "\t$Rs, $Rt, [$Rn]","",[]>, 11122 Sched<[WriteAtomic]> { 11123 bits<2> Sz; 11124 bit Acq; 11125 bit Rel; 11126 bits<5> Rs; 11127 bits<3> opc = 0b000; 11128 bits<5> Rn; 11129 bits<5> Rt; 11130 let Inst{31-30} = Sz; 11131 let Inst{29-24} = 0b111000; 11132 let Inst{23} = Acq; 11133 let Inst{22} = Rel; 11134 let Inst{21} = 0b1; 11135 let Inst{20-16} = Rs; 11136 let Inst{15} = 0b1; 11137 let Inst{14-12} = opc; 11138 let Inst{11-10} = 0b00; 11139 let Inst{9-5} = Rn; 11140 let Inst{4-0} = Rt; 11141 let Predicates = [HasLSE]; 11142} 11143 11144multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11145 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11146 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11147 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11148 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11149} 11150 11151let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11152class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11153 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11154 "\t$Rs, $Rt, [$Rn]","",[]>, 11155 Sched<[WriteAtomic]> { 11156 bits<2> Sz; 11157 bit Acq; 11158 bit Rel; 11159 bits<5> Rs; 11160 bits<3> opc; 11161 bits<5> Rn; 11162 bits<5> Rt; 11163 let Inst{31-30} = Sz; 11164 let Inst{29-24} = 0b111000; 11165 let Inst{23} = Acq; 11166 let Inst{22} = Rel; 11167 let Inst{21} = 0b1; 11168 let Inst{20-16} = Rs; 11169 let Inst{15} = 0b0; 11170 let Inst{14-12} = opc; 11171 let Inst{11-10} = 0b00; 11172 let Inst{9-5} = Rn; 11173 let Inst{4-0} = Rt; 11174 let Predicates = [HasLSE]; 11175} 11176 11177multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11178 string order> { 11179 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11180 def B : BaseLDOPregister<op, order, "b", GPR32>; 11181 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11182 def H : BaseLDOPregister<op, order, "h", GPR32>; 11183 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11184 def W : BaseLDOPregister<op, order, "", GPR32>; 11185 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11186 def X : BaseLDOPregister<op, order, "", GPR64>; 11187} 11188 11189// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11190// complex DAG for DstRHS. 11191let Predicates = [HasLSE] in 11192multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11193 string size, dag SrcRHS, dag DstRHS> { 11194 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11195 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11196 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11197 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11198 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11199 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11200 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11201 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11202 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11203 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11204} 11205 11206multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11207 string size, dag RHS> { 11208 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11209} 11210 11211multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11212 string size, dag LHS, dag RHS> { 11213 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11214} 11215 11216multiclass LDOPregister_patterns<string inst, string op> { 11217 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11218 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11219 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11220 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11221} 11222 11223multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11224 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11225 (i64 GPR64:$Rm), 11226 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11227 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11228 (i32 GPR32:$Rm), 11229 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11230 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11231 (i32 GPR32:$Rm), 11232 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11233 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11234 (i32 GPR32:$Rm), 11235 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11236} 11237 11238let Predicates = [HasLSE] in 11239multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11240 string size, dag OLD, dag NEW> { 11241 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11242 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11243 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11244 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11245 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11246 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11247 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11248 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11249 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11250 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11251} 11252 11253multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11254 string size, dag OLD, dag NEW> { 11255 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11256} 11257 11258multiclass CASregister_patterns<string inst, string op> { 11259 defm : CASregister_patterns_ord<inst, "X", op, "64", 11260 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11261 defm : CASregister_patterns_ord<inst, "W", op, "32", 11262 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11263 defm : CASregister_patterns_ord<inst, "H", op, "16", 11264 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11265 defm : CASregister_patterns_ord<inst, "B", op, "8", 11266 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11267} 11268 11269let Predicates = [HasLSE] in 11270class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11271 Instruction inst> : 11272 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11273 11274multiclass STOPregister<string asm, string instr> { 11275 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11276 !cast<Instruction>(instr # "LB")>; 11277 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11278 !cast<Instruction>(instr # "LH")>; 11279 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11280 !cast<Instruction>(instr # "LW")>; 11281 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11282 !cast<Instruction>(instr # "LX")>; 11283 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11284 !cast<Instruction>(instr # "B")>; 11285 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11286 !cast<Instruction>(instr # "H")>; 11287 def : BaseSTOPregister<asm, GPR32, WZR, 11288 !cast<Instruction>(instr # "W")>; 11289 def : BaseSTOPregister<asm, GPR64, XZR, 11290 !cast<Instruction>(instr # "X")>; 11291} 11292 11293class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11294 dag iops, dag oops, list<dag> pat> 11295 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11296 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11297 bits<5> Rt; 11298 bits<5> Rn; 11299 let Inst{31-21} = 0b11111000001; 11300 let Inst{15} = 1; 11301 let Inst{14-12} = opc; 11302 let Inst{11-10} = 0b00; 11303 let Inst{9-5} = Rn; 11304 let Inst{4-0} = Rt; 11305 11306 let Predicates = [HasV8_7a]; 11307} 11308 11309class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11310 list<dag> pat = []> 11311 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11312 let Inst{20-16} = 0b11111; 11313} 11314 11315class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11316 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11317 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11318 bits<5> Rs; 11319 let Inst{20-16} = Rs; 11320} 11321 11322//---------------------------------------------------------------------------- 11323// Allow the size specifier tokens to be upper case, not just lower. 11324def : TokenAlias<".4B", ".4b">; // Add dot product 11325def : TokenAlias<".8B", ".8b">; 11326def : TokenAlias<".4H", ".4h">; 11327def : TokenAlias<".2S", ".2s">; 11328def : TokenAlias<".1D", ".1d">; 11329def : TokenAlias<".16B", ".16b">; 11330def : TokenAlias<".8H", ".8h">; 11331def : TokenAlias<".4S", ".4s">; 11332def : TokenAlias<".2D", ".2d">; 11333def : TokenAlias<".1Q", ".1q">; 11334def : TokenAlias<".2H", ".2h">; 11335def : TokenAlias<".B", ".b">; 11336def : TokenAlias<".H", ".h">; 11337def : TokenAlias<".S", ".s">; 11338def : TokenAlias<".D", ".d">; 11339def : TokenAlias<".Q", ".q">; 11340